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/

Reply via email to