Bug 4863 – DWARF debug symbols treat arrays as unsigned long long

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
x86
OS
FreeBSD
Creation time
2010-09-13T15:34:00Z
Last change time
2012-01-31T14:06:15Z
Assigned to
nobody
Creator
bugs-puremagic
Blocks
4044

Attachments

IDFilenameSummaryContent-TypeSize
756argsfoo.dreduced testcase that exhibits the bugtext/plain97

Comments

Comment #0 by bugs-puremagic — 2010-09-13T15:34:38Z
(I haven't checked if this also affects D1, and it probably also affects non-FreeBSD *ixes at least.) I tested both gdb head (checked out after the D patches went in) and Doug Rabson's D-aware debugger ngdb which he annouced as a 'Technology Preview' here: http://lists.freebsd.org/pipermail/freebsd-current/2009-August/011071.html ..and found two things: a) gdb still chokes on dmd -g debug symbols because the D DWARF extensions conflict with DWARF-4: http://d.puremagic.com/issues/show_bug.cgi?id=4180 disabling the DW_TAG_type_unit case in gdb/dwarf2read.c at least makes it no longer complain: http://people.freebsd.org/~nox/tmp/d/d-gdb-dwarf2read.c.patch b) both debuggers treat arrays as unsigned long long (like main()'s standard string[] args) - at least ngdb prints them correctly if I do a manual cast: (ngdb) p *cast(char [][] *)&args I then looked at the debug symbols using readelf -w and found it's actually dmd's fault not the debugger's, the array really seems to be marked as the unsigned long long type: <1><a4>: Abbrev Number: 3 (DW_TAG_base_type) DW_AT_name : unsigned long long DW_AT_byte_size : 8 DW_AT_encoding : 7 (unsigned) .. <2><516>: Abbrev Number: 5 (DW_TAG_formal_parameter) DW_AT_name : args DW_AT_type : <a4> DW_AT_location : 2 byte block: 91 8 (DW_OP_fbreg: 8)
Comment #1 by nfxjfg — 2010-09-13T19:10:50Z
I think dmd uses ulong for arrays internally. All the array runtime functions in lifetime.d (Tango/druntime) actually return array descriptors as ulong!
Comment #2 by bugs-puremagic — 2010-09-14T10:31:30Z
Maybe I was not clear :) The problem is this: % dmd -w -g xzj.d lzma/lzma.d -L-llzma % grep main.\*args xzj.d void main(string[] args) % ngdb.new ./xzj (ngdb) b _Dmain Id Enb Address Where 1 y 0x804a077 D main(unsigned long long args): xzj.d:256 ^^^^^^^^^^^^^^^^^^^^^^^ (ngdb) r foo bar Stopped at breakpoint 1 D main(args=2895955435326537731): xzj.d:256 ^^^^^^^^^^^^^^^^^^^^ => 259* // --debug (ngdb) p *cast(char [][] *)&args $0 = (char[][]) ["./xzj", "foo", "bar"] (ngdb) q (same with the patched gdb only that doesn't understand the cast.) And meanwhile I found out this doesn't happen always: % cat args.d import std.stdio; void main(string[] args) { foreach(arg; args) writeln(arg); } % dmd -g -w args.d % ngdb.new ./args (ngdb) b _Dmain Id Enb Address Where 1 y 0x80491fb D main(char[][] args): args.d:5 (ngdb) r foo bar Stopped at breakpoint 1 D main(args=["./args", "foo", "bar"]): args.d:5 => 5* foreach(arg; args) (ngdb) q So now I probably should extract the most simple testcase that exhibits the bug, I haven't done that yet so for now here are links to the xzj source: http://people.freebsd.org/~nox/tmp/d/xzj.d http://people.freebsd.org/~nox/tmp/d/lzma.d
Comment #3 by bugs-puremagic — 2010-09-14T11:06:33Z
And btw I can confirm Linux is affected too: % readelf -w linux/xzj .. <1><6bb>: Abbrev Number: 3 (DW_TAG_base_type) DW_AT_name : unsigned long long DW_AT_byte_size : 8 DW_AT_encoding : 7 (unsigned) .. <2><11c1>: Abbrev Number: 6 (DW_TAG_formal_parameter) DW_AT_name : args DW_AT_type : <6bb> DW_AT_location : 2 byte block: 91 8 (DW_OP_fbreg: 8) vs. % readelf -w linux/args <1><62>: Abbrev Number: 3 (DW_TAG_base_type) DW_AT_name : char DW_AT_byte_size : 1 DW_AT_encoding : 8 (unsigned char) <1><6a>: Abbrev Number: 4 (Unknown TAG value: 41) DW_AT_byte_size : 8 DW_AT_type : <62> <1><70>: Abbrev Number: 4 (Unknown TAG value: 41) DW_AT_byte_size : 8 DW_AT_type : <6a> .. <2><a5>: Abbrev Number: 5 (DW_TAG_formal_parameter) DW_AT_name : args DW_AT_type : <70> DW_AT_location : 2 byte block: 91 8 (DW_OP_fbreg: 8) I've put the binaries here: http://people.freebsd.org/~nox/tmp/d/linux/xzj http://people.freebsd.org/~nox/tmp/d/linux/args
Comment #4 by bugs-puremagic — 2010-09-14T15:48:14Z
Created attachment 756 reduced testcase that exhibits the bug Ok I have a minmal testcase now, all it took was a local variable: % readelf -w linux/argsfoo .. <1><7c>: Abbrev Number: 3 (DW_TAG_base_type) DW_AT_name : unsigned long long DW_AT_byte_size : 8 DW_AT_encoding : 7 (unsigned) .. <2><c1>: Abbrev Number: 5 (DW_TAG_formal_parameter) DW_AT_name : args DW_AT_type : <7c> DW_AT_location : 2 byte block: 91 8 (DW_OP_fbreg: 8)