Stefan Hajnoczi
Sometimes it’s not humanly possible to inspect or modify data structures manually in a debugger because they are too large or complex to navigate. Think of a linked list with hundreds of elements, one of which you need to locate. Finding the needle in the haystack is only possible by scripting the debugger to automate repetitive steps.
This article gives an overview of the GNU Debugger’s Python scripting support so that you can tackle debugging tasks that are not possible manually.
What scripting GDB in Python can do
GDB can load Python scripts to automate debugging tasks and to extend debugger functionality. I will focus mostly on automating debugging tasks but extending the debugger is very powerful though rarely used.
Say you want to search a linked list for a particular node:
(gdb) p node.next . (gdb) p node.next.next . (gdb) p node.next.next.next
Doing this manually can be impossible for lists with too many elements. GDB scripting support allows this task to be automated by writing a script that executes debugger commands and interprets the results.
Loading Python scripts
The source GDB command executes files ending with the .py extension in a Python interpreter. The interpreter has access to the gdb Python module that exposes debugging APIs so your script can control GDB.
$ cat my-script.py print('Hi from Python, this is GDB <>'.format(gdb.VERSION)) $ gdb (gdb) source my-script.py Hi from Python, this is GDB Fedora 8.3.50.20190824-28.fc31
Notice that the gdb module is already imported. See the GDB Python API documentation for full details of this module.
It’s also possible to run ad-hoc Python commands from the GDB prompt:
Executing commands
GDB commands are executed using gdb.execute(command, from_tty, to_string). For example, gdb.execute('step') runs the step command. Output can be collected as a Python string by setting to_string to True. By default output goes to the interactive GDB session.
Although gdb.execute() is fundamental to GDB scripting, at best it allows screen-scraping (interpreting the output string) rather than a Pythonic way of controlling GDB. There is actually a full Python API that represents the debugged program’s types and values in Python. Most scripts will use this API instead of simply executing GDB commands as if simulating an interactive shell session.
Navigating program variables
The entry point to navigating program variables is gdb.parse_and_eval(expression). It returns a gdb.Value.
When a gdb.Value is a struct its fields can be indexed using value['field1']['child_field1'] syntax. The following example iterates a linked list:
elem = gdb.parse_and_eval('block_backends.tqh_first') while elem: name = elem['name'].string() if name == 'drive2': print('Found <>'.format(elem['dev'])) break elem = elem['link']['tqe_next']
This script iterates the block_backends linked list and checks the name field of each element against "drive2". When it finds "drive2" it prints the dev field of that element.
Conclusion
Python scripts can automate tedious debugging tasks in GDB. Having the full power of Python and access to file I/O, HTTP requests, etc means pretty much any debugging task can be turned into a full-blown program. A subset of this was possible in the past through GDB command scripts, but Python is a much more flexible programming language and familiar to many developers (more so than GDB’s own looping and logic commands!).
Debugger does not start. GDB not support Python scripting.
Hi I have just upgraded to Qt Creator 5.3
When I try to run the debugger I get the message box
«The selected build of GDB does not support Python scripting it cannot be used in Qt Creator»
And no debugging happens.
When I run the auto detected GDBs in Options | Build & Run I get below. (Ubuntu 14.04) I get the following results.
$ gdb version
GNU gdb (GDB) 7.7
. $ python —version
Python 2.7.6
. Before I upgraded, debugging could happen, but local variable informatino was not very good. Thanks for anyhelp
What does gdb says if you run python inside it.
@
(gdb) python print(«Hello, world!»)
Hello, world!
(gdb)
@
I guess you need to check python version. On Ubuntu 14.04 I have (gdb) python import sys; print (sys.version)
3.4.0 (default, Apr 11 2014, 13:08:54)
[GCC 4.8.2]
(gdb) And I have both 2.7 and 3.4 python installed. $ python —version
Python 2.7.6 $ python3 —version
Python 3.4.0
Ah! I get (gdb) python print(«Hello world!»)
Python scripting is not supported in this copy of GDB.
(gdb)
The latest version of QtCreator does not support gdb without python, so you need to install Ubuntu package or build gdb with python support Here is how it looks like on Ubuntu 14.04
@
$ gdb —version
GNU gdb (Ubuntu 7.7-0ubuntu3.1) 7.7
@
Thanks, inspired by http://blog.hostilefork.com/qtcreator-debugger-no-locals-ubuntu/ I dowloaded gdb 7.7.1 from http://ftp.gnu.org/gnu/gdb/ I then run form gdb-7.7.1 directory(not sure whether configure options needed) ./configure —prefix /usr/local/gdb-python2 —with-python
make
make install I then created a new debugger link in Tools | Options | Build & Run, Debugger manual section pointing to /usr/local/gdb-python2/bin/gdb, and a new kit in Kits Manual section using that link. It seems to be able to debug now.
sudo apt-get install gdb-python2
Check gdb packet, on my system (Kali Linux) by default was installed «gdb-minimal». Replase it by full «gdb» packet with include python support.
@Sriep I am using below configuration Ubuntu 16 Qt 3.5.1 and I want to debug an application to raspberry pi from Host PC. I am able to run the application in release mode to Rpi. I tried same solutions and able to install the gdb-7.7.1 and installed it and configuring it.. But I am still receiving the below errors. Debugging starts
Listening on port 10005
Remote debugging from host 192.168.0.108
Process /home/pi/appchooser/build-appchooser-RaspberryPi-Debug/appchooser created; pid = 6518
Build ID mismatch between current exec-file /home/sruhad/QtSample/QtSample/build-appchooser-LocalPC-Debug/appchooser
and automatically determined exec-file loading /home/pi/appchooser/build-appchooser-RaspberryPi-Debug/appchooser /home/pi/appchooser/build-appchooser-RaspberryPi-Debug/appchooser: Not a directory.
while parsing target description (at line 10): Target description specified unknown architecture «arm»
Could not load XML target description; ignoring
Killing process(es): 6518
Debugging has finished Debugging log: &»warning: while parsing target description (at line 10): Target description specified unknown architecture «arm»\n»
while parsing target description (at line 10): Target description specified unknown architecture «arm»
&»warning: Could not load XML target description; ignoring\n»
Could not load XML target description; ignoring
208^error,msg=»Remote ‘g’ packet reply is too long (expected 312 bytes, got 328 bytes): 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0fdff7e0000000030eafc76100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000″
dRemote ‘g’ packet reply is too long (expected 312 bytes, got 328 bytes): 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0fdff7e0000000030eafc76100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Cannot compile GDB7.8 with Python support
I am trying to install GDB7.8 with Python support. From the source folder, I am running ./configure —with-python When I did tab-complete from —with- I did not see Python in the list. But when I ran configure with that flag, it did not baulk. When I run make, it complains that Python is not found.
$ which python python python2.7 python2.7-dbg-config python2 python2.7-dbg $ which python2.7 /usr/bin/python2.7
I compiled GDB without —with-python and things installed without error. I was under the impression that GDB7.8 had Python support without the need for special flags. But when I run:
$gdb python (gdb) run test.py
(gdb) pi printf.py Python scripting is not supported in this copy of GDB.
Do sh -x ./configure —with-python and keep the output. Look for how configure handles —with-* , and look at the Makefile to see how it checks for python2.7 . Could it need the python2.7 source ?
2 Answers 2
I spent quite a bit of time working on getting gdb (7.9) to work with Python (2.7). In the end everything worked rather well. However, there are a bunch of things that you have to get right. The key point is that the gdb configure script tries to compile a small C program that looks like this.
If this program won’t compile, then Python support won’t be built. For this program to compile, the Python.h include file must be found in /usr/include/python2.7 . This file will only exist if the python-devel package is installed. On my system (redhat), the command for installing this package is sudo yum install python-devel .
However, that’s not enough to get Python installed. Before the configure script tries to compile the C program, it gets various options from python-config.py . If these options aren’t correct, then the C program won’t compile. On my system, python-config.py returned the options below.
-lpthread -ldl -lutil -lm -lpython2.7 -Xlinker -export-dynamic
These options didn’t cause any problems in my environment. Other folks have had problems with the options returned from python-config.py and have made changes to python-config.py to resolve these problems. On my system the complete compile command was
gcc -o conftest -g -O2 -I/usr/include/python2.7 -I/usr/include/python2.7 \ conftest.c -ldl -lncurses -lz -lm -ldl -lpthread -ldl -lutil -lm \ -lpython2.7 -Xlinker -export-dynamic
This compile command completed without any errors as soon as I installed python-devel . Note you don’t have to manually enter the gcc command. I did run the gcc command several times to make sure everything was correct. Normally, the configure script will run the compiler for you. Also note that to get the overall gdb install process to complete, makeinfo also had to be installed. The command for installing makeinfo was sudo yum install texinfo .
Overall, the correct set of steps seems to be
- Install python-devel
- Install texinfo
- Download the gdb source and gunzip it and untar it.
- cd to the gdb-7.9 directory with the configure file.
./configure --prefix=/usr --with-python make sudo make install
It should be possible to get gdb to work with Python 3. The various gdb scripts and install programs mention Python 3 in many, many places. However, the correct procedure for installing gdb with Python 3 is unknown to me at this point.