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

Reply via email to