Debugging Cython code on Windows x64

Debugging of Cython-Code on 64-bit Windows is not really straightforward. I am using spyderlib for development, and while it has good support for the pdb, it lacks any support for Cython debugging.

Additionally, even compiling x64 Cython code on Windows is not straightforward, since the Microsoft compiler should be used (as outlined in this official article). The MinGW-x64 compiler seems not to be the first choice in this scenario.

So once you set up your build tools to get the Cython builds running, of course you might at some point need to get some debug information. The usual Cython debugging guides only give instructions for using gdb as debugger, but this should (can?) not be used with MSVC compiled binaries. For luck, Microsoft also provides you with some great tools to get from command line to their debugging solutions.

Building

First, it is necessary to call the compiler with the debug options (tell it to supply the links from compiled code to sourcecode, as well as turn off code optimizations). The compiler options are covered in this excellent response on stackoverflow. They can be broken down to the following instructions:

  • for the compiler, use the -Zi and /Od command line options for debugging, and -Zi and /O2 for release versions,
  • for the linker, in both cases use the -debug option.

The -Zi option turns on the generation of "binary-sourcecode" links for the debugger (by default exported to a .pdb file in the binary directory). This does not "slow down" your code. The /Od option tells the compiler to not use code optimizations, so that you can better follow the control flow in debug mode (/O2 "[...] optimizes code for maximum speed" (MSDN) for your release binary).

The -debug option tells the linker to collect the "binary-sourcecode" information from several object file into one .pdb file, which usually is what you want.

Example

If you decided to use disttools to build your Cython project, adding these command line parameters is as simple as defining your Extension as

1
2
3
4
Extension("your_extension", sources=["your_extension.pyx"],
                extra_compile_args=["-Zi", "/Od"], # for release version change /Od compile arg
                                                   # to /O2 (optimization for maximum speed)
                extra_link_args=["-debug"]) # leave this enabled for release! :)

Invoking the debugger

Now you can build the project with all needed information, but since it is not a standard VS project how can you start debugging?

Microsoft provides you with the function

1
void WINAPI DebugBreak(void);

which is just what you need for this purpose (MSDN). In your Cython file, simply link against the Windows.h header-file, and call DebugBreak() at the place where you want to start debugging. Once the code is executed, a window will pop up, asking whether you want to start debugging python, and offering you to use an instance of any installed Visual Studio. If you select one, you can start debugging the Cython code as if you would've written the code in VS (including setting Breakpoint with a simple click, running to cursor, etc.).

Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# Include Windows.h
# for debugging, setting breakpoints:
cdef extern from "<Windows.h>":
    void DebugBreak()

# ...

# Start debugging:
def your_cython_function() :
    """A function to step into Cython debugging.

    """
    # You can set a breakpoint by calling
    DebugBreak()
    # ...

Comments

Tags

Archive

Archive