Wednesday, October 12, 2011

GDB: Quickly attach to the only instance of a program

Wouldn't it be nice if, instead running shell pidof foo and pasting the resulting PID into an attach command, you could just run one command to attach to your inferior? Sort of like this:
(gdb) qattach crawl
[Thread debugging using libthread_db enabled]
0xb7d1588e in __open_nocancel () at ../sysdeps/unix/syscall-template.S:82
82      ../sysdeps/unix/syscall-template.S: No such file or directory.
        in ../sysdeps/unix/syscall-template.S
Well, now you can! Just arrange for GDB to run the following Python code first, which (gdb) Python Commands and (gdb) Startup will show you how to do:

# Copyright (c) 2011 Samuel Bronson
# This software is made available under the same license as the
# "expat" XML library for C, or the "do whatever you want" license, at
# your option.

# Note: The subprocess.check_output() function is new in Python 2.7.

class QAttach(gdb.Command):
    """Quickly attach to the only instance of a program."""

    def __init__(self):
        super(QAttach, self).__init__("qattach", gdb.COMMAND_RUNNING, gdb.COMPLETE_FILENAME)

    def invoke(self, arg, from_tty):
        import subprocess

        if not arg:
            print "qattach: Missing target name!"

        pids = subprocess.check_output(['pidof', arg]).split()

        if len(pids) != 1:
            print subprocess.check_output(['ps'] + pids)
            gdb.execute("attach "+pids[0])