<type>documentation</type>
<domain>debug</domain>
<id>debugger-api</id>
<title>Debugger API</title>
<date>$Date$</date>
<version>$Revision$</version>
<product>per+</product>

The debugger API controls debugging more closely from your Python code. It is used to
control threaded debugging, and to develop support for debugging embedded scripting or
other custom environments.

**High-Level API**

To use the high-level API, you must first configure and ``import wingdbstub`` as described
in `Debugging Externally Launched Code <ref:debug/debugging-externally-launched-code>`__
for code running on the same host as the IDE, or `Debugging Remotely Launched Code
<ref:debug/remote-debugging>`__ if you are debugging code running on another host:

* ``wingdbstub.Ensure(require_connection=1, require_debugger=1)`` ensures that the debugger
  is running and connected to the IDE. If ``require_connection`` is true, ``ValueError``
  will be raised if a connection to the IDE cannot be made. If ``require_debugger`` is true,
  ``ValueError`` will be raised if the debugger binaries cannot be found or the debugger
  cannot be started.

**Low-Level API**

The low-level API can be used through ``sys._wing_debugger`` (after ``import sys``) in
debug processes launched from the IDE or those using ``wingdbstub``. In the latter case,
the same API is available on ``wingdbstub.debugger``:

* ``SetDebugThreadIdents(threads={}, default_policy=1)`` can be used in multi-threaded
  code to tell the debugger which threads to debug. Set ``threads`` to a dictionary that maps
  from thread id, as obtained from ``thread.get_ident()``, or ``thread_id`` in the
  ``PyThreadState``, to one of the following values: ``0`` to run the thread without debug,
  or ``1`` to debug the thread and immediately stop it if any thread stops. Set
  ``default_policy`` to the action to take when a thread is not found in the thread map.
  
* ``Break()`` pauses the free-running debug program on the current line, as if at a
  breakpoint.
  
* ``SuspendDebug()`` disables debugging, in order to temporarily avoid debug overhead.
  This leaves the connection to the IDE intact so that resuming is faster.
  
* ``ResumeDebug()`` resumes debugging if it has been called as often as ``SuspendDebug()``.

  Here is a simple usage example:

.. python::
  
    import wingdbstub
    a = 1 # This line is debugged
    wingdbstub.debugger.SuspendDebug()
    x = 1 # This is executed without debugging
    wingdbstub.debugger.ResumeDebug()
    y = 2 # This line is debugged
    
* ``StopDebug()`` stops debugging completely and disconnects from Wing. The debug program
  continues executing in non-debug mode and must be restarted to start debugging again.
  
* ``StartDebug(stophere=0, connect=1)`` starts debugging, optionally connecting back to
  the IDE and/or stopping immediately afterwards.  This does not work after ``StopDebug()``
  has been called.
  
* ``ProgramQuit()`` may need to be called before the debug program is exited if
  ``kEmbedded`` was set to ``1`` in ``wingdbstub.py``. This makes sure the debug 
  connection to the IDE is closed cleanly. See `Debugging Embedded Python Code
  <ref:debug/debugging-embedded-code>`__ for details on when this is needed.
  
