如何调试 PyQt 崩溃?

How to debug PyQt crashes?

我正在开发一个国际象棋程序,其中 GUI 通过 UCI protocol 与引擎通信,目前使用 OSX 和 PyCharm。我正在使用 QProcess 进行通信。

我的应用崩溃了,但我无法确定地重现这些崩溃。 Python 输出只给出

Process finished with exit code 134

OSX 上的崩溃报告提供了这份详细报告,但老实说,我完全不知道如何取得进一步进展。我怀疑线程有问题,但如何调试?

Process:         Python [527]
Path:            /usr/local/Cellar/python3/3.4.1/Frameworks/Python.framework/Versions/3.4/Resources/Python.app/Contents/MacOS/Python
Identifier:      org.python.python
Version:         3.4.1 (3.4.1)
Code Type:       X86-64 (Native)
Parent Process:  pycharm [360]
Responsible:     pycharm [360]
User ID:         501

Date/Time:       2015-02-16 10:40:09.497 +0100
OS Version:      Mac OS X 10.9.5 (13F34)
Report Version:  11
Anonymous UUID:  XXXXXX


Crashed Thread:  4  Uci_engine

Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000

Application Specific Information:
abort() called
*** error for object 0x7fb104975000: pointer being realloc'd was not allocated


Thread 0:: Dispatch queue: com.apple.main-thread
0   QtCore                          0x0000000109475d2e QByteArray::resize(int) + 6
1   QtCore                          0x00000001094ec5e9 QRingBuffer::clear() + 123
2   QtCore                          0x00000001094f58ab QProcess::readData(char*, long long) + 257
3   QtCore.so                       0x000000010a081784 sipQProcess::readData(char*, long long) + 106
4   QtCore                          0x00000001094f0648 QIODevice::read(char*, long long) + 828
5   QtCore                          0x00000001094f0a92 QIODevice::readAll() + 398
6   QtCore                          0x00000001094f59a6 QProcess::readAllStandardOutput() + 48
7   QtCore.so                       0x000000010a082b78 meth_QProcess_readAllStandardOutput(_object*, _object*) + 120
8   org.python.python               0x0000000107cbad5c PyEval_EvalFrameEx + 19156
9   org.python.python               0x0000000107cb60d4 PyEval_EvalCodeEx + 1628
10  org.python.python               0x0000000107c490b8 function_call + 360
11  org.python.python               0x0000000107c2be11 PyObject_Call + 103
12  org.python.python               0x0000000107c3a8a4 method_call + 136
13  org.python.python               0x0000000107c2be11 PyObject_Call + 103
14  org.python.python               0x0000000107cbdb30 PyEval_CallObjectWithKeywords + 93
15  sip.so                          0x00000001097bfd68 sip_api_invoke_slot_ex + 435
16  QtCore.so                       0x000000010a0f5cb0 PyQtProxy::invokeSlot(qpycore_slot const&, void**, int) + 162
17  QtCore.so                       0x000000010a0f5b7c PyQtProxy::unislot(void**) + 184
18  QtCore.so                       0x000000010a0f5ab3 PyQtProxy::qt_metacall(QMetaObject::Call, int, void**) + 111
19  QtCore                          0x000000010956222d QObject::event(QEvent*) + 637
20  QtGui                           0x0000000108985ed5 QApplicationPrivate::notify_helper(QObject*, QEvent*) + 195
21  QtGui                           0x0000000108987419 QApplication::notify(QObject*, QEvent*) + 889
22  QtGui.so                        0x000000010811a29a sipQApplication::notify(QObject*, QEvent*) + 122
23  QtCore                          0x0000000109551bb8 QCoreApplication::notifyInternal(QObject*, QEvent*) + 118
24  QtCore                          0x000000010955259c QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) + 716
25  com.apple.CoreFoundation        0x00007fff904985b1 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
26  com.apple.CoreFoundation        0x00007fff90489c62 __CFRunLoopDoSources0 + 242
27  com.apple.CoreFoundation        0x00007fff904893ef __CFRunLoopRun + 831
28  com.apple.CoreFoundation        0x00007fff90488e75 CFRunLoopRunSpecific + 309
29  com.apple.HIToolbox             0x00007fff87427a0d RunCurrentEventLoopInMode + 226
30  com.apple.HIToolbox             0x00007fff87427685 ReceiveNextEventCommon + 173
31  com.apple.HIToolbox             0x00007fff874275bc _BlockUntilNextEventMatchingListInModeWithFilter + 65
32  com.apple.AppKit                0x00007fff87e5724e _DPSNextEvent + 1434
33  com.apple.AppKit                0x00007fff87e5689b -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 122
34  com.apple.AppKit                0x00007fff87e4a99c -[NSApplication run] + 553
35  QtGui                           0x0000000108943936 QEventDispatcherMac::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 540
36  QtCore                          0x000000010954f215 QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 77
37  QtCore                          0x000000010954f386 QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) + 356
38  QtCore                          0x0000000109552009 QCoreApplication::exec() + 199
39  QtGui.so                        0x000000010811b4eb meth_QApplication_exec_(_object*, _object*) + 80
40  org.python.python               0x0000000107cbad5c PyEval_EvalFrameEx + 19156
41  org.python.python               0x0000000107cb60d4 PyEval_EvalCodeEx + 1628
42  org.python.python               0x0000000107cb5a72 PyEval_EvalCode + 63
43  org.python.python               0x0000000107cd9b28 run_mod + 58
44  org.python.python               0x0000000107cd9dc7 PyRun_FileExFlags + 178
45  org.python.python               0x0000000107cd95e7 PyRun_SimpleFileExFlags + 909
46  org.python.python               0x0000000107cec4f7 Py_Main + 3095
47  org.python.python               0x0000000107c19e27 0x107c18000 + 7719
48  libdyld.dylib                   0x00007fff87a165fd start + 1

