www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Debugging D code with GDB

reply Eduard Staniloiu <edi33416 gmail.com> writes:
Hello,

I'm trying to use `gdb` to debug D binaries, but I'm having 
trouble accessing the methods of a struct or class. It seems that 
`gdb` doesn't see them.

Given the following simple example
```
// test.d
struct S
{
     int x;

     void myPrint() { writefln("x is %s\n", x); }
}

void main(string[] args)
{
     S s;
}
```
Compile the source file with debug simbols (`dmd -g test.d 
-of=test`) and open the binary with gdb (`gdb test`) and run the 
following

```

 run
 ptype s
type = struct test.S { int x; }
 print s.myPrint()
Structure has no component named myPrint. ``` As you can see, when I try to access the `myPrint()` method I get the error "Structure has no component named myPrint." Looking up gdb's bugzilla, I've found this issue [0] that basically says that gdb treats D as C code (and that would explain why it doesn't look for function definitions inside D structs). A simple "fix"/"hack" to this problem is to define a helper function that will take my symbol as a parameter and internally call the function that I need, like below: ``` extern (C) void helper(ref S s) { s.myPrint(); } ``` While this does the job for this trivial example, it doesn't scale for a real project. Are there any solutions to this problem? Looking forward to your answers, Edi [0] - https://sourceware.org/bugzilla/show_bug.cgi?id=22480
Nov 27 2021
next sibling parent Alexey <animuspexus protonmail.com> writes:
I found what Nemiver is much better for debugging D programs. 
With GDB I've got many problems, don't remember exactly. Thou 
I've used it through ddd, so maybe it's ddd problems, not exactly 
GDB's
Nov 27 2021
prev sibling next sibling parent reply user1234 <user1234 12.de> writes:
On Saturday, 27 November 2021 at 14:17:11 UTC, Eduard Staniloiu 
wrote:
 Hello,

 I'm trying to use `gdb` to debug D binaries, but I'm having 
 trouble accessing the methods of a struct or class. It seems 
 that `gdb` doesn't see them.

 [...]

 Looking forward to your answers,
 Edi

 [0] - https://sourceware.org/bugzilla/show_bug.cgi?id=22480
Hello, while I never evaluate calls during debugging I've managed to find a way : you can call the mangled name so for ```d module a; import std.stdio; struct S { int myPrint(){return 8;} } pragma(msg, S.myPrint.mangleof); int main(string[] args) { S s; return 0; } ``` in gdb CLI ```bash p (int) _D1a1S7myPrintMFZi(s) $1 = 8 ``` works. Note that for some reasons writefln causes a crash, that's why I've modified the example. The problem is that my workaround does not scale better than your.
Nov 28 2021
parent reply russhy <russhy gmail.com> writes:
On Sunday, 28 November 2021 at 14:53:17 UTC, user1234 wrote:
 ...
there is a plugin to demangle things automatically https://github.com/ANtlord/gdb-ddemangle
Nov 28 2021
parent user1234 <user1234 12.de> writes:
On Sunday, 28 November 2021 at 16:44:38 UTC, russhy wrote:
 On Sunday, 28 November 2021 at 14:53:17 UTC, user1234 wrote:
 ...
there is a plugin to demangle things automatically https://github.com/ANtlord/gdb-ddemangle
That's off-topic. The point here is that you can (unfortunately) **only** evaluate the call using the mangled form, it's not about transforming the output. Actually what would be useful is a plugin the mangle the call in custom expression before passing it to gdb ;)
Nov 28 2021
prev sibling parent reply Iain Buclaw <ibuclaw gdcproject.org> writes:
On Saturday, 27 November 2021 at 14:17:11 UTC, Eduard Staniloiu 
wrote:
 Hello,

 I'm trying to use `gdb` to debug D binaries, but I'm having 
 trouble accessing the methods of a struct or class. It seems 
 that `gdb` doesn't see them.

 Given the following simple example
 ```
 // test.d
 struct S
 {
     int x;

     void myPrint() { writefln("x is %s\n", x); }
 }

 void main(string[] args)
 {
     S s;
 }
 ```
 Compile the source file with debug simbols (`dmd -g test.d 
 -of=test`) and open the binary with gdb (`gdb test`) and run 
 the following

 ```

 run
 ptype s
type = struct test.S { int x; }
 print s.myPrint()
Structure has no component named myPrint. ``` As you can see, when I try to access the `myPrint()` method I get the error "Structure has no component named myPrint."
DMD doesn't emit this information. GDB can't work miracles when the compiler isn't pulling its own weight.
Nov 28 2021
parent reply =?ISO-8859-1?Q?Lu=EDs?= Ferreira <contact lsferreira.net> writes:
On Sun, 2021-11-28 at 21:59 +0000, Iain Buclaw via Digitalmars-d-learn
wrote:
 On Saturday, 27 November 2021 at 14:17:11 UTC, Eduard Staniloiu=20
 wrote:
 Hello,
