[RFC] "info registers" is misleading
Michael Snyder
msnyder@redhat.com
Mon Jan 21 23:13:00 GMT 2002
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 <stdio.h>
>
> 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.
More information about the Gdb-patches
mailing list