Debugging Python Extension Written in C with Eclipse
I tested M2Crypto with Python 2.6 prereleases, and there was a single test that was failing in test_smime.py: test_verifyBad failed because verify raised SMIME_Error when it was expected to raise PKCS7_Error. This code has worked without changes with all prior Python versions.
Looking at just the Python code showed no clues as to what was going wrong.
It looked like I would need to refresh my gdb debugging skills, but luckily there are some pretty good instructions on how to debug Python extensions with gdb. The added wrinkle with M2Crypto is that you need to compile OpenSSL in debug mode as well.
Openssl:
./config --prefix=/path/to/debug --openssldir=/path/to/debug/openssl -d make make install
M2Crypto:
/path/to/debug/python setup.py build -g build_ext --openssl=/path/to/debug -I/path/to/debug/include/openssl -g
I quickly grew tired of the limitations of the command line interface, so I started wondering how I could use Eclipse. The following assume you have already installed Python setuptools (a prerequisite to running the M2Crypto unit tests like we are doing here), and that you have Eclipse 3.3 with CDT plugin. Other versions of Eclipse may work, but are untested.
Open Debug Dialog, put in /path/to/debug/python as the C++ application on the Main tab. In Arguments write setup.py test --test-suite=tests.test_smime, and put in the M2Crypto workspace directory where you just built the debug M2Crypto. In Source tab add both OpenSSL and Python source trees you just built. I battled for a while with the Project on the Main tab, since Eclipse seems to insist on a C/C++ project. I eventually resolved to create a dummy C project: in C/C++ perspective create new C executable (Empty Project) and use that as a placeholder (it isn’t actually used for anything relevant).
Then just hit debug, and watch it stop at main (using the exact settings as above). Navigate to _m2crypto_wrap.c, and place a breakpoint on line 5946 (if (!PKCS7_verify(pkcs7, (STACK_OF(X509) *)stack, store, data, bio, flags)) {) and hit continue. In a short while the debugger drops you in that function and you can investigate variable values etc.
This probably isn’t the cleanest way to do this, but it works, and since I need to resort to debugging C/C++ very rarely these days, I can live with the procedure.
Funnily enough I actually solved the bug by not using Eclipse or gdb at all. I happened to notice that the function that was misbehaving was returning Py_None, when in all other error cases (I checked) the C code returns NULL when raising Python exception. Somewhat subtle difference in how 2.6 differs from prior releases.
I also ended up finding and fixing another issue: X509_Store.load_info was failing silently if it couldn’t find the file to load. Now it returns the return value from the wrapped OpenSSL function, or in case of error it raises X509Error exception.



Joachim Dahl:
Thank you for posting this guide – I have been trying to get it working
for my Python extension module, but couldn’t quite figure it out.
Configuring Eclipse as a development tool for writing Python extension
modules would be tremendously useful. If you ever have time, I am
sure that many Python programmers will be very grateful for a step-by-step
guide of how to set this up for a very simple extension module (for example
the ‘noddy’ project in the Python documentation).
Joachim
November 1, 2008, 3:05 pm