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

如何捕获Python subprocess.check_output调用C++程序抛出的异常?

如何让Python捕获C++程序的除零/浮点异常信息

你遇到的问题其实有两个核心原因,咱们一步步拆解解决:

首先,除零触发的是操作系统的硬件信号(SIGFPE),不是C++标准库的std::exception类型——你C代码里的catch(exception &e)根本抓不到这个错误!程序会直接被信号终止,返回的状态码-8就是SIGFPE的标识。其次,Python的check_output默认只捕获子进程的stdout,而你C里用cerr输出的内容是在stderr流里,默认没被捕获,所以看不到那行错误信息。

下面给出具体的解决方案:

第一步:修改C++代码,正确处理除零错误

有两种实用的方式可选:

方式1:手动检查除数,主动抛出标准异常

既然除零不会触发C++标准异常,那我们可以在计算前手动判断除数是否为0,主动抛出std::runtime_error,这样catch块就能正常捕获并输出信息:

#include<iostream>
#include<exception>
#include <stdexcept>
using namespace std;

int main() {
    int a=5;
    int b=0;
    try {
        cout<< "I am a statement before division"<< endl;
        // 手动检查除数,避免触发硬件信号
        if (b == 0) {
            throw runtime_error("Floating point exception: division by zero");
        }
        int c = a/b;
        cout<< "I am a statement after division"<< endl;
    } catch(const exception &e) {
        cerr << "Cerr - To test exception: " << e.what() << "\n" << endl;
        // 返回非零状态码,让Python感知到程序出错
        return 1;
    }
    return 0;
}

方式2:捕获SIGFPE信号

如果你不想手动检查所有可能的浮点错误,可以注册信号处理函数来捕获SIGFPE,输出错误信息后正常退出:

#include<iostream>
#include<exception>
#include <stdexcept>
#include <signal.h>
#include <unistd.h>

using namespace std;

void sigfpe_handler(int signum) {
    cerr << "Floating point exception (SIGFPE) caught!" << endl;
    // 退出程序并返回非零状态码
    exit(1);
}

int main() {
    // 注册SIGFPE信号的处理函数
    signal(SIGFPE, sigfpe_handler);
    
    int a=5;
    int b=0;
    try {
        cout<< "I am a statement before division"<< endl;
        int c = a/b;
        cout<< "I am a statement after division"<< endl;
    } catch(exception &e) {
        cerr << "Cerr - To test exception \n" << endl;
        return 1;
    }
    return 0;
}

第二步:修改Python代码,捕获stderr输出

subprocess.check_output默认只捕获子进程的stdout,我们需要让它同时捕获stderr,这样才能拿到C++里cerr输出的内容。修改后的Python代码如下:

import subprocess
import traceback

print('Sample Python to simulate exception')
TestOP = 'Default'
try:
    # 把stderr合并到stdout一起捕获,同时设置universal_newlines让输出为字符串
    TestOP = subprocess.check_output(
        ["/lhome/workspace/testException/testxptn"],
        stderr=subprocess.STDOUT,
        universal_newlines=True
    )
except subprocess.CalledProcessError as e :
    print(f"Command failed with return code {e.returncode}")
    print("Output from C++ program:")
    print(e.output)
    # 如果需要Python侧的栈追踪可以保留下面两行,否则可以注释掉
    # tb = traceback.format_exc()
    # print(tb)

最终效果

修改后运行Python脚本,你会得到类似这样的输出(以方式1为例):

Sample Python to simulate exception
I am a statement before division
Command failed with return code 1
Output from C++ program:
Cerr - To test exception: Floating point exception: division by zero

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:50:04