From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2253 invoked by alias); 11 Jul 2007 21:13:55 -0000 Received: (qmail 2242 invoked by uid 22791); 11 Jul 2007 21:13:54 -0000 X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.4) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 11 Jul 2007 21:13:52 +0000 Received: (qmail 17173 invoked from network); 11 Jul 2007 21:13:50 -0000 Received: from unknown (HELO localhost) (jimb@127.0.0.2) by mail.codesourcery.com with ESMTPA; 11 Jul 2007 21:13:50 -0000 To: "Dave Korn" Cc: "'Hadron'" , "'Nick Roberts'" , "'Hadron'" , Subject: Re: argc - cant access memory References: <87ejjhg137.fsf@gmail.com> <18066.47080.812496.129394@kahikatea.snap.net.nz> <87hcoc5uef.fsf@gmail.com> <00a401c7c32a$567046f0$2e08a8c0@CAM.ARTIMI.COM> From: Jim Blandy Date: Wed, 11 Jul 2007 21:13:00 -0000 In-Reply-To: <00a401c7c32a$567046f0$2e08a8c0@CAM.ARTIMI.COM> (Dave Korn's message of "Tue, 10 Jul 2007 20:41:40 +0100") Message-ID: User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-IsSubscribed: yes Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org X-SW-Source: 2007-07/txt/msg00103.txt.bz2 "Dave Korn" 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 : lea 0x4(%esp),%ecx 0x08048358 : and $0xfffffff0,%esp 0x0804835b : pushl 0xfffffffc(%ecx) 0x0804835e : push %ebp 0x0804835f : mov %esp,%ebp 0x08048361 : push %ebx 0x08048362 : push %ecx 0x08048363 : sub $0x10,%esp 0x08048366 : mov %ecx,%ebx 0x08048368 : movl $0x1,(%esp) 0x0804836f : call 0x8048298 0x08048374 : mov (%ebx),%eax 0x08048376 : add $0x10,%esp 0x08048379 : pop %ecx 0x0804837a : pop %ebx 0x0804837b : pop %ebp 0x0804837c : lea 0xfffffffc(%ecx),%esp 0x0804837f : 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.