Roadblock

Whiteknight on 2008-07-07T15:52:00

I picked up work this morning, coming back from the nice three-day weekend. Unfortunately, I have hit a bit of a roadblock and cannot seem to figure out where the problem lies.

What I am trying to do now is to get the build process to complete. At the moment, building fails at the following step, in compilers/pge:

../../parrot ../../runtime/parrot/library/PGE/Perl6Grammar.pir --output=PGE/builtins_gen.pir PGE/builtins.pg

Most of the build steps up to this point that require parrot are very short and simple, and none of them that I can see trigger a full GC run. I've added a series of diagnostic messages to trace the execution path of this step, and the answers that I find are quite perplexing. The GC finishes a complete run in batch mode. After the GC run completes, the program segfaults.

My initial assumption is that somewhere I am freeing an object that should not be freed, attempting to reuse a pointer from a freed object, and segfaulting that way. So, I comment out the function calls to the sweep code, and try to build again. Same result. I think that maybe a call to gc_it_add_free_object is freeing an object that should not be freed, so I comment that function out. Same result. The GC at this point is simply not freeing any objects. We perform the normal allocation functions and the mark phase, but we do not sweep or recycle any usused objects after they have been marked dead.

So I fire up GDB and run that step in the debugger. GDB tells me that the error is occurring in a memcpy call from src/strings.c:Parrot_unmake_COW. So, I go into that function, add a few PARROT_ASSERT() calls and diagnostic messages and...Same Result. I mean, the result was exactly the same, no diagnostic messages printed out (even though it should be printing a few things before any pointers are dereferenced), no assertions fail, nothing. If it weren't for the debugger telling me that the error is occuring here, I wouldn't believe that this function is being called anywhere near the segfault.

However, if it is a problem with strings (and I don't doubt necessarily that it could be), I figure I'll poke around with them a little bit more. I go to src/headers.c:get_string_header and make extra certain to initialize all fields in the new string header, especially all pointers. Again, nothing changes.

I'm going to play around with my allocators now, to ensure they are returning proper pointers. after that, I'm diving back into GDB to single-step my way through the entire program (or, the important parts of it anyway). Hopefully, I can get this particular problem solved and soon.


STRING Problems

chromatic on 2008-07-07T17:35:31

That reminds me a little bit of Parrot RT #51652. I'm not sure it's the same problem, but that part of Parrot can be a little fragile.

Re:STRING Problems

Whiteknight on 2008-07-07T23:19:12

Good call. The ticket number is right even though the link is wrong.

I added in a few statements to test for the basic isomorphisms that I've been relying on:

        PARROT_ASSERT(offsetof(Buffer, flags) == offsetof(PObj, flags));
        PARROT_ASSERT(offsetof(Buffer, flags) == offsetof(PMC, flags));
        PARROT_ASSERT(offsetof(Buffer, flags) == offsetof(STRING, flags));
        PARROT_ASSERT(offsetof(Buffer, flags) == offsetof(Stack_Chunk_t, flags));

All these assertions appear to be passing. I'll dig through src/headers.c and some of my allocators again, and make sure that I am not relying on any other relationships besides these.

I do know that I could probably do better in aligning data in memory. I currently pack things together tightly in the arenas, and this throws off object alignment. On the off-chance that poor alignment could cause a segfault, I'll go back and redo this.