* [RFC] Possible gcc/DWARF or gdb/DWARF problem
@ 2003-11-29 20:26 Fred Fish
2003-12-01 1:54 ` Daniel Jacobowitz
2003-12-01 15:21 ` Jim Blandy
0 siblings, 2 replies; 4+ messages in thread
From: Fred Fish @ 2003-11-29 20:26 UTC (permalink / raw)
To: gcc-bugs; +Cc: gdb, fnf
While chasing a gdb testsuite failure for the sh-elf toolchain, I
discovered a problem printing a local variable that appears to be
either a generic gcc bug in how it generates DWARF2 info for the local
variable, or perhaps a gdb bug in how gdb interprets the DWARF2
information.
I've done a quick check of the 2.0.0 revision of the DWARF industry
review draft of the DWARF standard and I didn't see anything obvious
that relates to this particular situation. But it has been years
since I did any serious low level DWARF hacking so I could have easily
missed something.
Consider the following code, simplified from some "scope" tests in the
gdb testsuite:
signed char bar (register signed char u)
{
return (u + 1);
}
signed char foo (register signed char u)
{
register signed char l = u;
l = bar (l);
return (l);
}
main ()
{
foo (3);
}
Note that:
(1) the register declarations are required to expose the bug. Without
them, the generated code and debug information is different and the
problem goes away.
(2) The example should be compiled without optimization.
(3) The problem is masked if the target is little endian. Toolchains
such as sh-elf or mipsisa32-elf which are bi-endian help to
demonstrate this.
Here is an example using the sh-elf toolchain in big endian mode.
Note that the value of 'l' after being assigned from 'u' and before
calling bar() is printed as 0 and should be 3, the same as 'u':
$ sh-elf-gcc -g -m4 -mb -o b b.c
$ sh-elf-gdb b
GNU gdb 2003-11-29-cvs
Copyright 2003 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=sh-elf"...
(gdb) tar sim
Connected to the simulator.
(gdb) load
Loading section .init, size 0x36 vma 0x1000
Loading section .text, size 0x1900 vma 0x1040
Loading section .fini, size 0x2a vma 0x2940
Loading section .rodata, size 0x1e vma 0x296c
Loading section .data, size 0x798 vma 0x2a0c
Loading section .eh_frame, size 0x4 vma 0x31a4
Loading section .ctors, size 0x8 vma 0x31a8
Loading section .dtors, size 0x8 vma 0x31b0
Loading section .jcr, size 0x4 vma 0x31b8
Loading section .got, size 0xc vma 0x31bc
Loading section .stack, size 0x4 vma 0x30000
Start address 0x1040
Transfer rate: 68080 bits/sec.
(gdb) br foo
Breakpoint 1 at 0x1186: file b.c, line 8.
(gdb) run
Starting program: /tmp/b
Breakpoint 1, foo (u=3 '\003') at b.c:8
8 register signed char l = u;
(gdb) n
10 l = bar (l);
(gdb) p l
$1 = 0 '\0'
(gdb)
If however we use little endian mode, the value is printed correctly:
$ sh-elf-gcc -g -m4 -ml -o b b.c
$ sh-elf-gdb b
GNU gdb 2003-11-29-cvs
Copyright 2003 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=sh-elf"...
(gdb) tar sim
Connected to the simulator.
(gdb) load
Loading section .init, size 0x36 vma 0x1000
Loading section .text, size 0x1900 vma 0x1040
Loading section .fini, size 0x2a vma 0x2940
Loading section .rodata, size 0x1e vma 0x296c
Loading section .data, size 0x798 vma 0x2a0c
Loading section .eh_frame, size 0x4 vma 0x31a4
Loading section .ctors, size 0x8 vma 0x31a8
Loading section .dtors, size 0x8 vma 0x31b0
Loading section .jcr, size 0x4 vma 0x31b8
Loading section .got, size 0xc vma 0x31bc
Loading section .stack, size 0x4 vma 0x30000
Start address 0x1040
Transfer rate: 68080 bits/sec.
(gdb) br foo
Breakpoint 1 at 0x1186: file b.c, line 8.
(gdb) run
Starting program: /tmp/b
Breakpoint 1, foo (u=3 '\003') at b.c:8
8 register signed char l = u;
(gdb) n
10 l = bar (l);
(gdb) p l
$1 = 3 '\003'
(gdb)
The problem is that the live value of 'l' at the time we print it is
on the stack, and the address computed from the dwarf information is
for the lowest address of the 4 byte stack slot that holds the
character value. In the big endian case, this is for the most
significant byte, which is zero. In the little endian case, this is
for the least significant byte, which is 3.
Note also that the dwarf info is identical for either endian:
$ sh-elf-gcc -g -m4 -mb -c b.c
$ dwarfdump -a b.o >b.o.mb
$ sh-elf-gcc -g -m4 -ml -c b.c
$ dwarfdump -a b.o >b.o.ml
$ diff b.o.mb b.o.ml
The code is also identical except for a pseudo that indicates the
endianness:
$ sh-elf-gcc -g -m4 -mb -S b.c
$ mv b.s b.s.mb
$ sh-elf-gcc -g -m4 -ml -S b.c
$ mv b.s b.s.ml
$ diff b.s.mb b.s.ml
2a3
> .little
$ diff -c b.s.mb b.s.ml
*** b.s.mb 2003-11-29 13:00:08.000000000 -0700
--- b.s.ml 2003-11-29 13:00:16.000000000 -0700
***************
*** 1,5 ****
--- 1,6 ----
.file "b.c"
.text
+ .little
.section .debug_abbrev,"",@progbits
.Ldebug_abbrev0:
.section .debug_info,"",@progbits
$
For reference, here are the relevant parts of the dwarfdump output:
<1>< 107> DW_TAG_base_type
DW_AT_name signed char
DW_AT_byte_size 1
DW_AT_encoding DW_ATE_signed_char
<2>< 160> DW_TAG_variable
DW_AT_name l
DW_AT_decl_file 1 /tmp/b.c
DW_AT_decl_line 8
DW_AT_type <107>
DW_AT_location DW_OP_fbreg 0
I'd like to get some comments on whether this is a gcc/DWARF or
gdb/DWARF issue. If the consensus is that gdb is not doing the right
thing, then I'll chase the problem in gdb. If the consensus is that
it is gcc, then I'll file a formal gcc bug report. My guess is that
since gcc is generating the memory offset of a 1 byte object relative
to the frame pointer that the DW_AT_location for the big endian case
should be:
DW_AT_location DW_OP_fbreg 3
-Fred
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFC] Possible gcc/DWARF or gdb/DWARF problem
2003-11-29 20:26 [RFC] Possible gcc/DWARF or gdb/DWARF problem Fred Fish
@ 2003-12-01 1:54 ` Daniel Jacobowitz
2003-12-01 15:21 ` Jim Blandy
1 sibling, 0 replies; 4+ messages in thread
From: Daniel Jacobowitz @ 2003-12-01 1:54 UTC (permalink / raw)
To: fnf; +Cc: gcc-bugs, gdb
On Sat, Nov 29, 2003 at 01:26:03PM -0700, Fred Fish wrote:
> I'd like to get some comments on whether this is a gcc/DWARF or
> gdb/DWARF issue. If the consensus is that gdb is not doing the right
> thing, then I'll chase the problem in gdb. If the consensus is that
> it is gcc, then I'll file a formal gcc bug report. My guess is that
> since gcc is generating the memory offset of a 1 byte object relative
> to the frame pointer that the DW_AT_location for the big endian case
> should be:
>
> DW_AT_location DW_OP_fbreg 3
I agree. We're describing an object in memory of size 1. It should be
at the specified location, not padded.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFC] Possible gcc/DWARF or gdb/DWARF problem
2003-11-29 20:26 [RFC] Possible gcc/DWARF or gdb/DWARF problem Fred Fish
2003-12-01 1:54 ` Daniel Jacobowitz
@ 2003-12-01 15:21 ` Jim Blandy
2003-12-01 16:42 ` Fred Fish
1 sibling, 1 reply; 4+ messages in thread
From: Jim Blandy @ 2003-12-01 15:21 UTC (permalink / raw)
To: fnf; +Cc: gcc-bugs, gdb
Fred Fish <fnf@public.ninemoons.com> writes:
> For reference, here are the relevant parts of the dwarfdump output:
>
> <1>< 107> DW_TAG_base_type
> DW_AT_name signed char
> DW_AT_byte_size 1
> DW_AT_encoding DW_ATE_signed_char
>
> <2>< 160> DW_TAG_variable
> DW_AT_name l
> DW_AT_decl_file 1 /tmp/b.c
> DW_AT_decl_line 8
> DW_AT_type <107>
> DW_AT_location DW_OP_fbreg 0
>
> I'd like to get some comments on whether this is a gcc/DWARF or
> gdb/DWARF issue. If the consensus is that gdb is not doing the right
> thing, then I'll chase the problem in gdb. If the consensus is that
> it is gcc, then I'll file a formal gcc bug report. My guess is that
> since gcc is generating the memory offset of a 1 byte object relative
> to the frame pointer that the DW_AT_location for the big endian case
> should be:
>
> DW_AT_location DW_OP_fbreg 3
So, in the big-endian case, the compiler is generating code that
places the one-byte value at offset 3 from the frame base register.
(Since you say the code for the little-endian and big-endian cases is
identical, we know it uses 32-bit stores and loads to fb+0 to access
it, but that's irrelevant; it's a one-byte value.) Right?
You're right --- GCC is wrong. The Dwarf 2 info it's producing
clearly describes a one-byte value at offset 0 from the frame base.
How GCC decides to generate code to access it is not our problem.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFC] Possible gcc/DWARF or gdb/DWARF problem
2003-12-01 15:21 ` Jim Blandy
@ 2003-12-01 16:42 ` Fred Fish
0 siblings, 0 replies; 4+ messages in thread
From: Fred Fish @ 2003-12-01 16:42 UTC (permalink / raw)
To: Jim Blandy; +Cc: fnf, gcc-bugs, gdb
> it uses 32-bit stores and loads to fb+0 to access
> it, but that's irrelevant; it's a one-byte value.) Right?
Correct.
> You're right --- GCC is wrong.
I'll go ahead and file a formal gcc bug report.
-Fred
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2003-12-01 16:42 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-11-29 20:26 [RFC] Possible gcc/DWARF or gdb/DWARF problem Fred Fish
2003-12-01 1:54 ` Daniel Jacobowitz
2003-12-01 15:21 ` Jim Blandy
2003-12-01 16:42 ` Fred Fish
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox