|Version 3 (modified by nwellnhof, 4 years ago)|
If you are getting a segfault on one platform but can't reproduce it on another, you can use the gcdebug runcore on the second platform; If the segfault is a result of a GC bug that isn't being tripped on that platform, this trick will allow other core developers to find (and hopefully fix) the bug.
For example, OSX/intel's gdb doesn't quite work for the steps below; by using the other runcore, you can force the bug to occur on a linux box, where gdb is adequate for the task.
If you can reliably generate the segfault, you do NOT need the --runcore option.
Fire up parrot inside gdb:
$ gdb parrot
Now run the PIR code
(gdb) run --runcore=gcdebug foo.pir
This will eventually segfault; at that point, figure out which PMC has been garbage collected prematurely. get the address of that PMC. (Note that the PMC will have a valid address, but its data pointer will be 0xdeadbeef).
Now, the problem is, you don't necessarily know where this PMC was allocated. To figure this out, you'll need to check in pmc_new when a pmc of this address was creatd.
Since this address can be reused during the course of the program, you have to find the *last* time this was done. Rather than step through by hand, you can use gdb to help you automate this.
First, set a conditional breakpoint on the return line of pmc_new(), looking for the value of the pmc that caused the segfault. The odds are VERY good that it will end up being the same address on subsequent runs. If the address changes, try passing a constant hash seed to parrot with the --hash-seed option. Please double check this line number (current as of 10/27/07)
(gdb) break src/pmc.c:73 if pmc==<VALUE OF COLLECTED PMC>
Now, tell gdb that every time you stop at this breakpoint, you want it to print a backtrace and continue. Assuming this is your first and only breakpoint:
(gdb) commands 1 Type commands for when breakpoint 1 is hit, one per line. End with a line saying just "end". >bt >c >end
Now, run the same command again. Everytime the conditional breakpoint is hit, a backtrace will be generated, and gdb will continue to the next breakpoint.
This time when you get your segfault, you'll have a backtrace showing where that pmc was created. Presumably it should have been registered with the GC system and wasn't, and was therefore collected prematurely.
chromatic++; All the smart stuff here is his. For an overview of Parrot's GC and the GD debugging runcore, see Debugging GC Problems in Parrot. For a sample debugging session, see How to Debug a GC Problem in Parrot.