Debugger Limitations


Home » Support » Index of All Documentation » Wing IDE Reference Manual » Advanced Debugging Topics »

There are certain situations that the debugger cannot handle, because of the way the Python programming language works. If you are having problems getting the debugger to stop at breakpoints or to display source as you step through your code, one or more of these may apply.

Always read the Trouble-shooting Failure to Debug section first. If that fails to uncover your problem, refer to the following detailed documention of debugger limitations (many of which are extremely rare and esoteric):

(1) Your source files must be stored on disk and accessible to the IDE. If you are trying to debug code fragments, try writing them to disk temporarily and setting the __file__ variable in the module name space before invoking Python's exec or eval. This will allow Wing's debugger to map code objects to the source you've temporarily written to disk.

(2) Running without saving will lead to incorrect display of breakpoints and run position because the debug process runs against the on-disk version of the source file. Wing will indicate in the Messages tool and Stack Data status indicator that some files are out of sync so this case should only occur if you ignore its warnings.

(3) You cannot run the debug program using the -O or -OO optimization options for the Python interpreter. This removes information about line numbers and source file names, making it impossible to stop at breakpoints or step through code.

(4) There are several cases where Wing may fail to stop at breakpoints or exceptions, or may fail to find source files corresponding with breakpoints or exception points. All of these are caused by storage of incorrect file names in *.pyc files:

  • Moving *.pyc files on disk after they are generated invalidates the file name stored in the file if it is a partial relative path. This happens if your PYTHONPATH or sys.path contains partial relative path names.
  • A similar problem may result from use of compileall.py and some other utilities that don't record a correct filename in the *.pyc file.
  • If you run the same code twice using different paths to the same working directory, as is possible on Linux/Unix with symbolic links, the file names left in *.pyc may contain a mix of each of these paths. If the symbolic link that was used is subsequently removed, some of the file names become invalid.

The fix for all of these problems is to remove the *.pyc files and let Python regenerate them from the corresponding *.py files with the correct file name information.

Hint: You can open *.pyc files in most text editors to inspect the stored file names.

(5) For code that spends much of its time in C/C++ without calling Python at all, for example as in a GUI main loop, the debugger may not reliably stop at breakpoints added during a run session, and may not respond to Pause requests. See section Debugging Non-Python Mainloops for more information.

(6) You cannot use pdb or other debuggers in code that you are running within the Wing debugger. The two debuggers conflict because they attempt to use the same debugger hooks in the Python interpreter.

(7) If you override __import__ in your code, you will break the debugger's ability to stop at breakpoints unless you call the original __import__ as part of your code whenever a module is actually imported. If you cannot call the original __import__ for some reason, it may be possible to instead use wingdbstub and then call wingdbstub.debugger.NotifyImport(mod) from your import handler (where mod is the module that was just imported).

(8) If you set __file__ in a module's name space to a value other than its original, Wing will be unable to stop at breakpoints in the module and may fail to report exceptions to the IDE's user interface.

(9) If you use an extension module to call C/C++ level stdio calls instead of using the Python-level facilities, the debug process will remain unresponsive to Wing IDE while waiting for keyboard input, I/O redirection to the Debug Probe in Wing Pro will fail, and you may run into out-of-order character reads in some cases. Details can be found in Debug Process I/O.

(10) Using partial path names in module __file__ attribute can in rare cases cause Wing to fail to stop on breakpoints and exceptions, to fail to display source files, or to confuse source files of the same name.

A partial path name may end up in __file__ only when (a) invoking Python code with a partial path name, for example with python myfile.py instead of python /path/to/myfile.py, (b) sending partial path names into exec, (c) using partial path names in your PYTHONPATH or sys.path, or (d) using compileall.py or similar tool to compile modules with a partial path name.

Because Wing does everything possible to avoid this problem in practice, it actually only occurs in the following rare cases:

  • When modules are loaded with partial path names and os.chdir() is called before debugging is started. This is only possible when using wingdbstub or otherwise starting debug after your debug process is started.
  • When modules are loaded with partial path names and os.chdir() is called after wingdbstub.debugger.SuspendDebug() and before wingdbstub.debugger.ResumeDebug().
  • When modules are loaded with partial path names and removed from sys.modules before the debugger is started or while debugging is suspended.
  • When code objects are created on the fly using compile(), the C API, or the new module, a relative filename or an incorrect filename are used for the filename argument, and os.chdir() is called before the code is executed.

(11) Wing tries to identify when source code in the IDE matches or does not match the code that is running in the debug process. There are certain very rare cases where this will fail, which may lead to failure to stop on breakpoints and other problems even when files are identified by the IDE as being synchronized:

Using execfile(), eval(), or exec with a globals dict that contains __file__ will cause Wing to incorrectly assert that the specified file has been reloaded. In practice, this scenario usually occurs when execfile() is called from the top level of a module, in which case the module is in fact being loaded or reloaded (so no mis-identification of module load status occurs). However, in cases where a module load takes a long time or involves a long-running loop at the top level, the execfile(), eval(), or exec may occur after edits to the module have been made and saved. In this case, Wing will mis-identify the module as having been reloaded with the new edits.

This problem can also be triggered if a globals with __file__ is explicitly passed to execfile(), eval(), or exec. However, it will only occur in this case when the code object file name is ?, and locals and globals dictionaries are the same, as they are by default for these calls.

(12) In very rare cases, when using the wingdbstub.py, if you set sys.exitfunc after debugging has been started, the IDE will time out on a broken network connection after the debug program exits on an exception. This only happens in some exception handling modes with exceptions that look like they will be handled because a try/except block is present that might handle the exception, but where the exception is not in the end handled and the debug program exits without calling StopDebug(). Work-arounds include setting sys.exitfunc before importing wingdbstub.py or adding a top-level try/except clause that always calls StopDebug() before exiting the debug program.

(13) Naming a file <string> will prevent the debugger from debugging that file because it is confused with the default file name used in Python for code that is not located in a file.

(14) The debugger may fail to step or start after stopping at a breakpoint if the floating point mode is set to single precision (24 bit) on Intel x86 and potentially other processors. This is sometimes done by graphics libraries such as DirectX or by other code that optimizes floating point calculations.

(15) When using Stackless Python, overriding stackless.tasklet.__call__ without calling the Wing debugger's __call__ will break the debugger.

« 13.9. Debugging Code Running Under Py2exeTable of Contents14. Integrated Version Control »