From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 24862 invoked by alias); 22 Jan 2002 06:51:24 -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 24815 invoked from network); 22 Jan 2002 06:51:19 -0000 Received: from unknown (HELO fred.ninemoons.com) (68.15.182.197) by sources.redhat.com with SMTP; 22 Jan 2002 06:51:19 -0000 Received: (from fnf@localhost) by fred.ninemoons.com (8.11.6/8.11.6) id g0M6pMe17608; Mon, 21 Jan 2002 23:51:23 -0700 From: Fred Fish Message-Id: <200201220651.g0M6pMe17608@fred.ninemoons.com> Subject: [RFC] "info registers" is misleading To: gdb-patches@sources.redhat.com Date: Mon, 21 Jan 2002 22:51:00 -0000 Cc: fnf@redhat.com Reply-To: fnf@redhat.com X-Mailer: ELM [version 2.5 PL6] MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-SW-Source: 2002-01/txt/msg00678.txt.bz2 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. -Fred