Tôi đã gặp sự cố này bằng cách sử dụng boost :: python khi mã C++ của chúng tôi kích hoạt gọi lại python.Tôi thỉnh thoảng sẽ nhận được "đối tượng GC đã được theo dõi" và chương trình sẽ chấm dứt.
Tôi đã có thể đính kèm GDB vào quy trình trước khi kích hoạt lỗi. Một điều thú vị, trong mã python, chúng tôi đã gói lại gọi lại với một phần functools, đã thực sự che giấu nơi xảy ra lỗi thực sự. Sau khi thay thế một phần bằng một lớp trình bao bọc có thể gọi đơn giản. "Đối tượng GC đã được theo dõi lỗi" không còn xuất hiện nữa, thay vào đó tôi bây giờ chỉ nhận được một segfault.
Trong tăng của chúng tôi :: trình bao python, chúng tôi đã có hàm lambda để xử lý cuộc gọi lại C++ và hàm lambda đã bắt hàm tăng :: python :: object callback. Hóa ra, vì lý do gì đó, trong destructor cho lambda, nó không phải lúc nào cũng có được GIL khi phá hủy boost :: python :: object đã gây ra segfault.
Khắc phục là không sử dụng hàm lambda, mà thay vào đó hãy tạo một hàm functor để đảm bảo có được GIL trong trình hủy trước khi gọi PyDECREF() trên đối tượng boost :: python ::.
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;
};
Có, bạn có thể tạo một bãi chứa. Trên thực tế, kết xuất được tạo tự động khi có sự cố (segfault) như được mô tả trong bài viết mà bạn đã đề cập đến. Nhưng bạn có thể ép buộc hoạt động bằng tay, bằng cách gửi tín hiệu quá trình bằng cách sử dụng 'kill'. BTW Bạn đã xem http://pyrit.wordpress.com/2010/02/18/385/ chưa? – user3159253
Khi chúng tôi đang thiết lập cho kết xuất lõi, bạn có biết tệp kết xuất được tạo khi quá trình này bị trục trặc và biến mất không? – Feru
Bãi chứa được lưu trữ trong thư mục làm việc hiện tại của một quá trình. – user3159253