函数返回阶段触发Bus Error的C语言程序问题求助
总线错误(Bus Error)排查思路:子函数返回后程序崩溃
问题描述
父函数调用子函数后,所有逻辑执行正常,但子函数返回后触发Bus Error,后续代码无法执行。相关代码如下:
int main () { game(); // 这段代码无法执行,程序触发Bus Error printf("Execute 2"); return 1; } int game () { game_t GameInfo = {.level = 1, .score = 0, .playerCh = 0, .playerX = 1, .playerY = 1}; gameLevel(&GameInfo); mvprintw(1,1, "Executed"); // 代码执行到这里一切正常 return 1; }; void gameLevel (game_t *GameInfo) { // 确定游戏区域大小 int cellCols = COLS / 3; int cellRows = (LINES / 3) - 2; GameInfo -> playerX = 1; GameInfo -> playerY = 1; generateMaze(0); int solved = 0; int level = GameInfo -> level; // 设置玩家默认位置 getPlayerDefault(GameInfo); pthread_t enemies_th; pthread_create(&enemies_th, NULL, enemies, (void *)GameInfo); // enemies(&level); while (solved == 0 && GameInfo -> collision != 1) { printGameInfo(GameInfo); noecho(); char move = getch(); echo(); if (GameInfo -> collision != 1) { if (checkMoveValidity(move, GameInfo) == 1) { solved = movePlayer(move, GameInfo); if (solved == 1) { break; } } } else { break; } } if (solved == 1) { pthread_cancel(enemies_th); GameInfo->level++; gameLevel(GameInfo); } else { // 游戏结束 pthread_cancel(enemies_th); return; } }
实际代码包含ncurses库、多线程及复杂自定义结构,所有逻辑正常运行,仅返回环节出错。
排查思路
- 排查递归栈溢出:
gameLevel函数在关卡完成时会递归调用自身,多次递归会耗尽栈空间,破坏栈帧结构,导致返回时触发Bus Error。建议将递归改为循环结构,避免栈资源耗尽。 - 检查多线程对栈内存的访问:
GameInfo是在game函数的栈上分配的,当gameLevel返回后,game函数即将返回时,栈上的GameInfo会被销毁。如果enemies线程此时还在访问该结构体,就会触发Bus Error。可以将GameInfo用malloc分配在堆上,或者确保线程在GameInfo生命周期结束前完全终止(比如用pthread_join等待线程结束,而不是仅用pthread_cancel)。 - 验证ncurses资源清理:如果程序退出前未正确调用
endwin()等ncurses清理函数,可能导致终端状态异常,引发Bus Error。检查game函数返回前是否完成ncurses环境的清理。 - 检测栈内存越界:检查是否有代码越界修改
GameInfo结构体的成员,破坏了栈帧的返回地址,导致函数返回时跳转到非法地址。可以用valgrind工具检测内存问题:valgrind --leak-check=full ./your_program,它会定位内存越界、野指针等问题。 - 优化线程终止方式:
pthread_cancel是强制终止线程,可能导致线程处于异常状态,甚至残留对GameInfo的访问。建议改用标志位(比如在game_t中添加running成员),让线程主动检查标志位并退出,避免强制取消带来的问题。
内容的提问来源于stack exchange,提问作者Michal Gally
相关产品推荐
相关产品推荐

