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() ===\n' \ -ex 'p a()' \ -ex 'echo === b() ===\n' \ -ex 'p b()' \ -ex 'stop' \ -ex 'quit' \ ./bug
I think this has been fixed (I am using GDB 15): gdb --batch -x bug.gdb ./bug1 Temporary breakpoint 1 at 0x251ea: file bug.d, line 3. [Thread debugging using libthread_db enabled] Using host libthread_db library "/usr/lib/libthread_db.so.1". Temporary breakpoint 1, D main () at bug.d:3 3 void main(){} === a() === $1 = '\000' <repeats 15 times> === b() === $2 = '\000' <repeats 16 times> A debugging session is active. Inferior 1 [process 681157] will be killed. Quit anyway? (y or n) [answered Y; input not from terminal]
It still happens here. GDB 15.1, DMD v2.109.1.
(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 return values). If the DWARF dump looks abstract, basically, 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.
(In reply to liushuyu from comment #3) > (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.
Thank you, DMD bug filed: https://issues.dlang.org/show_bug.cgi?id=24888