Thread 1:: Dispatch queue: com.apple.libdispatch-manager
0   libsystem_kernel.dylib          0x00007fff8e18f662 kevent64 + 10
1   libdispatch.dylib               0x00007fff86c6f421 _dispatch_mgr_invoke + 239
2   libdispatch.dylib               0x00007fff86c6f136 _dispatch_mgr_thread + 52

Thread 2:
0   libsystem_kernel.dylib          0x00007fff8e18aa1a mach_msg_trap + 10
1   libsystem_kernel.dylib          0x00007fff8e189d18 mach_msg + 64
2   com.apple.CoreFoundation        0x00007fff90489f15 __CFRunLoopServiceMachPort + 181
3   com.apple.CoreFoundation        0x00007fff90489539 __CFRunLoopRun + 1161
4   com.apple.CoreFoundation        0x00007fff90488e75 CFRunLoopRunSpecific + 309
5   com.apple.AppKit                0x00007fff87ff705e _NSEventThread + 144
6   libsystem_pthread.dylib         0x00007fff8c7a2899 _pthread_body + 138
7   libsystem_pthread.dylib         0x00007fff8c7a272a _pthread_start + 137
8   libsystem_pthread.dylib         0x00007fff8c7a6fc9 thread_start + 13

Thread 3:: QProcessManager
0   libsystem_kernel.dylib          0x00007fff8e18e9aa __select + 10
1   QtCore                          0x000000010952cf86 QProcessManager::run() + 132
2   QtCore                          0x00000001094735ba QThreadPrivate::start(void*) + 386
3   libsystem_pthread.dylib         0x00007fff8c7a2899 _pthread_body + 138
4   libsystem_pthread.dylib         0x00007fff8c7a272a _pthread_start + 137
5   libsystem_pthread.dylib         0x00007fff8c7a6fc9 thread_start + 13

