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

Boost-Python2移植到Boost-Python3后程序退出时崩溃问题

Boost-Python3嵌入程序退出崩溃问题排查

问题场景

将程序从Boost-Python2移植到Boost-Python3时,发现嵌入Python3的Boost程序退出时崩溃,但相同代码基于Python2.7构建可正常运行。可复现的示例代码如下:

#include <boost/python.hpp>
#include <stdio.h>

int main()
{
  Py_InitializeEx(0);

  boost::python::object modMath = boost::python::import("math");
  boost::python::object cosFunc = modMath.attr("cos");

  Py_Finalize();
}

Python3.x环境下的回溯信息:

Program received signal SIGSEGV, Segmentation fault.
PyObject_GC_Del (op=0x7ffff6f134f0) at ../Modules/gcmodule.c:2313
2313    ../Modules/gcmodule.c: Нет такого файла или каталога.
(gdb) bt
#0  PyObject_GC_Del (op=0x7ffff6f134f0) at ../Modules/gcmodule.c:2313
#1  0x0000555555555366 in _Py_DECREF (op=0x7ffff6f134f0) at /usr/include/python3.9/object.h:430
#2  0x0000555555555469 in boost::python::api::object_base::~object_base (this=0x7fffffffde78, __in_chrg=<optimized out>) at /usr/include/boost/python/object_core.hpp:423
#3  0x00005555555553a8 in boost::python::api::object::~object (this=0x7fffffffde78, __in_chrg=<optimized out>) at /usr/include/boost/python/object_core.hpp:238
#4  0x0000555555555244 in main () at test3x_tb.cpp:12

原因分析

Python3与Python2在Py_Finalize()的行为上存在关键差异:

  • Python2中,Py_Finalize()后仍允许部分不规范的Python对象操作,不会立即触发崩溃
  • Python3中,Py_Finalize()会彻底销毁Python运行时环境,释放所有相关内存资源

示例代码中,modMath和cosFunc是栈上的boost::python::object对象,它们的析构时机是main()函数结束时——此时Py_Finalize()已经执行完毕,Python运行时已被销毁。当Boost Python的对象析构函数调用Py_DECREF时,会访问已经被释放的内存空间,直接触发段错误。

解决方法

核心思路是让所有Boost Python对象在Py_Finalize()之前完成析构,具体有两种实现方式:

方案1:使用局部作用域限制对象生命周期

通过添加代码块,将Python相关操作包裹起来,确保modMath和cosFunc在Py_Finalize()调用前就被销毁:

#include <boost/python.hpp>
#include <stdio.h>

int main()
{
  Py_InitializeEx(0);

  {
    boost::python::object modMath = boost::python::import("math");
    boost::python::object cosFunc = modMath.attr("cos");
    // 在这里执行需要Python对象的操作
  } // 作用域结束,modMath和cosFunc自动析构

  Py_Finalize();
}

该方案符合C++的RAII原则,代码简洁安全,优先推荐。

方案2:动态分配对象并手动释放

如果无法使用局部作用域,可以用new动态分配boost::python::object,在Py_Finalize()前手动delete:

#include <boost/python.hpp>
#include <stdio.h>

int main()
{
  Py_InitializeEx(0);

  boost::python::object* modMath = new boost::python::object(boost::python::import("math"));
  boost::python::object* cosFunc = new boost::python::object((*modMath).attr("cos"));
  
  // 执行需要Python对象的操作
  delete cosFunc;
  delete modMath; // 手动释放对象,确保在Py_Finalize前完成

  Py_Finalize();
}

内容的提问来源于stack exchange,提问作者dhyan.nataraj

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 12:48:24