Debugging D code with GDB
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 ``` break _Dmain # break at D entry point 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
Re: Debugging D code with GDB
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
Re: Debugging D code with GDB
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 #!dmd -g 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.
Re: Debugging D code with GDB
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
Re: Debugging D code with GDB
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 ;)
Re: Debugging D code with GDB
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 ``` break _Dmain # break at D entry point 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.
Re: Debugging D code with GDB
On Sun, 2021-11-28 at 21:59 +, Iain Buclaw via Digitalmars-d-learn wrote: > 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 > > > > ``` > > > break _Dmain # break at D entry point > > > 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. 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. -- Sincerely, Luís Ferreira @ lsferreira.net signature.asc Description: This is a digitally signed message part
Re: Debugging D code with GDB
On Monday, 29 November 2021 at 14:48:21 UTC, Luís Ferreira wrote: On Sun, 2021-11-28 at 21:59 +, 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).
Re: Debugging D code with GDB
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!
Re: Debugging D code with GDB
On Tue, 2021-11-30 at 09:01 +, Iain Buclaw via Digitalmars-d-learn wrote: > On Monday, 29 November 2021 at 14:48:21 UTC, Luís Ferreira wrote: > > On Sun, 2021-11-28 at 21:59 +, 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?) > 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 ? -- Sincerely, Luís Ferreira @ lsferreira.net signature.asc Description: This is a digitally signed message part