Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to debug C extensions for Python on Windows

I have a problem with a segfault in pyodbc and would like to debug it in Windows XP x86. However, the information online seems primarily Linux-centric. What is the best way to go about this?

like image 728
pyrospade Avatar asked Jul 29 '12 22:07

pyrospade


People also ask

How do you debug C in Python?

In order to debug the C/C++ code of an extension, you need to use the native debugger, GDB or LLDB, and debug the interpreter process that loads your script and runs the application. For that, you can either attach to a running Python process or debug a properly configured Custom Build Application.

How do I debug Python in Windows?

With a stand-alone Python file open, right-click in the editor, select Start with Debugging, and Visual Studio launches the script with the global default environment (see Python environments) and no arguments. But from then on, you have full debugging support.

Can you use GDB with Python?

Pretty much anything that can be done at the GDB command line can be done with a breakpoint from Python. You can attach commands to a breakpoint, make it conditional, ignore a certain number of hits, make the breakpoint specific to a thread or process, and all of the things you can do from the command line.

Can you run Python in debug mode?

Basic debugging If you're only interested in debugging a Python script, the simplest way is to select the down-arrow next to the run button on the editor and select Debug Python File in Terminal.


2 Answers

So I was able to successfully resolve my issue by using Visual Studio 2008. I loosely followed the steps listed here -

http://www.velocityreviews.com/forums/t329214-debugging-python-extensions.html

And some tips on workarounds here -

Compiling python modules whith DEBUG defined on MSVC

Here is my version of the steps for anyone else who may encounter this problem.

  1. In case you haven't already, be sure to setup the Python header and libs directories in VS

    a. Go to Tools > Options > Projects and Solutions > VC++ Directories. Be sure to add your include and libs path to the Include and Library files' path, respectively. (e.g. C:\Python27\include, C:\Python27\libs)

  2. Go to your Python include folder (once again, e.g. C:\Python27\include) and edit pyconfig.h. Comment out the line # define Py_DEBUG and save. Go to your libs folder (e.g. C:\Python27\libs) and make a copy of python27.lib. Name the copy python27_d.lib.

  3. Create a new project. Choose Win32 Project and name it the module name (in my case pyodbc. Click Next then choose DLL for Application type and check Empty Project.

  4. In the Solution Explorer, right-click on Header Files and choose Add > Existing Item. Select all of the header files that you need. Do the same for Source Files.

  5. Go to Project > Properties, then under Configuration Properties -

    a. General - ensure that you are using the correct Character Set. For me it was Use Multi-Byte Character Set. Python 3 probably needs Use Unicode Character Set.

    b. Debugging - enter the path to Python in the Command field. (e.g. C:\Python27\python.exe). Then set Attach to Yes.

    c. Linker > General - change the Output File to end in .pyd instead of .dll.

  6. Ensure that your configuration is set to Debug. Go to Build > Build Solution.

  7. Open a cmd and cd into the directory where your pyd file was compiled. Start python from the cmd window. To attach debugger on this running python process, go back to Visual Studio and click the green play button to start debugging. You can also use Debugging -> Attach to Process... Now go back to Python and import your module. Play, test, and try to break it!

like image 190
pyrospade Avatar answered Oct 05 '22 23:10

pyrospade


Debugging workflow with WinDbg

This workflow will create debugging information for a Release build, so you don't have to mess with the original include and library files of Python.

  1. Download and install Debugging Tools for Windows

  2. Get the symbol files for your Python version and extract them. For Python 2.7.3 this would be http://www.python.org/ftp/python/2.7.3/python-2.7.3-pdb.zip.

  3. Modify setup.py to generate debugging files. You have to add '/Zi' to extra_compile_args and '/DEBUG' to extra_link_args. Example:

    ext_modules  = [Extension('pyuv', sources=['src/pyuv.c'],
                              extra_compile_args=['/Zi'],
                              extra_link_args=['/DEBUG'])
                    ]
    
  4. Build the extension as always (python setup.py ...).

  5. Start WinDbg and specify the Symbol Search Path (Ctrl + S).

    C:\Path\To\Extension_pdb
    C:\Path\To\Extracted\python-2.7.3-pdb
    srv*;SRV*c:\tmp*http://msdl.microsoft.com/download/symbols
    

    The last line will download and cache required symbols for Windows modules.

  6. Start the Python executable (Ctrl + E). You can directly execute a script or run in interactive mode.

  7. Skip the initial breakpoint with "Go" (F5).

  8. If there is a Segmentation fault the execution will break and you will see something like Access violation - code c0000005 (first chance) in the WinDbg console.

  9. You can get detailed exception information by typing !analyze -v in the WinDbg console and the current stack trace with kb. Here is an example of such an output.

You should be able to combine this approach with pyrospade's answer to debug with Visual Studio if you omit his second step and build the project with Release configuration.

A further tutorial for WinDbg could be found here.

like image 43
schlamar Avatar answered Oct 06 '22 01:10

schlamar