=20
 I'm trying to use `gdb` to debug D binaries, but I'm having=20
 trouble accessing the methods of a struct or class. It seems=20
 that `gdb` doesn't see them.
=20
 Given the following simple example
 ```
 // test.d
 struct S
 {
 =C2=A0=C2=A0=C2=A0 int x;
=20
 =C2=A0=C2=A0=C2=A0 void myPrint() { writefln("x is %s\n", x); }
 }
=20
 void main(string[] args)
 {
 =C2=A0=C2=A0=C2=A0 S s;
 }
 ```
 Compile the source file with debug simbols (`dmd -g test.d=20
 -of=3Dtest`) and open the binary with gdb (`gdb test`) and run=20
 the following
=20
 ```

 run
 ptype s
type =3D struct test.S { =C2=A0=C2=A0=C2=A0 int x; }
 print s.myPrint()
Structure has no component named myPrint. ``` =20 As you can see, when I try to access the `myPrint()` method I=20 get the error "Structure has no component named myPrint." =20
=20 DMD doesn't emit this information. GDB can't work miracles when=20 the compiler isn't pulling its own weight.
I confirm this is an issue with DMD. I filed a bug in the issue tracker, in case you want to follow: https://issues.dlang.org/show_bug.cgi?id=3D22551 Anyway, DMD exports the symbol, it should work if you do something like `myPrint(&s)`, but I think there is another problem on calling it, due to defective calling convention on both DMD and LDC implementations. LDC exports the symbol correctly, although. --=20 Sincerely, Lu=C3=ADs Ferreira lsferreira.net
Nov 29 2021
parent reply Iain Buclaw <ibuclaw gdcproject.org> writes:
On Monday, 29 November 2021 at 14:48:21 UTC, Luís Ferreira wrote:
 On Sun, 2021-11-28 at 21:59 +0000, Iain Buclaw via 
 Digitalmars-d-learn wrote:
 
 DMD doesn't emit this information. GDB can't work miracles 
 when the compiler isn't pulling its own weight.
I confirm this is an issue with DMD. I filed a bug in the issue tracker, in case you want to follow: https://issues.dlang.org/show_bug.cgi?id=22551 Anyway, DMD exports the symbol, it should work if you do something like `myPrint(&s)`, but I think there is another problem on calling it, due to defective calling convention on both DMD and LDC implementations. LDC exports the symbol correctly, although.
Indeed, gdb assumes calling convention is same as default for target (actually its been years since I last looked, but are calling conventions tags in dwarf? Does gdb know about functions with thiscall or regparm attributes?) Another thing on the gdb side, it is currently missing D language support for overloads, so that the correct function would be picked when you call e.g std.math.sin(1f).
Nov 30 2021
next sibling parent Eduard Staniloiu <edi33416 gmail.com> writes:
On Tuesday, 30 November 2021 at 09:01:38 UTC, Iain Buclaw wrote:
 On Monday, 29 November 2021 at 14:48:21 UTC, Luís Ferreira 
 wrote:
 [...]
Indeed, gdb assumes calling convention is same as default for target (actually its been years since I last looked, but are calling conventions tags in dwarf? Does gdb know about functions with thiscall or regparm attributes?) Another thing on the gdb side, it is currently missing D language support for overloads, so that the correct function would be picked when you call e.g std.math.sin(1f).
So currently the workaround is they way to go. Thank you all for your help and suggestions!
Dec 02 2021
prev sibling parent =?ISO-8859-1?Q?Lu=EDs?= Ferreira <contact lsferreira.net> writes:
On Tue, 2021-11-30 at 09:01 +0000, Iain Buclaw via Digitalmars-d-learn
wrote:
 On Monday, 29 November 2021 at 14:48:21 UTC, Lu=C3=ADs Ferreira wrote:
 On Sun, 2021-11-28 at 21:59 +0000, Iain Buclaw via=20
 Digitalmars-d-learn wrote:
=20
 DMD doesn't emit this information. GDB can't work miracles=20
 when the compiler isn't pulling its own weight.
=20 I confirm this is an issue with DMD. I filed a bug in the issue=20 tracker, in case you want to follow:=20 https://issues.dlang.org/show_bug.cgi?id=3D22551 =20 Anyway, DMD exports the symbol, it should work if you do=20 something like `myPrint(&s)`, but I think there is another=20 problem on calling it, due to defective calling convention on=20 both DMD and LDC implementations. =20 LDC exports the symbol correctly, although.
=20 Indeed, gdb assumes calling convention is same as default for=20 target (actually its been years since I last looked, but are=20 calling conventions tags in dwarf? Does gdb know about functions=20 with thiscall or regparm attributes?) =20
Yes, it is specified in 7.15. Calling Convention Encodings in DWARF standard. You can use DW_AT_calling_convention attribute to specify a certain calling convention, being DW_CC_normal the default value. But you have very limited number of calling conventions available, being the rest considered vendor-specific. You might want DW_CC_BORLAND_thiscall ? --=20 Sincerely, Lu=C3=ADs Ferreira lsferreira.net
Jan 04 2022