There are types of bugs that are difficult to debug from within Python:

In these cases, you can try gdb.

Prerequisites

You need to have gdb on your system and Python debugging extensions. Extensions package includes debugging symbols and adds Python-specific commands into gdb. On a modern Linux system, you can easily install these with:

Fedora:

Ubuntu:

Centos*:

* tested on Centos 7. python-debuginfo is installable after the first two commands.

For gdb support on legacy systems, look at the end of this page.

Running with `gdb`

There are two possible ways:

  1. run python under gdb from the start. Note: the python executable needs to have debug symbols in it which may be another exe python2.7-dbg depending on your system

  2. attach to already running python process

To run python under gdb there are also two ways.

Interactive:

Automatic:

This will run the program til it exits, segfaults or you manually stop execution (using Ctrl+C).

If the process is already running, you can attach to it provided you know the process ID.

Attaching to a running process like this will cause it to stop. You can tell it to continue running with c command.

Debugging process

If your program segfaulted, gdb will automatically pause the program, so you can switch into gdb console to inspect its state. You can also manually interrupt program execution by pressing Ctrl+C in the console.

See the page EasierPythonDebugging for the list of Python helper commands for gdb.

Getting a C Stack Trace

If you are debugging a segfault, this is probably the first thing you want to do.

At the (gdb) prompt, just run the following command:

With luck, this will give some idea of where the problem is occurring and if it doesn't help you fix the problem, it can help someone else track down the problem.

The quality of the results will depend greatly on the amount of debug information available.

Getting a Python Stack Trace

If you have Python extensions installed, you can enter:

to get stack trace with familiar Python source code.

Working With Hung Processes

If a process appears hung, it will either be waiting on something (a lock, IO, etc), or be in a busy loop somewhere. In either case, attaching to the process and getting a back trace can help.

If the process is in a busy loop, you may want to continue execution for a bit (using the cont command), then break (Ctrl+C) again and bring up a stack trace.

If the hang occurs in some thread, the following commands may be handy:

Current thread is marked with *. To see where it is in Python code, use py-list:

To see Python code positions for all threads, use:

References

GDB on Legacy systems

It may happen that you need to use gdb on a legacy system without advanced Python support. In this case you may find the following information useful.

GDB Macros

A set of GDB macros are distributed with Python that aid in debugging the Python process. You can install them by adding the contents of Misc/gdbinit in the Python sources to ~/.gdbinit -- or copy it from Subversion. Be sure to use the correct version for your version of Python or some features will not work.

Note that the new GDB commands this file adds will only work correctly if debugging symbols are available.

Depending on how you've compiled Python, some calls may have had their frame pointers (i.e. $fp in GDB) optimised away, which means GDB won't have access to local variables like co that can be inspected for Python callstack information. For example, if you compile using -g -O3 using GCC 4.1, then this occurs. Similarly, with gcc 4.5.2 on Ubuntu (at least) the macros fail for the same reason. The usual symptom is that you'll see the call_function routine appearing to be between PyEval_EvalFrameEx and PyEval_EvalCodeEx, and the macro failing with No symbol "co" in current context.. There are two work-arounds for the issue:

Also note that the stop condition for the while-loops in the pystack and pystackv routines were originally designed for the case where you're running the Python interpreter directly, and not running the interpreter withing another program (by loading the shared library and manually bootstrapping the interpreter). So you may need to tweak the while-loops depending on the program you're intending to debug. See, for example, this StackOverflow post for another (putative) stop condition.

Getting Python Stack Traces With GDB Macros

At the gdb prompt, you can get a Python stack trace:

Alternatively, you can get a list of the Python locals along with each stack frame:

More useful macros not in python's gdbinit file

See http://web.archive.org/web/20070915134837/http://www.mashebali.com/?Python_GDB_macros:The_Macros for some more handy python gdb macros.

DebuggingWithGdb (last edited 2016-07-21 12:06:25 by DanKoretsky)

Unable to edit the page? See the FrontPage for instructions.