gdb/1433: Broken Display of Bitfields
jimb@redhat.com
jimb@redhat.com
Wed Oct 29 17:43:00 GMT 2003
Synopsis: Broken Display of Bitfields
State-Changed-From-To: open->closed
State-Changed-By: jimb
State-Changed-When: Wed Oct 29 17:43:10 2003
State-Changed-Why:
Thanks for the very clear and explicit bug report.
I believe this is a compiler problem: GCC is generatating Dwarf 2 info
that incorrectly describes the location of the bitfield in the
structure.
Here is the machine code in your assembly file for the assignment to
s1.elvis:
.Lg2:
movl s1,%eax
andl $-8192,%eax
orl $8191,%eax
movl %eax,s1
It fetches the first longword (32 bits) of s1, clears the low 13 bits,
sets them to all ones, and then writes the longword back to s1. So as
far as the machine code is concerned, elvis lives in the 13 least
significant bits of the first longword of s1.
Since the i386 is little-endian, those bits are also the least
significant end of the first word (16 bits) of s1. So the debug
info's 'DW_AT_byte_size' is correct.
However, DW_AT_bit_offset counts from the most significant bit of the
containing word, not the least significant. So the proper bit offset
would be three, not zero.
GCC 3.3 generates the following Dwarf 2 for this:
.uleb128 0x3 # (DIE (0x2f) DW_TAG_member)
.long .LC0 # DW_AT_name: "elvis"
.byte 0x1 # DW_AT_decl_file
.byte 0x2 # DW_AT_decl_line
.long 0x60 # DW_AT_type
.byte 0x4 # DW_AT_byte_size
.byte 0xd # DW_AT_bit_size
.byte 0x13 # DW_AT_bit_offset
.byte 0x2 # DW_AT_data_member_location
.byte 0x23 # DW_OP_plus_uconst
.uleb128 0x0
This stipulates a four-byte container, and gives a bit offset of 19,
which is correct: there are 19 bits of the 32-bit container above the
13 that contain the actual value.
Here is a transcript of GDB debugging the program correctly, when it
is compiled with GCC 3.3:
$ cat jvd.c
struct t {
int elvis :13;
int bruce :5;
char jvd;
} s1;
main() {
s1.elvis = -1;
s1.bruce = -1;
return s1.jvd == 0;
}
$ gcc --version
gcc (GCC) 3.3
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ gcc -g -dA -save-temps jvd.c -o jvd
$ $D6/gdb/gdb jvd
GNU gdb 2003-10-17-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 "i686-pc-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) break main
Breakpoint 1 at 0x8048324: file jvd.c, line 9.
(gdb) run
Starting program: /rigel/jimb/gdb/bugs/1433/jvd
Breakpoint 1, main () at jvd.c:9
9 s1.elvis = -1;
(gdb) disp s1
1: s1 = {elvis = 0, bruce = 0, jvd = 0 '\0'}
(gdb) step
10 s1.bruce = -1;
1: s1 = {elvis = -1, bruce = 0, jvd = 0 '\0'}
(gdb)
12 return s1.jvd == 0;
1: s1 = {elvis = -1, bruce = -1, jvd = 0 '\0'}
(gdb)
13 }
1: s1 = {elvis = -1, bruce = -1, jvd = 0 '\0'}
(gdb)
http://sources.redhat.com/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gdb&pr=1433
More information about the Gdb-prs
mailing list