Saturday, December 10, 2011

Python commands added to gdb

I have managed to define several useful commands for gdb using python.  These commands work with both gdb and ddd.  The basic commands are text commands, but I did manage to create a gtk window for defining variables and watches.

Defining variables

The first command is "dv" which stands for define variable.  The basic idea is to associate a name with an address which can be either a scalar or an array.  Here is the command usage

    dv name address format size count


The name can be any name.  It is treated as a string internally in the python code and can be nearly any string other than the empty string.

The address can be a number, a register or an expression.  The original idea was to support hexadecimal addresses, but you can use "$rsp" and define a variable as the current stack pointer.  You can also use "$rsp+8" and define a variable offset by 8 bytes into the stack.  The software will enclose the address in parentheses to allow using expressions.

The format is a single letter defining the type of output requested.  "d" means decimal output, "x" means hexadecimal, "c" means character, "f" means floating point, and "s" means a C string.  There is also a "v" type for arrays of strings like argv in C main programs.

The size is the number of bytes for the variable or for each array element.  This number should be 1, 2, 4 or 8.

Count is the number of array elements.

So to define an array named "x" of 10 floats, you could use

    dv x 0x602010 f 4 10

This is unfortunately too many values on one line, but as long as X Windows is available a gtk window will pop up allowing a convenient method for defing varaibles:


The variable definition window uses first and last instead of count to satisfy the needs for watching variables.  For those needs it might be convenient to start at an index other than 0.

Printing variables

The command to print a variable is "pv".  This cam be used in 3 ways:

    pv name
    pv name count
    pv first last

When no numbers are given the entire array is printed as defined.  If one number is given, this specifies how many numbers are printed starting at index 0.  If two numbers are given, they specify the first and last index to print (inclusively).  Below is a sample showing the effect of "pv":

    (gdb) pv stack
    stack[0-5]:    0 40044b 7fffffffe976 400895 f0b2ff 400850


Watching variables

The command to watch a variable is "wv".  A watched variable is printed for each step of the execution of the debugged program.  The usage is like that for printing:

    wv name
    wv name count
    wv first last

Below is a sample of gdb output showing 2 watched variables:

    (gdb)  n
    p[0-3]:       1     2.5     7.5   9.125
    stack[0-5]:    3 40044b 7fffffffe976 602030 602010 602060
    76                inc     rcx
 
Listing variables

The command to list variables is "lv".  Below is the output:

  (gdb) lv
  Name             Address   Format           Type  Bytes  Count
  p             (0x602030)     %7g          double    8      4
  stack               $rsp    %4lx   unsigned long    8      6
  st                  $rsp    %4lx   unsigned long    8      6

Using ddd

The ddd debugger runs gdb internally and this is the same gdb, so these commands also work in the ddd console window.  This makes a nice environment, since ddd shows the source code in the source window which is much simpler to follow that showing each line before it is executed.

For a little extra thrill it is possible to show watched variables in the ddd data window.  Unfortunately this seems to be impossible to control completely with python.  The variable definition window will be available for defining variables.  Then you can enter a command like the one blow in the ddd console window:

    graph display `pv stack 0 7`

Please note that there are back quotes surrounding the "pv" portion of the previous command.   This command allows watching data in the data window:


No comments: