<type>how-to</type>
<domain>debug</domain>
<id>debugging-extension-modules-on-linux</id>
<title>Debugging Extension Modules on Linux/Unix</title>
<date>$Date$</date>
<version>$Revision$</version>
<product>per+</product>

The first step in debugging C/C++ modules with gdb is to make sure that you are using a
version of Python that was compiled with debug symbols. To do this, you need a source
distribution of Python and you need to configure the distribution as described in the
accompanying ``README.rst`` file.

In most cases, this can be done as follows: (1) Type ``./configure``, (2) type ``make
OPT=-g``, and (3) type ``make``. Once the build is complete you can optionally install it
with ``make install`` or just run Python in place without installing it.

When this is complete, compile your extension module against that version of Python.

**Starting Debug**

In order to run code both within Wing's Python debugger and gdb, launch your debug process
from Wing first, then note the process ID shown in the tooltip that appears when you hover
the mouse over the debug icon in the lower left of Wing's main window.

Next, start gdb and type ``attach <pid>`` where ``<pid>`` is replaced with the process ID
reported by Wing. This will pause the process as it attaches, which gives you a chance to
set breakpoints. When you're ready to continue the process, type ``c`` in gdb.

You are now debugging both at the Python and C/C++ level. You should be able to pause,
step, and view data in Wing whenever gdb is not paused. When gdb is paused, Wing's
debugger cannot be used until the process is continued at the gdb level.

**Tips and Tricks**

* ``Misc/gdbinit`` in the Python source distribution contains useful macros for
  inspecting Python code from gdb. For example, ``pystack`` will print the Python stack,
  ``pylocals`` will print the Python locals, and ``pyframe`` prints the current Python stack
  frame. To use it, copy it into your ``~/.gdbinit``.

* The following works to view Python data in ``PyObject * obj``::

    (gdb) p PyObject_Print (obj, stderr, 0)

* Breakpoints in a shared library cannot be set until after the shared library is
  loaded. ``^C^C`` can be used to interrupt the debug process, set breakpoints, and then
  continue.

* If ``LD_LIBRARY_PATH`` or other environment is not set as expected, check whether it
  is set in ``.cshrc``. This file is read each time gdb runs so may overwrite your value. To
  work around this, set ``LD_LIBRARY_PATH`` in ``.profile`` instead. This file is read only
  once at login time.

See `Debugging with Gdb <https://wiki.python.org/moin/DebuggingWithGdb>`__ for more 
information.

