NEW RESEARCH REPORT: Overcoming the limitations of coding agents in complex software systems

WatchPoint

How to use the GDB command hook?

In this GDB Tutorial

In the last two GDB tutorials, we looked at user-defined functions, both in the GDB command-line and in Python.

In this GDB article, we look at defining hooks, a handy variant of a user-defined GDB command. Again, we’ll do both in the command-line and Python.

Let’s start your program the usual way.

Hooks in the GDB command-line

In the command-line, we specify a user-defined command just like before, but only this time we start it with hook- (hook dash).




Whatever comes after the dash is the command that we hook. In the example above, every time we do a next, it prints “HERE COMES A NEXT” before the command runs.

GDB session defining hook-next, which prints HERE COMES A NEXT before each next command

We can do a post-hook with a hookpost to do something after the command happens.




GDB session adding hookpost-next, so each next also prints DONE THE NEXT

There’s a pseudo command that we can hook called stop. That’s a very useful command because every time the inferior stops we go back to the GDB-prompt, and we can run something.

For example, let’s go to a backtrace or bt each time we step into the program.




GDB hook-stop printing a backtrace each time the program stops

The advantage of using GDB command hook in the command-line is that you can do them very quick and dirty. And it is pretty easy to remember syntax too, which is nice. But if you want to do something a bit more meaningful and want to check it into source control, you probably want to do that in Python.

Let’s see how we do that.

UDB Time Travel Debugger
Find and fix bugs in minutes – save time on debugging
Learn more »

GDB hooks in Python

The equivalent of stop in a way is that we can hook the prompt. Again, it’s a simple syntax. The only thing we need is a function.

$ vim stop
$ vim stop
$ vim stop
def foo():
   print("BEFORE THE PROMPT")
gdb.events.before_prompt.connect(foo)
def foo():
   print("BEFORE THE PROMPT")
gdb.events.before_prompt.connect(foo)
def foo():
   print("BEFORE THE PROMPT")
gdb.events.before_prompt.connect(foo)

Note that the syntax is connect, not hook.

If we now source stop.py, then it prints the text “BEFORE THE PROMPT” as we do expect it before every prompt.

GDB sourcing a Python script that prints BEFORE THE PROMPT before every prompt

There are a whole bunch of other events though that we can hook to.

For example, let’s do the equivalent of the stop we were just doing in the command-line, but this time in Python.

Unlike the before_prompt command, other commands expect an event-argument which you can look up to tell why the program stopped.

def stop(ev):
  print("stopped, ev={}.format(ev.__dict__))
gdb.events.stop.connect(stop)
def stop(ev):
  print("stopped, ev={}.format(ev.__dict__))
gdb.events.stop.connect(stop)
def stop(ev):
  print("stopped, ev={}.format(ev.__dict__))
gdb.events.stop.connect(stop)

Notice that it will reconnect every time we run this; you can connect functions multiple times.

(gdb) source stop
(gdb) source stop
(gdb) source stop

We hit an event. It is an inferior thread which has a breakpoint associated with it. So, we can see this breakpoint number two.

GDB Python stop hook reporting a breakpoint stop, with the event details highlighted

If we disable breakpoints and continue to the end of the program, then we reach a different kind of stop. We hit an abort, and we can see that we were stopped due to a SIGABRT, abort.

GDB Python stop hook reporting a SIGABRT stop, with the event details highlighted

There are many events that a program can stop on. You can stop at an exited event, just when the program exits. You can have a cont event, which you can hook before the program starts. You can have memory_change or register_change events or even breakpoint events such as breakpoint_created, breakpoint_modified or breakpoint_deleted.

Where to go for more information?

You can look up an extensive list of events that are available in GDB in the info page in the usual way. How to do that again?

$ info
$ info
$ info

Though, the trouble with these info pages is that you need to know what to look for.

GDB info manual open in a terminal, with a search for events in python typed in

Let’s search for “events in python”. This gives you a whole chapter of all the things we just went through in this GDB tutorial, including all the different events; pretty extensive, pretty powerful.

GDB info page describing the Python events.exited and events.stop events

I hope you do recognise how you might do a lot of cool stuff with that.

That’s hooks!

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

Good luck debugging.

Don’t miss my next GDB tutorial: sign up to the gdbWatchPoint mailing list now.

Want debugging tips directly in your inbox?

Sure, why not?

Become a C/C++ Debugging Ninja.

Get debugging tutorials straight to your inbox

Become a C/C++ Debugging Ninja.

Get debugging tutorials straight to your inbox

Become a C/C++ Debugging Ninja.

Get debugging tutorials straight to your inbox