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.dhttp://people.freebsd.org/~nox/tmp/d/lzma.d
Comment #3 by bugs-puremagic — 2010-09-14T11:06:33Z
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)