Thread 4 Crashed:: Uci_engine
0   libsystem_kernel.dylib          0x00007fff8e18e866 __pthread_kill + 10
1   libsystem_pthread.dylib         0x00007fff8c7a335c pthread_kill + 92
2   libsystem_c.dylib               0x00007fff91b34b1a abort + 125
3   libsystem_malloc.dylib          0x00007fff876b5451 realloc + 364
4   QtCore                          0x00000001094762dd QByteArray::realloc(int) + 161
5   QtCore                          0x0000000109475d88 QByteArray::resize(int) + 96
6   QtCore                          0x00000001094ec6c1 QRingBuffer::reserve(int) + 157
7   QtCore                          0x00000001094f41ec QProcessPrivate::_q_canReadStandardOutput() + 76
8   QtCore                          0x00000001094f65ce QProcess::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) + 364
9   QtCore                          0x0000000109565d71 QMetaObject::activate(QObject*, QMetaObject const*, int, void**) + 2037
10  QtCore                          0x00000001095a7b68 QSocketNotifier::activated(int) + 60
11  QtCore                          0x000000010956a421 QSocketNotifier::event(QEvent*) + 383
12  QtGui                           0x0000000108985ed5 QApplicationPrivate::notify_helper(QObject*, QEvent*) + 195
13  QtGui                           0x0000000108987419 QApplication::notify(QObject*, QEvent*) + 889
14  QtGui.so                        0x000000010811a29a sipQApplication::notify(QObject*, QEvent*) + 122
15  QtCore                          0x0000000109551bb8 QCoreApplication::notifyInternal(QObject*, QEvent*) + 118
16  QtCore                          0x0000000109579db7 QEventDispatcherUNIX::activateSocketNotifiers() + 203
17  QtCore                          0x0000000109579b8e QEventDispatcherUNIXPrivate::doSelect(QFlags<QEventLoop::ProcessEventsFlag>, timeval*) + 1426
18  QtCore                          0x000000010957ae39 QEventDispatcherUNIX::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 341
19  QtCore                          0x000000010954f215 QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 77
20  QtCore                          0x000000010954f386 QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) + 356
21  QtCore                          0x0000000109471ca5 QThread::exec() + 217
22  QtCore.so                       0x000000010a0c28f3 meth_QThread_exec_(_object*, _object*) + 99
23  org.python.python               0x0000000107cbad5c PyEval_EvalFrameEx + 19156
24  org.python.python               0x0000000107cb60d4 PyEval_EvalCodeEx + 1628
25  org.python.python               0x0000000107c490b8 function_call + 360
26  org.python.python               0x0000000107c2be11 PyObject_Call + 103
27  org.python.python               0x0000000107c3a8a4 method_call + 136
28  org.python.python               0x0000000107c2be11 PyObject_Call + 103
29  org.python.python               0x0000000107cbdb30 PyEval_CallObjectWithKeywords + 93
30  sip.so                          0x00000001097b6559 sip_api_call_method + 214
31  QtCore.so                       0x000000010a002174 sipVH_QtCore_11(PyGILState_STATE, void (*)(_sipSimpleWrapper*, PyGILState_STATE), _sipSimpleWrapper*, _object*) + 47
32  QtCore.so                       0x000000010a0c24fb sipQThread::run() + 79
33  QtCore                          0x00000001094735ba QThreadPrivate::start(void*) + 386
34  libsystem_pthread.dylib         0x00007fff8c7a2899 _pthread_body + 138
35  libsystem_pthread.dylib         0x00007fff8c7a272a _pthread_start + 137
36  libsystem_pthread.dylib         0x00007fff8c7a6fc9 thread_start + 13

Thread 5:
0   libsystem_kernel.dylib          0x00007fff8e18ee6a __workq_kernreturn + 10
1   libsystem_pthread.dylib         0x00007fff8c7a3f08 _pthread_wqthread + 330
2   libsystem_pthread.dylib         0x00007fff8c7a6fb9 start_wqthread + 13

Thread 4 crashed with X86 Thread State (64-bit):
  rax: 0x0000000000000000  rbx: 0x000000010a84d000  rcx: 0x000000010a84bd98  rdx: 0x0000000000000000
  rdi: 0x0000000000002f1f  rsi: 0x0000000000000006  rbp: 0x000000010a84bdc0  rsp: 0x000000010a84bd98
   r8: 0x00000000fffffff8   r9: 0x0000000000000000  r10: 0x0000000008000000  r11: 0x0000000000000206
  r12: 0x00007fb104975000  r13: 0x0000000000000004  r14: 0x0000000000000006  r15: 0x0000000107c1e000
  rip: 0x00007fff8e18e866  rfl: 0x0000000000000206  cr2: 0x00007fff784a0408

Logical CPU:     0
Error Code:      0x02000148
Trap Number:     133

看起来这个线程崩溃了。

Thread 4 Crashed:: Uci_engine
0   libsystem_kernel.dylib          0x00007fff8e18e866 __pthread_kill + 10
1   libsystem_pthread.dylib         0x00007fff8c7a335c pthread_kill + 92
2   libsystem_c.dylib               0x00007fff91b34b1a abort + 125
3   libsystem_malloc.dylib          0x00007fff876b5451 realloc + 364
4   QtCore                          0x00000001094762dd QByteArray::realloc(int) + 161

这个线程崩溃导致整个程序崩溃退出

从栈上看,内存访问异常,通常这种调试对python来说比较困难,对PyQt来说更复杂。它需要你了解很多cpython和它的实现,此外你还应该了解Qt和Sip的实现,因为Cpython有GC,所以比较复杂。在我看来,如果可以重现,则尝试添加更多日志以找出导致此问题的代码行。如果这种情况偶尔发生并且通常发生在 Qt 退出时间,那么您应该优雅地设置继承树。

此外,您使用的 pycharm 是哪个版本?最新的 PyCharm 4.* 将在调试期间自动挂钩 python 可执行程序,我发现有时它会在复杂的 PyQt 项目的调试期间崩溃,但如果 运行 没有调试,如果这仅发生在 "debug" 程序中,您可以尝试切换到更早的 pycharm 或禁用此自动挂接功能。