On 8 June 2015 at 13:18, Anders Magnusson <ra...@ludd.ltu.se> wrote: > David Holland skrev den 2015-06-08 19:06: >> >> On Mon, Jun 08, 2015 at 04:15:15PM +0200, Anders Magnusson wrote: >> >> printfing from the back of the front end is definitely "totally wrong >> >> in other ways that need to be rectified first" :( >> > Hm, I may be missing something, but what is wrong? >> > Where should you print it out otherwise? >> >> I would say the debug information ought to be attached to the >> representation nodes it describes as it moves through the backend; >> otherwise it's easily upset by fairly simple transformations. >> > It's simpler than that :-) > > Debug info for all data declarations etc are printed out when found, > so are the declarations themselves. No reason to keep them.
Traditional stabs, with their very limited capacity to describe whats going on don't exactly help (there are extensions), but they aren't really the problem. As you note, data values are printed by stabs.c:stabs_newsym() at the start of a block. For instance: case AUTO: cprint(0, "\t.stabs \"%s:%s\",%d,0," CONFMT ",%d\n", sname, ostr, N_LSYM, (CONSZ)suesize, BIT2BYTE(s->soffset)); break; case REGISTER: cprint(0, "\t.stabs \"%s:r%s\",%d,0,%d,%d\n", sname, ostr, N_RSYM, 1, s->soffset); break; it might be mostly correct at .O0 when on a statement boundary, but not when there's an optimizer. For instance: - stack values never get written back to the stack - multi-register values are never in contiguous registers (which is why debuggers invariably print wrong values). The compiler needs to describe where values are, for failing that, describe that the value was lost. > Debug info for code follows the code itself. This is necessary, since > the debug info must follow the reference to a place in the code stream, > otherwise the debug info might refer to a label that is optimized away > which is not acceptable by the assembler :-) In stabs.c:stabs_line, there's what I'm going to call a "gem": void stabs_line(int line) { if (inftn == 0) return; /* ignore */ Part of debugger folk law is to set a breakpoint on a function the debugger needs to do something like: - find foo - find foo's first stabn - set a breakpoint on the stabn, and then cross fingers and hope that the compiler hasn't sneezed the above code, which suppresses line-number information in the epilogue, explains why. Even without optimization shooting us in the foot, a program that stops (crashes) inside the epilogue (or initialization of a block, or mid way through a statement) has wrong information(1) - the stack isn't fully formed for instance (I suspect there was also folk law saying debuggers should surreptitiously single-step to the next stabn when they find the program stopped between two lines). Andrew (1) it may also have trouble unwinding, but that is another story