Recently I found the need to debug a Cython module that was computing derivatives generated from SymPy. There were too many variables to use printf statements effectively and I wanted a quick way just to watch the changes in variables. The purpose of this post is to share a quick and dirty method for debugging Cython modules.
Take the example code below to create a module enorm which exposes a function to calculate the Euclidean norm of a one-dimensional NumPy vector.
To step through enorm in enorm.pyx, first produce enorm.c:
Now open enorm.c and find the first line of enorm:
Now add a breakpoint interrupt above the line of interest. For GCC this is:
If inspecting control flow it can be helpful at this point to also turn off optimisations e.g. for GCC add the extra_compile_args=['-O0'] argument to Extension in setup.py. Next, build the extension module with debugging information.
On Windows you will have to rename the extension module from enorm_d.pyd to enorm.pyd. Now, just run python main.py in GDB/Visual Studio/OllyDbg to begin step through the function.
In GDB for example:
To more easily step through the original source use layout src (Beej's Quick Guide to GDB).