Fer*_*eru 15 python crash garbage-collection
我的python代码崩溃了,错误'GC Object has tracked'.试图找出调试此崩溃的最佳方法.
操作系统:Linux.
以下文章中有几点建议. 使用GDB进行Python内存调试
不确定哪种方法适用于作者.
找到一些关于此的文章.但不完全回答我的问题:http: //pfigue.github.io/blog/2012/12/28/where-is-my-core-dump-archlinux/
Fer*_*eru 13
在我的场景中找出了这个问题的原因(不一定是GC对象崩溃的唯一原因).我使用GDB和Core转储来调试此问题.
我有Python和C扩展代码(在共享对象中).Python代码使用C扩展代码注册一个Callback例程.在某个工作流程中,来自C扩展代码的线程在Python代码中调用已注册的回调例程.
这通常可以正常工作,但是当多个线程同时执行相同的操作时,会导致崩溃并且"GC对象已经被跟踪".
同步对多线程的python对象的访问确实解决了这个问题.
感谢任何回应.
小智 9
当我们的C++代码触发python回调时,我使用boost :: python遇到了这个问题.我偶尔会得到"GC对象已被跟踪",程序将终止.
我能够在触发错误之前将GDB附加到进程.有趣的是,在python代码中,我们用functools partial包装回调,实际上掩盖了真正的错误发生的地方.用简单的可调用包装类替换partial后."GC对象已经跟踪错误"不再弹出,而是我现在只是遇到了段错误.
在我们的boost :: python包装器中,我们有lambda函数来处理C++回调,lambda函数捕获了boost :: python :: object回调函数.事实证明,无论出于何种原因,在lambda的析构函数中,当销毁导致段错误的boost :: python :: object时,并不总是正确地获取GIL.
解决方法是不使用lambda函数,而是创建一个函子,确保在boost :: python :: object上调用PyDECREF()之前在析构函数中获取GIL.
class callback_wrapper
{
public:
callback_wrapper(object cb): _cb(cb), _destroyed(false) {
}
callback_wrapper(const callback_wrapper& other) {
_destroyed = other._destroyed;
Py_INCREF(other._cb.ptr());
_cb = other._cb;
}
~callback_wrapper() {
std::lock_guard<std::recursive_mutex> guard(_mutex);
PyGILState_STATE state = PyGILState_Ensure();
Py_DECREF(_cb.ptr());
PyGILState_Release(state);
_destroyed = true;
}
void operator ()(topic_ptr topic) {
std::lock_guard<std::recursive_mutex> guard(_mutex);
if(_destroyed) {
return;
}
PyGILState_STATE state = PyGILState_Ensure();
try {
_cb(topic);
}
catch(error_already_set) { PyErr_Print(); }
PyGILState_Release(state);
}
object _cb;
std::recursive_mutex _mutex;
bool _destroyed;
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13566 次 |
| 最近记录: |