Skip to content

DMD generates bad DWARF for static array return values #5583

Open
@dlangBugzillaToGithub

Description

@dlangBugzillaToGithub

Vladimir Panteleev reported this on 2024-11-28T07:22:49Z

Transferred from https://issues.dlang.org/show_bug.cgi?id=24888

Description

If an extern(C) function in a D program has a return value larger than 16 bytes, trying to call it and print its return value from gdb results in the error message "Too few arguments in function call.".

Reproducer:

cat > bug.d <<EOF
extern(C) auto a() { return (ubyte[16]).init; }
extern(C) auto b() { return (ubyte[17]).init; }
void main(){}
EOF

dmd -g bug

gdb -ex start \
	-ex 'echo === a() ===
' \
	-ex 'p a()' \
	-ex 'echo === b() ===
' \
	-ex 'p b()' \
	-ex 'stop' \
	-ex 'quit' \
	./bug

liushuyu on the gdb bugtracker ( https://sourceware.org/bugzilla/show_bug.cgi?id=30576 ) provided the following explanation:

> (In reply to Vladimir Panteleev from comment #2)
> > It still happens here. GDB 15.1, DMD v2.109.1.
> 
> Oh, I see now, you were using the DMD compiler.
> 
> After some investigations, I think it's a DMD bug. Here's the DWARF dump of
> the function bug.b():
> 
> 0x000000a9:   DW_TAG_subprogram
>                 DW_AT_sibling   (0x000000e7)
>                 DW_AT_MIPS_linkage_name ("b")
>                 DW_AT_type      (0x00000095 "ubyte[17]")
>                 DW_AT_external  (0x01)
>                 DW_AT_pure      (0x01)
>                 DW_AT_name      ("bug.b")
>                 DW_AT_decl_file ("/tmp/./bug.d")
>                 DW_AT_decl_line (2)
>                 DW_AT_decl_column       (16)
>                 DW_AT_low_pc    (0x0000000000042728)
>                 DW_AT_high_pc   (0x0000000000042754)
>                 DW_AT_frame_base        (0x0000004c:
>                    [0x0000000000042728, 0x0000000000042729): DW_OP_breg7
> RSP+8
>                    [0x0000000000042729, 0x000000000004272b): DW_OP_breg7
> RSP+16
>                    [0x000000000004272b, 0x0000000000042754): DW_OP_breg6
> RBP+16)
> 
> 0x000000d3:     DW_TAG_formal_parameter
>                   DW_AT_name    ("__HID1")
>                   DW_AT_type    (0x000000a4 "ubyte (*)[17]")
>                   DW_AT_artificial      (0x00)
>                   DW_AT_decl_file       ("/tmp/./bug.d")
>                   DW_AT_decl_line       (0)
>                   DW_AT_decl_column     (0)
>                   DW_AT_location        (DW_OP_fbreg -24)
> 
> It seems like DMD accidentally included the stack return argument in the
> debug data, which is incorrect (according to the DWARF v5 spec,
> DW_TAG_formal_parameter is only valid for parameters passing into the
> function, not implicit return values defined by ABI).
> 
> If the DWARF dump looks abstract the debug information describes
> the function as:
> 
> extern(C) ubyte[17] b(ubyte[17] __HID1);
> 
> So GDB thought you should pass something to the function.
> 
> In contrast, the GDC compiler wrote the debug information like this:
> 
> 0x00000184:   DW_TAG_subprogram
>                 DW_AT_external  (true)
>                 DW_AT_name      ("b")
>                 DW_AT_decl_file ("/tmp/bug.d")
>                 DW_AT_decl_line (2)
>                 DW_AT_decl_column       (16)
>                 DW_AT_type      (0x00000166 "ubyte[17]")
>                 DW_AT_low_pc    (0x00000000000251c9)
>                 DW_AT_high_pc   (0x00000000000251e6)
>                 DW_AT_frame_base        (DW_OP_call_frame_cfa)
>                 DW_AT_call_all_calls    (true)
> 
> Which is the correct definition for your bug.b function.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions