From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27952 invoked by alias); 22 Jan 2002 07:13:28 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 27855 invoked from network); 22 Jan 2002 07:13:15 -0000 Received: from unknown (HELO cygnus.com) (205.180.230.5) by sources.redhat.com with SMTP; 22 Jan 2002 07:13:15 -0000 Received: from telocity.telocity.com (taarna.sfbay.redhat.com [205.180.230.102]) by runyon.cygnus.com (8.8.7-cygnus/8.8.7) with SMTP id XAA13103; Mon, 21 Jan 2002 23:13:07 -0800 (PST) Message-ID: <3C4D0FF4.57D1@redhat.com> Date: Mon, 21 Jan 2002 23:13:00 -0000 From: Michael Snyder X-Mailer: Mozilla 3.04 (Win95; I) MIME-Version: 1.0 To: fnf@redhat.com CC: gdb-patches@sources.redhat.com Subject: Re: [RFC] "info registers" is misleading References: <200201220651.g0M6pMe17608@fred.ninemoons.com> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-SW-Source: 2002-01/txt/msg00679.txt.bz2 Fred Fish wrote: > > I had always thought that "info registers" is supposed to tell you > the actual register contents, and is simply a convenient way to see > all the registers with one command. I.E. it is equivalent to > doing something like: > > (gdb) p/x $r0 > (gdb) p/x $r1 > ... > > While chasing a bug in some THUMB code related to the stack not being > restored correctly when using the "return xxx" command, I stumbled > over a case where "info registers" prints the value of r11 differently > than "p/x $r11" does. > > Script started on Mon Jan 21 23:33:14 2002 > > $ cat bug.c > #include > > int > callee2 (int n) > { > return 0; > } > > int > callee1 (void) > { > int n = 1; > n = callee2 (n); > return n; > } > > int main () > { > callee1 (); > } > > $ arm-elf-gcc -mthumb -g -o bug bug.c > > $ ./gdb-orig -nw -nx bug > GNU gdb 2002-01-22-cvs > Copyright 2002 Free Software Foundation, Inc. > GDB is free software, covered by the GNU General Public License, and you are > welcome to change it and/or distribute copies of it under certain conditions. > Type "show copying" to see the conditions. > There is absolutely no warranty for GDB. Type "show warranty" for details. > This GDB was configured as "--host=i686-pc-linux-gnu --target=arm-elf"... > (gdb) tar sim > Connected to the simulator. > (gdb) load > Loading section .init, size 0x14 vma 0x8000 > Loading section .text, size 0x1570 vma 0x8014 > Loading section .fini, size 0x10 vma 0x9584 > Loading section .rodata, size 0x8 vma 0x9594 > Loading section .data, size 0x84c vma 0x969c > Loading section .eh_frame, size 0x4 vma 0x9ee8 > Loading section .ctors, size 0x8 vma 0x9eec > Loading section .dtors, size 0x8 vma 0x9ef4 > Loading section .jcr, size 0x4 vma 0x9efc > Start address 0x80cc > Transfer rate: 61440 bits in <1 sec. > (gdb) br callee2 > Breakpoint 1 at 0x81ae: file bug.c, line 6. > (gdb) run > Starting program: /build/sourceware/gdb/H-i686-pc-linux-gnu/T-arm-elf/gdb/bug > > Breakpoint 1, callee2 (n=1) at bug.c:6 > 6 return 0; > (gdb) info reg > r0 0x1 1 > r1 0x1ffffc 2097148 > r2 0x1fffe8 2097128 > r3 0x1fffdc 2097116 > r4 0x1 1 > r5 0x1ffffc 2097148 > r6 0x0 0 > r7 0x1fffe0 2097120 > r8 0x0 0 > r9 0x0 0 > r10 0x200100 2097408 > r11 0x1fffe0 2097120 > r12 0x0 0 > sp 0x1fffdc 2097116 > lr 0x81cf 33231 > pc 0x81ae 33198 > fps 0x0 0 > cpsr 0x20000033 536870963 > (gdb) p/x $r7 > $1 = 0x1fffe0 > (gdb) p/x $r11 > $2 = 0x0 > (gdb) quit > The program is running. Exit anyway? (y or n) y > > Notice in the above that "info reg" prints 0x1fffe0 for the value of > r11, while it actually has a value of 0x0. > > The culprit appears to be read_relative_register_raw_bytes_for_frame(), > which is: > > /* FIXME: This function increases the confusion between FP_REGNUM > and the virtual/pseudo-frame pointer. */ > > static int > read_relative_register_raw_bytes_for_frame (int regnum, > char *myaddr, > struct frame_info *frame) > { > int optim; > if (regnum == FP_REGNUM && frame) > { > /* Put it back in target format. */ > store_address (myaddr, REGISTER_RAW_SIZE (FP_REGNUM), > (LONGEST) FRAME_FP (frame)); > > return 0; > } > get_saved_register (myaddr, &optim, (CORE_ADDR *) NULL, frame, > regnum, (enum lval_type *) NULL); > > if (register_cached (regnum) < 0) > return 1; /* register value not available */ > > return optim; > } > > Getting rid of the section of code that checks for FP_REGNUM: > > if (regnum == FP_REGNUM && frame) > { > /* Put it back in target format. */ > store_address (myaddr, REGISTER_RAW_SIZE (FP_REGNUM), > (LONGEST) FRAME_FP (frame)); > > return 0; > } > > gets rid of the problem: > > $ ./gdb -nw -nx bug > GNU gdb 2002-01-22-cvs > Copyright 2002 Free Software Foundation, Inc. > GDB is free software, covered by the GNU General Public License, and you are > welcome to change it and/or distribute copies of it under certain conditions. > Type "show copying" to see the conditions. > There is absolutely no warranty for GDB. Type "show warranty" for details. > This GDB was configured as "--host=i686-pc-linux-gnu --target=arm-elf"... > (gdb) tar sim > Connected to the simulator. > (gdb) load > Loading section .init, size 0x14 vma 0x8000 > Loading section .text, size 0x1570 vma 0x8014 > Loading section .fini, size 0x10 vma 0x9584 > Loading section .rodata, size 0x8 vma 0x9594 > Loading section .data, size 0x84c vma 0x969c > Loading section .eh_frame, size 0x4 vma 0x9ee8 > Loading section .ctors, size 0x8 vma 0x9eec > Loading section .dtors, size 0x8 vma 0x9ef4 > Loading section .jcr, size 0x4 vma 0x9efc > Start address 0x80cc > Transfer rate: 61440 bits in <1 sec. > (gdb) br callee2 > Breakpoint 1 at 0x81ae: file bug.c, line 6. > (gdb) run > Starting program: /build/sourceware/gdb/H-i686-pc-linux-gnu/T-arm-elf/gdb/bug > > Breakpoint 1, callee2 (n=1) at bug.c:6 > 6 return 0; > (gdb) info reg > r0 0x1 1 > r1 0x1ffffc 2097148 > r2 0x1fffe8 2097128 > r3 0x1fffdc 2097116 > r4 0x1 1 > r5 0x1ffffc 2097148 > r6 0x0 0 > r7 0x1fffe0 2097120 > r8 0x0 0 > r9 0x0 0 > r10 0x200100 2097408 > r11 0x0 0 > r12 0x0 0 > sp 0x1fffdc 2097116 > lr 0x81cf 33231 > pc 0x81ae 33198 > fps 0x0 0 > cpsr 0x20000033 536870963 > (gdb) p/x $r7 > $1 = 0x1fffe0 > (gdb) p/x $r11 > $2 = 0x0 > (gdb) quit > The program is running. Exit anyway? (y or n) y > $ exit > > Notice now that "info reg" correctly prints 0x0 for r11. > > Any comments on the best way to fix this? I have no idea what the > motivation was to treat the frame pointer as a special case when block > printing the registers. This is an old old issue. The frame pointer register is special. Info registers does not show the actual value of the fp register -- it shows the virtual frame pointer (the address of the function's stack frame). Usually it's the same value -- unles you're in a frameless function (ie. one that does not use the frame pointer register). Now that we have pseudo-registers, we've talked about adding a pseudo-frame-pointer register and using it for FP_REGNUM, so that the "real" frame pointer register can always display its real value.