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.
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 ).
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).
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".
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:
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.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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With