Eric Wilhelm writes...
#ifdef DEBUG_PRINT
#define dbg_p(x) printf x
#else
#define dbg_p(x)
#endif
Thanks for the tip. I'd used the ifdefs, but not in this config.
Another segfault which emerged later was due to the reference count
on an SV going to 0;
I don't think I've ever had that problem. It might be that the layout
of my code never gave me the opportunity (I use oo inline a lot.)
SV* return_a_scalar (SV* input_sv) {
if (return_the_input_unchanged) {
SvREFCNT_inc(input_sv); /* otherwise it goes to zero */
return input_sv;
}
else {
SV* new_scalar = newSVpvn("foo", 3);
return new_scalar;
}
}
The crux of the biscuit is that Perl doesn't know that the scalar
it's getting back is the same one it sent to C. Perl decrements the
reference count for that scalar and cleans it up. The next time you
try to access it, BAM! Invalid SV and segfault.
I'm a fairly sophisticated Perl hacker, but my C skills haven't been
tested on this ambitious a project before. The O'Reilly book I
taught myself from, "Practical C Programming" by Steve Oualline,
doesn't offer any guidance on debugging memory issues.
Forget that, you just need the K&R book (and that doesn't help with
debugging either.)
I like the proportion of text to exercises in the Oualline. Randal's
Learning Perl is just about the ideal for the way I learn when I'm
teaching myself, and Practical C Programming is similar. Guess I'm
surprised that debugging memory wasn't considered fundamental enough
to be included.
Right. You're probably going to want to learn gdb or another C
debugger.
A subtlety I've gleaned from this experience is that if you're going
to rely on C pointers to make your code simple and fast, or because
you can't do what you need to do any other way, you have to allow
extra development time for debugging these memory problems. I think
nothing of writing hundreds of lines of complicated perl code, then
hitting go -- stuff that takes me days to write can have all the
crashing bugs eliminated in less than an hour. That has not been
true with C, at least C in this architectural plan (and I've been
recalling why I didn't like programming when I was introduced to it
as a youth in the pre-Perl era). Choosing to work with a lot of
pointers is like choosing to work with recursion -- you have to be
aware that you're making troubleshooting that much more time-
consuming. Fencepost errors with pointers are... just... evil.
As for learning a C debugger, I'm glad to know that's the next
step... but now I'll just do what I've been doing for this project,
putting off learning gdb for another day. I've managed to crush all
the *&##$ segfaults, thank dog.
Thanks for letting me know I was stumbling in the right direction.
Development has been a little slow, but damn those searches run quick
now!
Marvin Humphrey
Rectangular Research
http://www.rectangular.com/