Debugging Child Processes

Index of All Documentation » Wing Pro Reference Manual » Debugger » Multi-Process Debugging »

Sub-processes started with the Python multiprocessing module or with os.fork() may be debugged automatically, so that each child process appears as a separate debug process in Wing. This is disabled by default but can be enabled with the Debugger > Processes > Debug Child Processes preference or by setting Debug/Execute > Debug Child Processes in Project Properties.

Sub-processes started with os.system(), CreateProcess (on Windows), os.exec() (on Posix), or similar calls will not be debugged automatically because the OS completely replaces the parent process context and there is no way to keep a debug connection intact. However, it is still possible to debug processes launched in this way by manually initiating debug in the sub-process as described in Debugging Externally Launched Code.

Notice that processes started by os.fork() followed by os.exec() will be debugged only for the (usually brief) period of time between the os.fork() and os.exec() calls.

Debugging Child Processes Created with sys.executable

By default when debugging sub-processes is enabled, Wing replaces sys.executable to cover some of the common ways in which sub-processes may be launched, particularly on Windows. This can be disabled with the Debugger > Processes > Replace sys.executable preference.

Because the multiprocessing standard library module uses sys.executable to launch its children on Windows, this option must be enabled in order to debug children created by that module.

Wing replaces sys.executable at startup only. As a result, user code that alters the value (other than by calling multiprocessing.forking.set_executable) will break debugging of child processes that are launched with a command line that contains sys.executable.

When sys.executable replacement is enabled, code that invokes sys.executable to start a child process must also provide the environment variables starting with WINGDB_ to the child process. Otherwise, the debugger cannot determine which Python to run or how to connect to the IDE and the child process will fail to start.

If child processes are created with sys.executable the code that starts the child processes will need to correctly handle spaces in the path within sys.executable. Otherwise, child processes will fail to launch if Wing is installed into a directory path that has spaces in it and child process debugging is enabled.

One way to work around cases where sys.executable replacement does not work is to manually initiating debug in the sub-process as described in Debugging Externally Launched Code.

Target Processes for Handles on Windows

Replacing sys.executable will cause problems on Windows if a parent process launches children with a command line that contains a Handle created specifically for its child process, for example by setting hTargetProcessHandle in a call to DuplicateHandle. In this case, the handle will be invalid in the child because replacing sys.executable creates an intervening process and the child runs as the grand-child instead.

If a Handle is instead set to be inheritable for all child processes, for example by setting bInheritHandle in a call to DuplicateHandle, then replacing sys.executable will work without any problems.

Other Notes and Limitations

When debugging child processes created with the multiprocessing module, Wing will stop on exceptions raised in child processes. Continuing debug from that point will pack up and return the exception to the parent process, as in normal operation. Exceptions in children can be ignored with the Ignore this exception location checkbox in the Exceptions tool.

Overriding the _bootstrap method of multiprocessing.process.Process (or multiprocessing.process.BaseProcess in Python 3.4+) in a custom process class will prevent Wing from stopping on exceptions in child processes unless the exception is propagated to the inherited method. A work-around for this would be to call logging.exception with any exception before sending it out to the parent process.

Some approaches to spawning child processes may result in the creation of intermediate processes that appear in Wing's process tree display. For example, using the shell=True option in subprocess.Popen will do this on Linux. When setting shell=False you may need to change the command passed to Popen to a list rather than a string.

Debug overhead may reveal timing bugs not seen outside of the debugger. For example, a parent process may attempt to interact with a child process too quickly, causing problems only under the debugger. This is particularly likely on Windows, where there is an intermediate process created between the parent and child process.