Inspecting multidimensional C/C++ matrices by putting NumPy into GDB

Developing numerical programs in C, C++ or Fortran or even just fast C extensions like in my previous post, the chance of introducing a bug increases as complexity increases.

One of my favorite types of bugs are caused when working with multi-dimensional arrays. While multi-dimensional arrays are relatively painless in Python+NumPy, doing index and pointer magic in C/C++ on large linear arrays quickly becomes confusing and cost me many days of debugging on my thesis work. Luckily, we can use NumPy within GDB to visualize our multidimensional data thanks to the information in this codeproject.com post!

Installation

Grab the gdb_numpy.py script from the original codeproject.com post.

Python scripts must be placed in ${GDB_DATA_DIRECTORY}/python. To find out the current GDB data directory1 you can do the following:

(gdb) show data-directory
GDB's data directory is "/usr/share/gdb".  

That's all and we should be ready to go!

Demo

Here's a simple C program to fill a 4x3 matrix:

void main(int argc, char **argv) {  
    const int nrow = 4;
    const int ncol = 3;
    double x[nrow * ncol];
    for(int i = 0; i < nrow; i++) {
        for(int j = 0; j < ncol; j++) {
            x[i * ncol + j]  = i * j;
        }
    }
    // BREAK here
}

We can compile this code with debug symbols using gcc -g -c sample.c -o sample and run the sample in GDB with gcc ./sample

From GDB, we can set a breakpoint after filling the array and then use our freshly installed gdb_numpy magic:

> py import gdb_numpy
> py x = gdb_numpy.to_array("(double *)x", shape=(4 * 3,)).reshape(4, 3)
> py print x
[[0 0 0]
 [0 1 2]
 [0 2 4]
 [0 3 6]]

And simple as that, we have a beautiful pretty-printed matrix in our debugging session! We can go on to use matplotlib to plot the data:

> py import matplotlib.pyplot as plt
> py plt.imshow(x)
> py plt.show()

See also

Notes

  1. Check out the GDB Data Files Documentation on how to change the Data Directory, etc.