From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27921 invoked by alias); 10 May 2005 14:45:13 -0000 Mailing-List: contact gdb-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sources.redhat.com Received: (qmail 27711 invoked from network); 10 May 2005 14:45:00 -0000 Received: from unknown (HELO nevyn.them.org) (66.93.172.17) by sourceware.org with SMTP; 10 May 2005 14:45:00 -0000 Received: from drow by nevyn.them.org with local (Exim 4.50) id 1DVVyl-0003Pi-Vo; Tue, 10 May 2005 10:45:00 -0400 Date: Tue, 10 May 2005 14:45:00 -0000 From: Daniel Jacobowitz To: Tigran Aivazian Cc: gdb@sources.redhat.com Subject: Re: gdb problems with -O1 on x86_64 architecture. Message-ID: <20050510144459.GA12601@nevyn.them.org> Mail-Followup-To: Tigran Aivazian , gdb@sources.redhat.com References: <20050509163938.GA22498@nevyn.them.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.8i X-SW-Source: 2005-05/txt/msg00135.txt.bz2 On Tue, May 10, 2005 at 03:33:31PM +0100, Tigran Aivazian wrote: > Hi, > > I thought it is worth showing how it behaves on -O2 compiled binary as > well: > > # gcc -g -Wall -O2 -fno-optimize-sibling-calls uvar.c -o uvar-O2 > > (gdb) b kt_func3 > Breakpoint 1 at 0x4004e0: file uvar.c, line 11. > (gdb) r > Starting program: /root/mod/uvar-O2 > > Breakpoint 1, kt_func3 (x1=0x11111133, x2=0x22222244, x3=0x33333355, > x4=0x44444466, x5=0x55555577, x6=0x66666688, > x7=0x77777799, x8=0x888888aa, x9=0x9566b560) at uvar.c:11 > 11 return (x1 + x2 + x3/2 + x4/4 + x5/5 + x6/6 + x7/7 + x8/8 > + x9/9); > (gdb) bt > #0 kt_func3 (x1=0x11111133, x2=0x22222244, x3=0x33333355, x4=0x44444466, > x5=0x55555577, x6=0x66666688, x7=0x77777799, > x8=0x888888aa, x9=0x9566b560) at uvar.c:11 > #1 0x00000000004005d3 in kt_func2 (x1=, x2= optimized out>, x3=, > x4=, x5=, x6= optimized out>, x7=0x77777788, x8=0x88888899, > x9=0x999999aa) at uvar.c:16 > #2 0x0000000000400623 in kt_func1 (x1=, x2= optimized out>, x3=, > x4=, x5=, x6= optimized out>, x7=0x77777777, x8=0x88888888, > x9=0x99999999) at uvar.c:22 > #3 0x000000000040067a in main (argc=, argv= optimized out>) at uvar.c:30 > > As you see, it claims that x1,x2,x3,x4,x5,x6 are optimized out and > x7,x8,x9 are available and shows the correct values. This is for kt_func2 > and kt_func1 functions, but for kt_func3 it shows all values correctly > except the last one --- x9 is garbage. But with -O0 it shows everything > correctly. GDB's doing the best it can. Let me give you a case-by-case. First the top frame. We're at 0x4004e0; presumably because this function does not appear to have a prologue. Debuginfo says: x1 in reg5, but only for the first two instructions, then dead x2 in reg4 x3 in reg1 until +0x14 x4 in reg2 ... x9 in reg3 Well, reg3 is %rbx and that's just not true. 4004e4: 53 push %rbx 4004f7: 8b 5c 24 20 mov 0x20(%rsp),%ebx _NOW_ it's in rbx. The compiler didn't tell us that the variable came in on the stack and then moved to %rbx, it said it was in %rbx the whole time. This is a (very common) compiler bug; it's rare that a compiler tracks incoming argument locations properly. I hope GCC does someday. How about for the next frame? Let's look at 0x00000000004005d3 in kt_func2. Please take a look at the code for a moment. 400590: 48 83 ec 18 sub $0x18,%rsp 400594: 41 83 c1 11 add $0x11,%r9d 400598: 41 83 c0 11 add $0x11,%r8d 40059c: 8b 44 24 30 mov 0x30(%rsp),%eax 4005a0: 44 8b 54 24 28 mov 0x28(%rsp),%r10d 4005a5: 83 c1 11 add $0x11,%ecx 4005a8: 44 8b 5c 24 20 mov 0x20(%rsp),%r11d 4005ad: 83 c2 11 add $0x11,%edx 4005b0: 83 c6 11 add $0x11,%esi 4005b3: 83 c7 11 add $0x11,%edi 4005b6: 83 c0 11 add $0x11,%eax 4005b9: 41 83 c2 11 add $0x11,%r10d 4005bd: 41 83 c3 11 add $0x11,%r11d 4005c1: 89 44 24 10 mov %eax,0x10(%rsp) 4005c5: 44 89 54 24 08 mov %r10d,0x8(%rsp) 4005ca: 44 89 1c 24 mov %r11d,(%rsp) 4005ce: e8 0d ff ff ff callq 4004e0 4005d3: 48 83 c4 18 add $0x18,%rsp 4005d7: c3 retq How would you propose recovering the value which was in %r9d on entrance to this function? Or %ecx? It can't be done. A too-clever-for-its-own-good compiler might tell us that we could recreate a read-only copy by unwinding %r9d and then subtracting 0x11, except that I'm pretty sure the register is call clobbered, so we can't recreate its value anyway. -- Daniel Jacobowitz CodeSourcery, LLC