Bug Huntin

Whiteknight on 2008-06-30T23:59:01

I spent some time this morning working on peripheral projects: I did some consolidation work on the stack code and I did some IMCC work to enable use of the "self" keyword in :vtable functions. These were valuable, and well worth doing. Plus, I wanted to get the stack stuff out of the way first, so i could incorporate it easily into my GC work.

Then, shifting my focus back to where it should be, I open up the gsoc folder and type "make". Errors. This is to be expected, nothing ever works the first time. I learned that from a compsci teacher back in college, and if I dont remember anything about him or his class, I will always remember that lesson: It never compiles on the first try, don't even expect it.

So I went through all the little details, mistakes, and warnings, and finally got Parrot to compile. Compiling, of course, isn't the same as "working", and I have a lot of work left to do. The behavior now is the same as it was a week ago: The program starts up, and segfaults. Now, however, it doesn't appear to be running even simple programs anymore. I haven't attempted to run the test suite on it yet, but I don't expect it to be pretty when I do.

I installed a few ugly, but incredibly helpful, diagnostic messages hidden behind the GC_IT_DEBUG macro. When activated, the debugging messages print out a variety of information tidbits, most of which are point addresses and pool names. The first run through, I found an immediate problem with arena allocations, my pointer arithmetic was screwy and the objects I was allocating were coming out at 2046 bytes instead of the intended 24 bytes. I fixed that quickly, ran it again, and got the right answer the second time.

I've never used GDB before. I had done some debugging and reversing work on Windows with programs like OllyDBG, but I've never done any debugging on Linux (and certainly never from a terminal). I fired it up and ran through the program until it crashed. The crash happened, apparently, in src/charset.c in a function register_charset. A rather innocuous string comparison appears to be (if I'm reading this thing right) the source of the error.

When the program starts up, the various pools are initialized (constant string, buffer headers, string headers, pmcs, pmc_exts, and constant pmcs), a new arena is allocated in the constant string arena with 142 objects, and immediately a run is made on those objects. Previously about 120 constant string objects were allocated immediately before segfaulting, then I "fixed" the problem with pointers I described above, and now it only allocates 8 objects before segfaulting. Either way, the trend is obvious: When parrot is starting up, a lot of const string headers are being allocated immediately.

Now that I know where to focus my attention, hopefully I can get this particular issue solved soon. Something in the const string header must not get initialized properly, which leads to an inevitable segfault when so many are allocated at once. I'll take a close look at the code for the other GCs and the code in src/headers.c tomorrow and try to isolate the problem. Until then, I'm going to find a good reference for GDB for my evening reading.


GDB Reference

chromatic on 2008-07-01T01:26:44

If you have a Safari account, the physical book, or Google Books skills, the GDB chapter in C in a Nutshell is invaluable.