

Debugging Non-Python Mainloops

Because of the way the Python interpreter supports debugging, the debug process may become unresponsive if your debug process is free-running for long periods of time in non-Python code, such as C or C++. Whenever the Python interpreter is not called for long periods of time, messages from Wing IDE may be entirely ignored and the IDE may disconnect from the debug process. This primarily affects pausing a free-running program or setting, deleting, or editing breakpoints while free-running.

Examples of environments that can spend significant amounts of time outside of the Python interpreter include GUI kits such as Gtk, Qt, Tkinter, wxPython, and some web development tools like Zope. For the purposes of this section, we call these "non-Python mainloops".

Supported Non-Python Mainloops

Wing already supports Gtk, Tkinter, wxPython, and Zope. If you are using one of these, or you aren't using a non-Python mainloop at all, then you do not need to read further in this section.

Working with Non-Python Mainloops

If you are using an unsupported non-Python mainloop that normally doesn't call Python code for longer periods of time, you can work around the problem by adding code to your application that causes Python code to be called periodically.

The alternative to altering your code is to write special plug-in support for the Wing debugger that causes the debug server sockets to be serviced even when your debug program is free-running in non-Python code. The rest of this section describes what you need to know in order to do this.

Non-Python Mainloop Internals

Wing uses a network connection between the debug server (the debug process) and the debug client (Wing IDE) to control the debug process from the IDE and to inform the IDE when events (such as reaching a breakpoint or exception) occur in the debug process.

As long as the debug program is paused or stopped at a breakpoint or exception, the debugger remains in control and it can respond to requests from the IDE. Once the debug program is running, however, the debugger itself is only called as long as Python code is being executed by the interpreter.

This is usually not a problem because most running Python program are executing a lot of Python code. However, in a non-Python mainloop, the program may remain entirely in C, C++, or another language and not call the Python interpreter at all for long periods of time. As a result, the debugger does not get a chance to service requests from the IDE. Pause or attach requests and new breakpoints may be completely ignored in this case, and the IDE may detach from the debug process because it is unresponsive.

Wing deals with this by installing its network sockets into each of the supported non-Python mainloops, when they are detected as present in the debug program. Once the sockets are registered, the non-Python mainloop will call back into Python code whenever there are network requests pending.

Supporting Non-Python Mainloops

For those using an unsupported non-Python mainloop, Wing provides an API for adding the hooks necessary to ensure that the debugger's network sockets are serviced at all times.

If you wish to write support for a non-Python mainloop, you first need to check whether there is any hope of registering the debugger's socket in that environment. Any mainloop that already calls UNIX/BSD sockets select() and is designed for extensible socket registration will work and is easy to support. Gtk and Zope both fell into this category.

In other cases, it may be necessary to write your own select() call and to trick the mainloop into calling that periodically. This is how the Tkinter and wxPython hooks work. Some environments may additionally require writing some non-Python glue code if the environment is not already set up to call back into Python code.

Mainloop hooks are written as separate modules that are placed into src/debug/tserver within WINGHOME (the Wing IDE installation directory, or on OS X Contents/Resources in Wing's .app folder). The module _extensions.py also found there includes a generic class that defines the API functions required of each module, and is the place where new modules must be registered (in the constant kSupportedMainloops).

Writing Non-Python Mainloop Support

To add your own non-Python mainloop support, you need to:

  • Copy one of the source examples (such as _gtkhooks.py) found in src/debug/server, as a framework for writing your hooks. Name your module something like _xxxxhooks.py where xxxx is the name of your non-Python mainloop environment.
  • Implement the _Setup(), RegisterSocket(), and UnregisterSocket() methods. Do not alter any code from the examples except the code with in the methods. The name of the classes and constants at the top level of the file must remain the same.
  • Add the name of your module, minus the '.py' to the list kSupportedMainloops in _extensions.py

Examples of existing support hooks for non-Python mainloops can be found in src/debug/tserver within WINGHOME.

If you have difficulties writing your non-Python mainloop hooks, please contact Technical Support via http://wingware.com/support. We will be happy to assist you, and welcome the contribution of any hooks you may write.

Debugging Non-Python Mainloops