简体   繁体   English

如何在Windows上调试Python的C扩展

[英]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. 我在pyodbc中遇到段错误问题 ,想在Windows XP x86中调试它。 However, the information online seems primarily Linux-centric. 但是,在线信息似乎主要以Linux为中心。 What is the best way to go about this? 最好的方法是什么?

So I was able to successfully resolve my issue by using Visual Studio 2008. I loosely followed the steps listed here - 所以我能够通过使用Visual Studio 2008成功解决我的问题。我松散地按照这里列出的步骤 -

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

And some tips on workarounds here - 这里有一些关于解决方法的提示 -

Compiling python modules whith DEBUG defined on MSVC 编译在MSVC上定义的DEBUG的python模块

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 如果您还没有,请确保在VS中设置Python头和libs目录

    a. 一个。 Go to Tools > Options > Projects and Solutions > VC++ Directories . 转到工具>选项>项目和解决方案> VC ++目录 Be sure to add your include and libs path to the Include and Library files' path, respectively. 请务必分别将include和libs路径添加到Include和Library文件的路径中。 (eg C:\\Python27\\include , C:\\Python27\\libs ) (例如C:\\Python27\\includeC:\\Python27\\libs

  2. Go to your Python include folder (once again, eg C:\\Python27\\include ) and edit pyconfig.h . 转到Python include文件夹(再次,例如C:\\Python27\\include )并编辑pyconfig.h Comment out the line # define Py_DEBUG and save. 注释掉# define Py_DEBUG并保存。 Go to your libs folder (eg C:\\Python27\\libs ) and make a copy of python27.lib . 转到您的libs文件夹(如C:\\Python27\\libs ),并副本python27.lib Name the copy python27_d.lib . 将副本命名为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 . 选择Win32 Project并将其命名为模块名称(在我的例子中为pyodbc 。单击Next,然后选择DLL for Application type并选中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 . 对我来说,它是Use Multi-Byte Character Set Python 3 probably needs Use Unicode Character Set . Python 3可能需要Use Unicode Character Set

    b. Debugging - enter the path to Python in the Command field. 调试 - 在命令字段中输入Python的路径。 (eg C:\\Python27\\python.exe ). (例如C:\\Python27\\python.exe )。 Then set Attach to Yes . 然后将Attach设置为Yes

    c. C。 Linker > General - change the Output File to end in .pyd instead of .dll . 链接器>常规 - 将输出文件更改为以.pyd而不是.dll结尾。

  6. Ensure that your configuration is set to Debug. 确保您的配置设置为Debug。 Go to Build > Build Solution . 转到Build> Build Solution

  7. Open a cmd and cd into the directory where your pyd file was compiled. 打开cmd并cd到编译pyd文件的目录中。 Start python from the cmd window. 从cmd窗口启动python。 To attach debugger on this running python process, go back to Visual Studio and click the green play button to start debugging. 要在此运行的python进程上附加调试器,请返回Visual Studio并单击绿色播放按钮以开始调试。 You can also use Debugging -> Attach to Process... Now go back to Python and import your module. 您还可以使用Debugging - > Attach to Process ...现在返回Python并导入您的模块。 Play, test, and try to break it! 玩,测试,并尝试打破它!

Debugging workflow with WinDbg 使用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. 此工作流将为Release版本创建调试信息,因此您不必弄乱Python的原始包含和库文件。

  1. Download and install Debugging Tools for Windows 下载并安装Windows调试工具

  2. Get the symbol files for your Python version and extract them. 获取Python版本的符号文件并将其解压缩。 For Python 2.7.3 this would be http://www.python.org/ftp/python/2.7.3/python-2.7.3-pdb.zip . 对于Python 2.7.3,这将是http://www.python.org/ftp/python/2.7.3/python-2.7.3-pdb.zip

  3. Modify setup.py to generate debugging files. 修改setup.py以生成调试文件。 You have to add '/Zi' to extra_compile_args and '/DEBUG' to extra_link_args . 你必须将'/Zi'添加到extra_compile_args并将'/DEBUG'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 ... ). 一如既往地构建扩展( python setup.py ... )。

  5. Start WinDbg and specify the Symbol Search Path (Ctrl + S). 启动WinDbg并指定符号搜索路径(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. 最后一行将下载并缓存Windows模块所需的符号。

  6. Start the Python executable (Ctrl + E). 启动Python可执行文件(Ctrl + E)。 You can directly execute a script or run in interactive mode. 您可以直接执行脚本或以交互模式运行。

  7. Skip the initial breakpoint with "Go" (F5). 使用“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. 如果存在分段错误,则执行将中断,您将在WinDbg控制台中看到类似访问冲突的内容 - 代码c0000005(第一次机会)

  9. You can get detailed exception information by typing !analyze -v in the WinDbg console and the current stack trace with kb . 您可以通过在WinDbg控制台中键入!analyze -v以及使用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. 如果省略第二步并使用Release配置构建项目,您应该能够将此方法与pyrospade用Visual Studio调试的答案相结合。

A further tutorial for WinDbg could be found here . 可以在这里找到WinDbg的进一步教程。

Segfaults are especially mysterious, as there is no way to trap for them from your Python code, or even to get much stacktrace information on the C side of things. Segfaults特别神秘,因为没有办法从Python代码中捕获它们,甚至无法在C端获取大量的堆栈跟踪信息。 One thing that can give you at least a little more info is to use the Google breakpad C library to report a C stack trace when the segfault occurs. 至少可以为您提供更多信息的一件事是使用Google breakpad C库在发生段错误时报告C堆栈跟踪。

You may want to try David Malcolm's tool CPyChecker which statically analyses C extensions for memory leaks and other bugs. 您可能想尝试使用David Malcolm的工具CPyChecker ,它可以静态分析内存泄漏和其他错误的C扩展。 The tool is documented here . 该工具记录在此处

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM