嵌入Python代码导入numpy时触发SIGFPE(FPE_FLTOVF)错误排查求助
问题描述
单独运行C嵌入Python的测试代码时,Python可正常启动,成功导入numpy并输出预期的两行内容;但将相同代码嵌入到自有项目(存在未知初始化操作)后,执行import numpy语句时触发SIGFPE(具体为FPE_FLTOVF,由strace捕获),程序直接退出且未输出第二行内容。奇怪的是,用valgrind运行出错代码时,一切恢复正常。
测试代码
C代码
#include <Python.h> int main(int argc, char *argv[]) { Py_Initialize(); FILE* to_run_script= fopen("script.py", "r"); if (to_run_script != NULL) PyRun_SimpleFile(to_run_script, "script.py"); Py_Finalize(); return 0; }
Python代码
def func1(): print("numpy NOT YET imported!!\n") import numpy print("numpy is imported!!\n") return 1.5 func1()
排查方向
- 检查浮点数异常掩码:自有项目可能通过
feenableexcept或汇编指令修改了CPU浮点数异常掩码,开启了FPE_FLTOVF(浮点上溢)的捕获。可以在调用Py_Initialize()前后,用fegetexcept()获取当前掩码,对比单独运行和项目中的差异;必要时在嵌入代码前用fesetexcept()重置掩码,只保留默认需要捕获的异常(比如除零)。 - 排查内存对齐问题:numpy导入时会初始化SIMD相关的内存区域,对内存对齐要求较高。自有项目可能重载了内存分配函数(如
malloc)、修改了编译对齐选项(如-malign-double),导致内存对齐不满足要求。valgrind会自动处理此类对齐问题,所以运行正常。可以检查项目的编译参数和内存分配逻辑,确保numpy所需的内存对齐规则被满足。 - 检查全局状态污染:项目的初始化代码可能修改了Python依赖的环境变量(如
PYTHONPATH、LD_LIBRARY_PATH)、全局变量或系统资源。对比单独运行和项目中运行时的环境变量差异,或者在嵌入代码前后打印相关变量,确认是否存在干扰。 - 对比编译链接差异:测试程序和自有项目的编译选项、链接库版本可能不一致。比如测试程序链接静态Python库,项目链接动态库;或者numpy的版本/编译参数不同。检查两者的
CFLAGS、LDFLAGS,确保链接的Python和numpy库版本匹配,编译宏定义(如NDEBUG、PY_DEBUG)一致。 - 确认线程状态:如果项目是多线程架构,即使嵌入代码是单线程调用,其他线程也可能干扰Python的GIL状态。可以在
Py_Initialize()后调用PyEval_InitThreads(),确保Python线程状态初始化正确,避免全局状态冲突。
内容的提问来源于stack exchange,提问作者LaszloLadanyi
相关产品推荐
相关产品推荐

