Author: Gerhard Haering (gerhard@bigfoot.de)
0. Scope of this HOWTO
----------------------
This howto describes how to debug *native* win32 Python extensions with open
source tools. See Appendix A for how to do this with Cygwin's Python (which is
much simpler).
1. Prepare Python for development with gcc
------------------------------------------
- Install native Python: http://www.python.org/
- Install Cygwin (you'll need gcc, gdb, ...) http://www.cygwin.com/
- Get the dll2def package from
http://home.trouwweb.nl/Jerry/packages.html#LIB2DEF unzip and put the
executable somewhere in your path (it put such stuff in c:\opt\tools)
- Open the Cygwin shell and chdir to the libs directory of your Python
installation
- Create a python21.def file
$ dll2def c:/winnt/system32/python21.dll >python21.def
(Adjust the path to the python dll if you use Windows 9x or don't have your
OS installed in c:/winnt)
- Create a libpython21.a file
$ dlltool --dllname python21.dll --def python21.def --output-lib \
libpython21.a
- Create a fake debugging environment for distutils
(the debugging files download from python.org is of no use, because Cygwin
gdb cannot understand the debugger symbol format used by Visual C++,
which is used by the Python crew to build the native win32 Python).
$ cp libpython21.a libpython21_d.a
- Steps to make your life easier:
-- Put the directory of the native Python in your PATH.
-- Copy the native python.exe to something like ntpython.exe to avoid
confusion with Cygwin's Python
2. Write the extension module
-----------------------------
Here's a buggy extension module:
/* BEGIN FILE crash.c ***********************************************/
#include "Python.h"
PyObject* crash()
{
char* s = "test!";
s[0] = 'T'; /* This is asking for trouble :-) */
Py_INCREF(Py_None);
return Py_None;
}
static PyMethodDef crashMethods[] = {
{"crash", (PyCFunction)crash, NULL, NULL},
{NULL, NULL}
};
DL_EXPORT(void) initcrash(void)
{
PyObject *m;
m = Py_InitModule("crash", crashMethods);
}
/* END FILE crash.c ************************************************/
And the setup.py file to build it:
###### BEGIN setup.py ###############################################
import sys
from distutils.core import setup
from distutils.extension import Extension
setup (
name = "crash",
ext_modules = [Extension(
name="crash",
sources = [ "crash.c" ]
)],
)
###### END setup.py --###############################################
3. Build and debug the extension module
---------------------------------------
$ ntpython setup.py build --compiler=mingw32 --debug
$ cd build/lib.win32-2.1/
$ mv crash_d.pyd crash.pyd # workaround for distutils
$ gdb ntpython
- Run the application in gdb
- Then:
Python 2.1.1 (#20, Jul 20 2001, 01:19:29) [MSC 32 bit (Intel)] on win32
Type "copyright", "credits" or "license" for more information.
>>> import crash
>>> crash.crash()
- Gdb will point out where the segmentation fault happened
APPENDIX A
----------
How to debug Python extensions on Cygwin.
- You'll need Cygwin installed (the full development environment, including
gcc, gdb, python, ...)
- write a setup.py file (see above)
- compile the extension with debugging options:
$ python setup.py build --debug
- $ cd build/lib.cygwin_nt-5.0-1.3.1-i686-2.1
- $ gdb python
- Run the application
- "import crash"
- "crash.crash()"
APPENDIX B
----------
Unresolved issues:
- How to set breakpoints in extension modules