ncurses程序崩溃除了PuTTY以外的任何东西
发布时间:2020-12-16 07:01:38 所属栏目:百科 来源:网络整理
导读:我有一个较旧的基于ncurses的程序,它在一些文件上做了一些简单的IO(即:安装程序).但是,从与PuTTY不同的终端,它与SIGBUS崩溃 Program received signal SIGBUS,Bus error.0x00000000004028b1 in fDisplay (ptr=Variable "ptr" is not available.) at file_cpy
我有一个较旧的基于ncurses的程序,它在一些文件上做了一些简单的IO(即:安装程序).但是,从与PuTTY不同的终端,它与SIGBUS崩溃
Program received signal SIGBUS,Bus error. 0x00000000004028b1 in fDisplay (ptr=Variable "ptr" is not available. ) at file_cpy.c:676 676 sprintf(p," %-36s ",(*ptr)->datainfo.option); (gdb) where #0 0x00000000004028b1 in fDisplay (ptr=Variable "ptr" is not available. ) at file_cpy.c:676 #1 0x0000000000402cdb in fredraw (c=0x7fffffffe860) at file_cpy.c:696 #2 0x0000000000401996 in ls_dispatch (c=0x2020202020202020) at ds_cell.c:324 #3 0x0000000000403bf2 in main_dir (c=0x2020202020202020) at file_cpy.c:811 #4 0x0000000000403cb3 in main () at file_cpy.c:1345 (gdb) x/i $pc 0x4028b1 <fDisplay+17>: mov (%rax),%rdx (gdb) 这种情况发生在Linux和FreeBSD上,无论ncurses版本和32/64位架构如何.我完全难过了. 这里调用fDis??play(): /* * File redraw routine. Draws current list on screen. */ int fredraw (CELL * c) { register int row = c->srow; dlistptr p = c->list_start; int i = 0; char buff[200]; if (c->ecol - c->scol) sprintf(buff,"%*s",c->ecol - c->scol + 1," "); while (i <= c->erow - c->srow && p != NULL) { if (p == c->current) wattron(c->window,A_REVERSE); mvaddstr (row,c->scol,fDisplay(&p)); if (p == c->current) wattroff(c->window,A_REVERSE); row++; i++; p = p->nextlistptr; } if (row <= c -> erow) for (; row <= c -> erow ; row++) mvaddstr(row,buff); wrefresh(c->window); c -> redraw = FALSE; return TRUE; } 这里调用fredraw(): int main_dir(CELL *c) { int i; getcwd(current_path,sizeof(current_path)); strcat(current_path,"/.config.h"); load_file(current_path); c->keytable = file_cpy_menu; c->func_table = file_cpy_table; c->ListEntryProc = File_Entry; c->UpdateStatusProc = status_update; c->redraw = TRUE; c->ListExitProc = List_Exit; c->ListPaintProc = fredraw; c->srow = 3; c->scol = 1; c->erow = c->window->_maxy - 5; c->ecol = c->window->_maxx - 1; c->max_rows = c->window->_maxy; c->max_cols = c->window->_maxx; c->filename = "[ Config ]"; c->menu_bar = 0; c->normcolor = 0x07; c->barcolor = 0x1f; init_dlist(c); for (i = 0; config_type[i].option; i++) insert_fdlist(c,&config_type[i]); /* * Go Do It */ do { c->redraw = TRUE; ls_dispatch(c); } while (c->termkey != ESC && c->termkey != ALT_X); return TRUE; } 最后,main()调用上面的函数: int main() { CELL file_cpy = {0}; WINDOW *mainwin; mainwin = initscr(); start_color(); setup_colors(); cbreak(); noecho(); keypad(mainwin,TRUE); meta(mainwin,TRUE); raw(); leaveok(mainwin,TRUE); wbkgd(mainwin,COLOR_PAIR(COLOR_MAIN)); wattron(mainwin,COLOR_PAIR(COLOR_MAIN)); werase(mainwin); refresh(); file_cpy.window = mainwin; main_dir(&file_cpy); wbkgd(mainwin,A_NORMAL); werase(mainwin); echo(); nocbreak(); noraw(); refresh(); endwin(); return TRUE; } 解决方法
显然你正在调用main_dir和ls_dispatch,指针c初始化为0x2020202020202020.虽然不完全不可能,但我发现它不太可能,而且它看起来好像你用空格覆盖了指针.
valgrind可能会有所帮助,或某种内存或堆栈保护检查. 为什么这取决于终端,我不能说;可能存在一些依赖于TERM的代码(例如“分配与屏幕上一样多的行”).无论如何,这不是错误:它只是将bug打开的条件.这种错误通常是由硬连线常量引起的,有时候超出实际值(在上面的例子中,我可以说“分配96行”,假设96行对每个人来说总是足够的;而一个TERM与100行会影响假设并导致缓冲区溢出). 它也可能是调试器的工件,看看如何在堆栈上分配c(但我不这么认为:它应该是c = 0x7fffsomething – 至少在我检查的系统上).无论如何,我通过使file_cpy堆动态来重复这样的测试: int main() { CELL *file_cpy = NULL; WINDOW *mainwin; file_cpy = malloc(sizeof(CELL)); ... file_cpy->window = mainwin; main_dir(file_cpy); ... free(file_cpy); // file_cpy = NULL; // we immediately return return TRUE; 然后我会尝试在整个main_dir函数中制表指针的值,以防它被覆盖. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- opencv 读写XML YML
- 破折号明星破折号( – * – )在Ruby文件中做什么?
- XML文件要有根标签(Extra content at the end of the docu
- Swift webview:如何从javascript正确调用swift代码?
- Swift 2 – UnsafeMutablePointer到对象
- select2,利用ajax高效查询大数据列表(可搜索、可分页)
- ruby-on-rails – 深层嵌套的accepts_nested_attributes_fo
- Oracle JET入门Tutorial教程
- vue使用$emit时,父组件无法监听到子组件的事件实例
- flex 给group填充背景