WatchPoint

Image link

How to Write User-Defined GDB Commands in Python?

Last time we looked at user-defined commands in the GDB command-line. In this GDB tutorial, we look at writing our user-defined functions in Python.

The advantage of creating user-defined commands in Python is that you can automate a more complicated task or something that you might want to check into source control and share with your teammates. Using Python is more robust too; it’s more extensible and although a bit more work, it gives you better results in multiple ways.

 

Boilerplate to get you started

Let’s start with the initial boilerplate for our Python code. We write it in a file; bugreport.py.

$ vim bugreport.py

We create a class which we call BugReport, and we inherit it from the gdb.command class.

class BugReport (gdb.Command):

We give it a docstring, so you get an inbuilt type of help in the GDB command-line.

"""Collect required info for a bug report"""

We need to give it a constructor. We call a superclass constructor; we give it a name and a command. There are different command-classes, for example, maintenance commands, obscure commands and various others. We go with COMMAND_USER.

def__init__(self):
  super(BugReport, self).__init__("bugreport", gdb.COMMAND_USER)

We make a function that we call invoke, which is where the magic happens. This function takes an arg, which is just a string that contains all the arguments. It also has a boolean from_tty, so we know whether it ran from a script or the command line. The body of the function is not terribly interesting for this GDB tutorial, let’s just have it get a backtrace of all threads and the kernel version.

def invoke(self, arg, from_tty):
  gdb.execute(“thread apply all backtrace full”)
  import os
  os.system(“uname -a”)

Finally, we need to instantiate one of these classes; otherwise, nothing is going to happen.

BugReport()

Now from the GDB command-line, you can source bugreport.py and hey presto, you have a new command called bugreport.

Watch my video for this GDB tutorial to see how these few lines of Python code create a simple user-defined command for a bug report and with help text too.

Cool!

 

New call-to-action

Write bug report output to a file

You may find it helpful if the bug report output went straight into a file, so let’s do that now.

We could do a simple gdb.execute("set logging file"), but we are writing in Python, why not do this a little bit more cleanly?

def invoke(self, arg, from_tty):
  pagination = gdb.parameter("pagination")
  if pagination: gdb.execute("set pagination off")
  f = open("/tmp/bugreport.txt", "w")
  f.write(gdb.execute("thread apply all backtrace full", to_string=True))
  f.close()
  import os
  os.system("uname -a >> /tmp/bugreport.txt")
  if pagination: gdb.execute("set pagination on")

Note: Make sure you open the file for writing; adding “w”. Also, use to_string=True again to write the output to a string, not to the console.

Watch the video to see how this code for file logging works.

 

Final Python code

To help you get started quickly, create a file, for example, mybugreport.py.

$ vim mybugreport.py

Copy and paste the final Python code.

import os

class BugReport (gdb.Command):
  """Collect required info for a bug report"""

def__init__(self):
  super(BugReport, self).__init__("bugreport", gdb.COMMAND_USER)

def invoke(self, arg, from_tty):
  pagination = gdb.parameter("pagination")
  if pagination: gdb.execute("set pagination off")
  f = open("/tmp/bugreport.txt", "w")
  f.write(gdb.execute("thread apply all backtrace full", to_string=True))
  f.close()
  os.system("uname -a >> /tmp/bugreport.txt")
  if pagination: gdb.execute("set pagination on")

 BugReport()

Done!

I hope you found this GDB tutorial a useful introduction to user-defined commands in GDB, and that it motivates you to start creating your user-defined commands.

In my next GDB tutorial, we’ll look at how to use the hook command in user-defined commands; both in the GDB command-line and in Python.

Don’t forget to watch, subscribe, like, and share my video.

Good luck debugging.

 

GDB Training
Master GDB and save time debugging complex codebases
Learn more »

Don’t miss my next C++ debugging tutorial: sign up to my WatchPoint mailing list below.
Get tutorials straight to your inbox

Become a GDB Power User. Get Greg’s debugging tips directly in your inbox every 2 weeks.

Want GDB pro tips directly in your inbox?

Share this tutorial