[Issue 9800] Numerous issues with DWARF debug output

d-bugmail at puremagic.com d-bugmail at puremagic.com
Sun Dec 1 23:44:18 PST 2013


https://d.puremagic.com/issues/show_bug.cgi?id=9800



--- Comment #6 from Sarath Kumar Kodali <kodlists-dlang at yahoo.com> 2013-12-01 23:44:08 PST ---
All the problems listed are with DMD v2.6x when using -g switch. I have not
tried gdc or ldc, so cannot comment for them.

1. enum : type is not represented as DW_TAG_enumeration_type
2. enum values are not represented.

DWARF v2.0 (section 5.6, page 45) states that enum types is represented as
DW_TAG_enumeration_type and the enumeration literal as DW_TAG_enumerator. Each
enumerator value is represented with DW_AT_const_value attribute. 
DW_AT_const_value can be string, constant or block. However the standard says
only numeric constants are represented.

In DWARF v3.0, it is added that the enumeration type  can have DW_AT_type to
represent the type of underlying data type.

So with both V2 and V3, we can represent the enum info properly. I'm not sure
whether any debugger makes an assumption that enums will be only numeric values
with DWARF v2.0.

Due to non-representation of enums, gdb v7.5 complains that it is an incomplete
type and we cannot print its value using print command.

(gdb) p uiType
$2 = <incomplete type>
(gdb) p/x uiType
$3 = 0x0
(gdb) x/d &uiType
0xbfffed34:     1
(gdb)

3. arrays are represented as DW_TAG_structure_type instead of DW_TAG_array_type

dmd v2.64 emits DW_TAG_array_type for static arrays and "unsigned long long"
for dynamic arrays. string literal arrays are represented as
DW_TAG_structure_type.

There are advantages and disadvantages with representing arrays (static or
dynamic) as DW_TAG_structure_type or DW_TAG_array_type. The advantage with
DW_TAG_structure_type is that the @property fields of an array ("ptr" and
"length") become accessible from the debugger. But each element has to be
accessed separately like array.ptr[0]. With DW_TAG_array_type, all the array
values can be printed with "print array" command but .ptr and .length becomes
inaccessible. In any case, representing an array as "unsigned long long" is
plain wrong. BTW, gdb v7.5 is confused with DW_TAG_structure_type for string
literal array.

(gdb) list 5,5
5       auto names = [ "Foo", "Bar" ];
(gdb) p _D6dtypes5namesOAAya
$1 = {<error reading variable>, <error reading variable>, <error reading
variable>}
(gdb) ptype _D6dtypes5namesOAAya
type = struct _Array_uns long long {
    unsigned length;
    struct _Array_char *ptr;
}
(gdb) p _D6dtypes5namesOAAya.length
$2 = 3
(gdb) p _D6dtypes5namesOAAya.ptr
$3 = (struct _Array_char *) 0x8074b20
(gdb) p *_D6dtypes5namesOAAya.ptr
$4 = <error reading variable>
(gdb) ptype _D6dtypes5namesOAAya.ptr
type = struct _Array_char {
    unsigned length;
    char *ptr;
} *
(gdb) x/2s 0x8074b20
0x8074b20:      "Foo"
0x8074b24:      "Bar"


4. strings are represented as DW_TAG_base_type + DW_ATE_unsigned instead of
DW_TAG_string_type

DWARF v2.0 (section 5.8, page 46) states that "Fortran is one of the languages
that has a string type." That does not mean it was meant for only Fortran.

gdb v7.5 fails to recognize dmd strings.

below is the snapshot of gdb session. The D code is compiled with dmd -g. 

(gdb) l
101             }
102     }
103
104     int main(string[] args)
105     {
106             foreach (arg; args[1..$])
107             {
108                     if (!(arg == names[0] || arg == names[1]))
109                             return 1;
110             }
(gdb) s
108                     if (!(arg == names[0] || arg == names[1]))
(gdb) p arg
$1 = 13835042378651533313
(gdb)

6. DW_AT_external is set even for static types

That was a mistake, I meant "private" types. Module private variables &
functions and class private functions are represented as DW_AT_external

7. symbols within a module are not children of DW_TAG_module
8. module name should be removed from global symbols if they are made children
of module

Dwarf v2.0.0 has DW_TAG_module (section 3.2, page 25). Again the standard does
not say that this is for Modula2 language only. Using this tag, one could
represent D module "static this()" functions as module initialization code
using DW_AT_low_pc and DW_AT_high_pc as described in the spec.

Dwarf v3.0 further enhanced this and allowed multiple initialization codes per
module.

While this is getting fixed, the compiler should also emit
"TAG_imported_module" for module imports.

9. classes are represented as DW_TAG_structure_type instead of
DW_TAG_class_type
10. member functions are not represented as children of the aggregate, stuct or
class

I'm not sure in what way DW_TAG_interface_type is useful for debugging. I will
have to write some interfaces and check.

11. DW_AT_linkage_name should be used instead of DW_AT_MIPS_linkage_name

True, DW_AT_linkage_name is defined in DWARF v3.0. This is only a compliance
issue and does not affect debugging with gdb.

12. DW_TAG_decl_file and DW_TAG_decl_line are not produced for any symbol other
than DW_TAG_subprogram
13. For reference types DW_TAG_pointer_type is used instead of
DW_TAG_reference_type

Again, this is an issues for DMD v2.64. GCC does the right thing, so I would
expect GDC also does the right thing - I have not checked GDC though.

14. C type names are produced for DW_TAG_base_type instead of D type names (eg.
_Bool, wchar_t, unsigned char)

This is a  huge issue, as the debugger does not understand D basic types bool,
ulong, uint, ushort etc

15. string, wstring and dstring are all represented as same type, i.e.
"unsigned long long"

The D ABI states that when -gc switch is used "unsigned long long" is emitted
for dynamic array. Since TAG_string_type exists since DWARF 2.0, it should be
emitted for strings instead of treating them as dynamic arrays.

16. Annonymous unions are not represented.

This is a minor issue as this only affects while pretty printing the value of
an aggregate by the debugger. The anonymous union members are shown as members
of the container of union.

17. aliases are not represented.

Like #2, this is irritating while debugging.

20. @property is not represented. Maybe we can use DW_AT_elemental ???

I agree, DW_AT_elemental is a wrong choice for @property. Anyway, this and #19
(AT_pure) are low priority and there is no debugger support for these.

21. DW_AT_main_subprogram should be emitted for _Dmain, so that the debugger
knows that it is the starting function instead of main()

Below is gdb v7.5 session with code compiled with "dmd -g" or "dmd -gc"

gdb -q ./dtypes
Reading symbols from dtypes...done.
(gdb) start
[skip]
Temporary breakpoint 1, 0x08060313 in main ()
(gdb)
 bt
#0  0x08060313 in main ()
(gdb) tbreak _Dmain
Temporary breakpoint 2 at 0x80600c1: file dtypes.d, line 106.
(gdb) c
Continuing.

Temporary breakpoint 2, _Dmain (args=13835038538950770689) at dtypes.d:106
106             foreach (arg; args[1..$])
(gdb)

As can be seen, gdb thinks "main" is the start function instead of _Dmain.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list