I was debugging some code with pdb, and found that the program worked as intended whenever the pdb module was imported (whether or not any breakpoints were active), but crashes otherwise.
Specifically, the code is multithreaded standalone GUI application. The GUI is held in a side thread, while the main thread executes various operations as soon as the GUI is done constructing itself (i.e., they are added to the end of the queue of events on the event loop). Here is a minimal example:
#import pdb
class Gui(HasTraits):
hello = Button('hello')
def some_method(self):
print 58
class GuiThread(Thread):
def __init__(self):
Thread.__init__(self)
self.gui = Gui()
def run():
self.gui.configure_traits()
#pdb.set_trace()
g = GuiThread()
g.start()
from pyface.api import GUI
gui = GUI()
gui.invoke_later( g.gui.some_method )
This crashes with wx._core.PyDeadObjectError: The C++ part of the PyApp object has been deleted, attribute access no longer allowed
. However, if the single line import pdb
is uncommented, the program works as expected and the GUI thread prints 58 to stdout at the end of the event loop (even if the stack trace is not uncommented).
I have also been trying to test this behavior in some very simple wx applications that do not use traitsui. In these applications, the correct behavior (printing out 58) is found when debugging with a trace, but when not debugging the program segfaults.
My question is, what is pdb doing that might prevent the C++ objects from being garbage collected? Knowing this might help me trace down why this is happening.
See also the related questions here and here, which are somewhat less focused.