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

如何在CI流水线中检测程序未处理异常终止的退出状态?

判断程序是否因未处理异常终止

当你用system("myprogram")获取到wStatus后,需要通过POSIX定义的wait系列宏来解析进程终止状态,核心思路是区分正常退出和信号终止,再结合异常对应的信号来判断:

步骤解析

  1. 区分终止类型

    • 用WIFEXITED(wStatus)判断进程是否正常退出(通过exit()或return返回):如果返回非零值,说明是正常退出,可通过WEXITSTATUS(wStatus)获取退出码,这种情况不属于未处理异常终止。
    • 用WIFSIGNALED(wStatus)判断进程是否被信号终止:返回非零值表示进程因收到信号而意外终止,这是我们需要重点检查的情况。
  2. 识别异常对应的信号
    在绝大多数POSIX系统中(如Linux、macOS),未处理的C++异常会触发默认的终止逻辑:调用abort()函数,该函数会向进程发送SIGABRT信号(信号编号为6)。因此,当WTERMSIG(wStatus)返回SIGABRT时,即可判定程序大概率因未处理异常终止(注:手动调用abort()也会触发该信号,若需更精准判断,需修改目标程序的终止逻辑)。

  3. 可选:检查核心转储
    部分系统支持WCOREDUMP(wStatus)宏,可用来判断进程终止时是否生成了核心转储文件,这能作为异常终止的辅助验证依据。

代码示例

#include <stdio.h>
#include <sys/wait.h>
#include <signal.h>

int main() {
    auto wStatus = system("myprogram");

    if (WIFSIGNALED(wStatus)) {
        int terminateSignal = WTERMSIG(wStatus);
        if (terminateSignal == SIGABRT) {
            printf("程序因未处理异常终止(触发SIGABRT信号)\n");
        } else {
            printf("程序被信号 %d 终止\n", terminateSignal);
        }

        // 检查是否生成核心转储(部分系统支持)
        #ifdef WCOREDUMP
        if (WCOREDUMP(wStatus)) {
            printf("已生成核心转储文件\n");
        }
        #endif
    } else if (WIFEXITED(wStatus)) {
        int exitCode = WEXITSTATUS(wStatus);
        printf("程序正常退出,退出码:%d\n", exitCode);
    } else {
        printf("程序终止状态未知\n");
    }

    return 0;
}

注意事项

  • SIGABRT是POSIX标准定义的信号,在主流系统中编号均为6,但个别非标准系统可能有差异,需根据目标环境调整。
  • 如果目标程序自定义了std::terminate_handler,可能会改变终止行为(比如改为调用exit()返回特定码),此时需要对应调整判断逻辑。

内容的提问来源于stack exchange,提问作者Nicola Mori

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 06:49:52