You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

函数返回阶段触发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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 05:00:54