Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gdb pretty printing with direct function calls

I am trying to use the pretty printing facilities of GDB to show a custom C++ matrix class.

The class is quite standard you can find anywhere. It is a template parameterized by the type, and can be accessed with C-type notation like mat[i][j]. This first implicitly returns another template "Slice" class representing a row or a column, which can again accessed by the [] operator to extract the data. The class itself is using a plain C array for storage, but it is implementing some tricks on it, like an option of pre-allocating a larger matrix, enabling non-zero starts, using stride etc. The class does not have a native printing interface, and I cannot modify it, or link with my own code easily.

The custom features make it painful to reproduce the direct data access code in Python. But is that necessary? In general: why should pretty printing reproduce the logic of accessing the data? Cannot I just use C++ calls and use the [] operators to print the i,j-th element? The fact that the Slice class is a temporary in GDB during such a request further complicates this.

I am also quite a beginner with python and GDB scripting. I have tried to hack the examples to replace data access with gdb.execute calls, but I have no idea how to access the object name from the to_string function, so I can use something like gdb.execute(??? + '[]+str(i)+']', False, True).

I wonder what is the most effective way of doing this.

like image 953
takbal Avatar asked Dec 20 '11 16:12

takbal


People also ask

How do I enable pretty print in GDB?

in a directory of your choice (i.e. $(HOME)/distribs/gdb_printers). You will get 'python' subdirectory in the checkout directory. This makes pretty printing usable via command-line interface of gdb ( >(gdb) p my_std_string ).

What does print do in GDB?

The usual way to examine data in your program is with the print command (abbreviated p ), or its synonym inspect . It evaluates and prints the value of an expression of the language your program is written in (see section Using GDB with Different Languages). expr is an expression (in the source language).

What does incomplete type mean in GDB?

It means that the type of that variable has been incompletely specified. For example: struct hatstand; struct hatstand *foo; GDB knows that foo is a pointer to a hatstand structure, but the members of that structure haven't been defined. Hence, "incomplete type".


2 Answers

Cannot I just use C++ calls and use the [] operators to print the i,j-th element?

You can call from the pretty-printer into the inferior (being debugged) process using gdb.parse_and_eval (docs), but this has several disadvantages:

  • you need a "live" process to do this (in other words, your pretty printer will not work when you are debugging a core dump)
  • if the inferior is corrupt in some way, calling functions in it will likely corrupt it even more
  • if the inferior is multi-threaded, and the pretty printer calls into a function that may require a lock (e.g. malloc), then you are very likely to cause the pretty printer to deadlock, and there would not be any way to recover from such deadlock.
like image 166
Employed Russian Avatar answered Oct 18 '22 22:10

Employed Russian


This is not python scripting, but simple command sequences for GDB extension. I am defining a new command called print_matrix.

(gdb) define print_matrix
Type commands for definition of "print_matrix".
End with a line saying just "end".
>set $s_arr = $arg0
>set $i=0
>while($i < $arg1)
 >p (int [][$arg2]) *($s_arr + $i)
 >set $i = $i + 1
 >end
>end
(gdb) print_matrix arr 10 10
$90 = {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}}
$91 = {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}
$92 = {{2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}
$93 = {{3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}
$94 = {{4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}
$95 = {{5, 6, 7, 8, 9, 10, 11, 12, 13, 14}}
$96 = {{6, 7, 8, 9, 10, 11, 12, 13, 14, 15}}
$97 = {{7, 8, 9, 10, 11, 12, 13, 14, 15, 16}}
$98 = {{8, 9, 10, 11, 12, 13, 14, 15, 16, 17}}
$99 = {{9, 10, 11, 12, 13, 14, 15, 16, 17, 18}}
(gdb)

You could also save these commands as a script and use -x option

gdb -x <commands file name> binary.out
like image 1
Kamath Avatar answered Oct 19 '22 00:10

Kamath