Adventures in Debugging C/XS

Tags:

Originally posted as: Adventures in Debugging C/XS on blogs.perl.org.

... or Why A Good Perl Developer Is Not Automatically A Good C Developer, the Story of C Programming via Google.

My tests failed, but only sometimes. I was building an XS module to interface with a C wrapper around a C++ library (wrapper unnecessary? probably). make test was failing with exit code 11. Some quick searching revealed that I had an intermittent segfault. Calling a function as_xml would fail with a SEGV in strlen(). This only happened in perl after as_xml when perl was making a SV out of the return value. This also only mainly happened during make test. Doing prove myself would succeed 19 times out of 20, where make test would fail 19 times out of 20. Worse, my C test program would never fail at all.

I changed everything I could think of: Using a debugging perl and keeping debug symbols in my C library and XS module made the failures happen less frequently (making debugging ever more frustrating). perlbrew was a big help here, letting me switch between different versions of perl, debugging perl, threaded perl, and combinations thereof.

After playing with GDB (once again succeeding 19 times out of 20), I gave up and searched the web. I found the same mailing list thread multiple times, and read it multiple times, not coming up with anything that was relevant to my situation.

Until I read the thread again after another frustrating half-hour with GDB: I had forgotten to put a prototype in the .h file, causing the char* pointer being returned to be treated as an int. On my 64-bit system, this causes segfaults. The compiler was warning me of this, "warning: initialization makes pointer from integer without a cast", but I didn't understand the warning (and the web was not helpful on that one).

Adding the function prototype to the C wrapper header and recompiling fixed the problem.

And that is why I need to learn a lot more about C. Function prototypes? Header files? Why are those necessary (I'm asking rhetorically, of course)? Heap and stack? Might as well be herp and derp.

Lesson reinforced: Depth of knowledge does not equal breadth of knowledge.

Also, having IRC at work might have saved me a few hours of hassle.