This is the mail archive of the gdb@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: argc - cant access memory


"Dave Korn" <dave.korn@artimi.com> writes:
>   This is normal behaviour.  It's nothing to do with optimisation: it's just
> that gdb breakpoints at the very start of the function epilogue, but none of
> the arguments parameters are accessible in the expected places indicated by
> the debug info until after the epilogue has created the stack frame, etc.
>
>   Try this with any function you like: set a breakpoint on the very first line
> - the one with the opening '{' of the function, run until you hit the
> breakpoint.  You'll see nonsense in the locals and arguments.  Now use the
> 'next' function to step over the opening brace - which amounts to stepping
> over the function epilogue - and suddenly all those variables will spring into
> being with their correct values.
>
>   It's a cosmetic glitch that gdb fails to say something like "not in scope"
> before the prologue has completed.

Daniel's explanation is right, but I wanted to clarify something here:

As long as GDB is properly interpreting the debugging info it has
(which in this case it is), then this isn't GDB's problem to solve;
it's GCC's.  GDB can only debug the program as described by the
debugging information.  The fault here is in GCC for not properly
describing the code it produced.

Especially nowadays, there is no clear boundary between the prologue
and the body code; body instructions may be mixed in with prologue
instructions.  This means that it's not possible for GDB to accurately
declare variables "not in scope" until the end of the prologue.

DWARF does have the features required for the compiler to accurately
describe every variable's location at every point in the code, even in
the prologue, or at the function's entry point.  And GDB understands
that info (although it can't assign to variables in some cases).

The code I see is:

    (gdb) disass main
    Dump of assembler code for function main:
    0x08048354 <main+0>:	lea    0x4(%esp),%ecx
    0x08048358 <main+4>:	and    $0xfffffff0,%esp
    0x0804835b <main+7>:	pushl  0xfffffffc(%ecx)
    0x0804835e <main+10>:	push   %ebp
    0x0804835f <main+11>:	mov    %esp,%ebp
    0x08048361 <main+13>:	push   %ebx
    0x08048362 <main+14>:	push   %ecx
    0x08048363 <main+15>:	sub    $0x10,%esp
    0x08048366 <main+18>:	mov    %ecx,%ebx
    0x08048368 <main+20>:	movl   $0x1,(%esp)
    0x0804836f <main+27>:	call   0x8048298 <sleep@plt>
    0x08048374 <main+32>:	mov    (%ebx),%eax
    0x08048376 <main+34>:	add    $0x10,%esp
    0x08048379 <main+37>:	pop    %ecx
    0x0804837a <main+38>:	pop    %ebx
    0x0804837b <main+39>:	pop    %ebp
    0x0804837c <main+40>:	lea    0xfffffffc(%ecx),%esp
    0x0804837f <main+43>:	ret    
    End of assembler dump.

The 'lea' saves the frame's base address in %ecx; the 'and' aligns the
stack pointer.  At that point, there's no fixed relationship between
the stack pointer and the base of the frame; it depends on how
misaligned the sp was originally.  We save %ebp and set it from the
aligned stack pointer.

Here's the output from readelf -wfF, referring to %esp as 'r4',
%ecx as 'r1', and %ebp as 'r5':

    The section .eh_frame contains:

    00000000 ZERO terminator


    The section .debug_frame contains:

    00000000 00000010 ffffffff CIE "" cf=1 df=-4 ra=8
       LOC   CFA      ra   
    00000000 r4+4     c-4  

    00000014 00000024 00000000 FDE cie=00000000 pc=08048354..08048380
       LOC   CFA      r3   r4   r5   ra   
    08048354 r4+4     u    u    u    c-4  
    08048358 r1+0     u    r1   u    c-4  
    0804835e r4+4     u    r1   u    c-4  
    0804835f r4+8     u    r1   c-8  c-4  
    08048361 r5+8     u    r1   c-8  c-4  
    08048363 r5+8     c-12 c-16 c-8  c-4  

After the 'and' at 0x08048358, the CFA should always be %ecx+0, but as
you can see, the CFI emitted by GCC incorrectly reverts to offsets
from %esp and %ebp.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]