digitalmars.D - Stack tracing on Linux ?
- Georg Wrede (60/60) Apr 02 2009 With gdb I can either debug a core dump or an actual running process.
- Simon Gomizelj (26/86) Apr 03 2009 While I can't explain why gdb and dmd don't seem to work nicely together...
- Georg Wrede (4/111) Apr 02 2009 Ah, this looks nice. And the file name shows in the function names.
- Fawzi Mohamed (5/118) Apr 03 2009 you are right, on mac with dmd I get the full trace, on linux not.
- Walter Bright (3/6) Apr 03 2009 You can see using dumpobj -p on the object files that dmd *does* put in
- Fawzi Mohamed (4/11) Apr 03 2009 then the correct statement is that libbdf is not able to interpret that
- Walter Bright (3/6) Apr 03 2009 Right. I just don't know what is wrong with it. It appears to be correct...
- Fawzi Mohamed (17/95) Apr 02 2009 Well inlined functions will have no frame, also last call optimization
- Georg Wrede (16/32) Apr 02 2009 If I were to write a compiler, then using "-g -debug", etc. would make
- Sean Kelly (5/13) Apr 02 2009 The Tango plugin architecture for backtrace was designed so that the
- Fawzi Mohamed (9/23) Apr 03 2009 having some stacktracing by default there was the number one request at
- =?ISO-8859-1?Q?=22J=E9r=F4me_M=2E_Berger=22?= (17/43) Apr 04 2009 -----BEGIN PGP SIGNED MESSAGE-----
- Christopher Wright (4/10) Apr 03 2009 However, closures in D1 have a stack frame that is within the creating
- Fawzi Mohamed (2/13) Apr 03 2009 Now this is more clear, thanks!
- Georg Wrede (5/20) Apr 10 2009 If the current D closure architecture is considered stable and
With gdb I can either debug a core dump or an actual running process. For example, with import std.stdio; int main() { readWrite(); return 8; } void readWrite() { auto line = readln(); // here it waits, and that's when I debug // in another window write("Rivi oli: ", line); } I get the following stack trace (it looks the same whether I debug a core dump or a running instance) delimiter=10, fp=0x62e420) at iogetdelim.c:79 This is not perfect, 5..7 are functions written in D, but main is missing. Then, trying to examine a core dump from something that gets a segfault, I wrote the following, expecting that I'd get a grandiose stack trace $ cat npe.d import std.stdio; int main() { return foo(3); } int foo(int a) { return 1 + bar(a - 3); } int bar(int b) { return 1 + car(b - 3); } int car(int c) { return 1 + dar(c - 3); } int dar(int d) { return 1 + * cast(int*) d; // null pointer exception } Turns out I got zilch! I have DMD on Fedora 10, and used dmd -g -debug -v read2.d to compile. Incidentally, using dmd -gc -debug -v read2.d does seem to give the same stack trace.
Apr 02 2009
On Thu, 02 Apr 2009 04:56:46 -0400, Georg Wrede <georg.wrede iki.fi> wrote:With gdb I can either debug a core dump or an actual running process. For example, with import std.stdio; int main() { readWrite(); return 8; } void readWrite() { auto line = readln(); // here it waits, and that's when I debug // in another window write("Rivi oli: ", line); } I get the following stack trace (it looks the same whether I debug a core dump or a running instance) delimiter=10, fp=0x62e420) at iogetdelim.c:79 This is not perfect, 5..7 are functions written in D, but main is missing. Then, trying to examine a core dump from something that gets a segfault, I wrote the following, expecting that I'd get a grandiose stack trace $ cat npe.d import std.stdio; int main() { return foo(3); } int foo(int a) { return 1 + bar(a - 3); } int bar(int b) { return 1 + car(b - 3); } int car(int c) { return 1 + dar(c - 3); } int dar(int d) { return 1 + * cast(int*) d; // null pointer exception } Turns out I got zilch! I have DMD on Fedora 10, and used dmd -g -debug -v read2.d to compile. Incidentally, using dmd -gc -debug -v read2.d does seem to give the same stack trace.While I can't explain why gdb and dmd don't seem to work nicely together, you'd have much better luck using ldc. Compiling with ldc, this is the backtrace I got when debugging read2.d on my maching (and is what you're probably looking for): (gdb) run Starting program: /data/Code/D/error [Thread debugging using libthread_db enabled] [New Thread 0xb7d656c0 (LWP 14104)] Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 0xb7d656c0 (LWP 14104)] 0x080495fe in _D5error3darFiZi (d=-6) at error.d:23 23 return 1 + * cast(int*) d; // null pointer exception (gdb) backtrace -- Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Apr 03 2009
Simon Gomizelj wrote:On Thu, 02 Apr 2009 04:56:46 -0400, Georg Wrede <georg.wrede iki.fi> wrote:Ah, this looks nice. And the file name shows in the function names. If everyone wasn't telling me it's a licence issue, I'd take it for granted there's a bug in DMD.With gdb I can either debug a core dump or an actual running process. For example, with import std.stdio; int main() { readWrite(); return 8; } void readWrite() { auto line = readln(); // here it waits, and that's when I debug // in another window write("Rivi oli: ", line); } I get the following stack trace (it looks the same whether I debug a core dump or a running instance) delimiter=10, fp=0x62e420) at iogetdelim.c:79 This is not perfect, 5..7 are functions written in D, but main is missing. Then, trying to examine a core dump from something that gets a segfault, I wrote the following, expecting that I'd get a grandiose stack trace $ cat npe.d import std.stdio; int main() { return foo(3); } int foo(int a) { return 1 + bar(a - 3); } int bar(int b) { return 1 + car(b - 3); } int car(int c) { return 1 + dar(c - 3); } int dar(int d) { return 1 + * cast(int*) d; // null pointer exception } Turns out I got zilch! I have DMD on Fedora 10, and used dmd -g -debug -v read2.d to compile. Incidentally, using dmd -gc -debug -v read2.d does seem to give the same stack trace.While I can't explain why gdb and dmd don't seem to work nicely together, you'd have much better luck using ldc. Compiling with ldc, this is the backtrace I got when debugging read2.d on my maching (and is what you're probably looking for): (gdb) run Starting program: /data/Code/D/error [Thread debugging using libthread_db enabled] [New Thread 0xb7d656c0 (LWP 14104)] Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 0xb7d656c0 (LWP 14104)] 0x080495fe in _D5error3darFiZi (d=-6) at error.d:23 23 return 1 + * cast(int*) d; // null pointer exception (gdb) backtrace
Apr 02 2009
On 2009-04-02 20:51:26 +0200, Georg Wrede <georg.wrede iki.fi> said:Simon Gomizelj wrote:No the license issue is just for including this in tangoOn Thu, 02 Apr 2009 04:56:46 -0400, Georg Wrede <georg.wrede iki.fi> wrote:Ah, this looks nice. And the file name shows in the function names. If everyone wasn't telling me it's a licence issue,With gdb I can either debug a core dump or an actual running process. For example, with import std.stdio; int main() { readWrite(); return 8; } void readWrite() { auto line = readln(); // here it waits, and that's when I debug // in another window write("Rivi oli: ", line); } I get the following stack trace (it looks the same whether I debug a core dump or a running instance) delimiter=10, fp=0x62e420) at iogetdelim.c:79 This is not perfect, 5..7 are functions written in D, but main is missing. Then, trying to examine a core dump from something that gets a segfault, I wrote the following, expecting that I'd get a grandiose stack trace $ cat npe.d import std.stdio; int main() { return foo(3); } int foo(int a) { return 1 + bar(a - 3); } int bar(int b) { return 1 + car(b - 3); } int car(int c) { return 1 + dar(c - 3); } int dar(int d) { return 1 + * cast(int*) d; // null pointer exception } Turns out I got zilch! I have DMD on Fedora 10, and used dmd -g -debug -v read2.d to compile. Incidentally, using dmd -gc -debug -v read2.d does seem to give the same stack trace.While I can't explain why gdb and dmd don't seem to work nicely together, you'd have much better luck using ldc. Compiling with ldc, this is the backtrace I got when debugging read2.d on my maching (and is what you're probably looking for): (gdb) run Starting program: /data/Code/D/error [Thread debugging using libthread_db enabled] [New Thread 0xb7d656c0 (LWP 14104)] Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 0xb7d656c0 (LWP 14104)] 0x080495fe in _D5error3darFiZi (d=-6) at error.d:23 23 return 1 + * cast(int*) d; // null pointer exception (gdb) backtraceI'd take it for granted there's a bug in DMD.you are right, on mac with dmd I get the full trace, on linux not. About the missing line and file information I think dmd does not add that on mac/linux.
Apr 03 2009
Fawzi Mohamed wrote:you are right, on mac with dmd I get the full trace, on linux not. About the missing line and file information I think dmd does not add that on mac/linux.You can see using dumpobj -p on the object files that dmd *does* put in the information.
Apr 03 2009
On 2009-04-03 10:33:19 +0200, Walter Bright <newshound1 digitalmars.com> said:Fawzi Mohamed wrote:then the correct statement is that libbdf is not able to interpret that information correctly, because both on mac and on linux gdb and addr2line are not able to use ityou are right, on mac with dmd I get the full trace, on linux not. About the missing line and file information I think dmd does not add that on mac/linux.You can see using dumpobj -p on the object files that dmd *does* put in the information.
Apr 03 2009
Fawzi Mohamed wrote:then the correct statement is that libbdf is not able to interpret that information correctly, because both on mac and on linux gdb and addr2line are not able to use itRight. I just don't know what is wrong with it. It appears to be correct according to the dwarf spec.
Apr 03 2009
Well inlined functions will have no frame, also last call optimization (tail optimization) removes the frame. the backtrace typically gets the return address (i.e. the adress of the next instruction, not of the calling instruction). Normally the code tries to guess the calling instruction as the one before the return instruction, but it does not always work. So one has to expect that the backtrace might miss some frames. But normally this is not a problem. The tracing of tango svn version (that uses libc backtrace) seems to work rather well. It does not give you the names, but as said that is due to a license problem. gdb uses the same tools (and libbdf), that as jive has shown works well (but is GPL). So I think that things are working as expected, even if maybe not as you would like :) Fawzi On 2009-04-02 10:56:46 +0200, Georg Wrede <georg.wrede iki.fi> said:With gdb I can either debug a core dump or an actual running process. For example, with import std.stdio; int main() { readWrite(); return 8; } void readWrite() { auto line = readln(); // here it waits, and that's when I debug // in another window write("Rivi oli: ", line); } I get the following stack trace (it looks the same whether I debug a core dump or a running instance) delimiter=10, fp=0x62e420) at iogetdelim.c:79 This is not perfect, 5..7 are functions written in D, but main is missing. Then, trying to examine a core dump from something that gets a segfault, I wrote the following, expecting that I'd get a grandiose stack trace $ cat npe.d import std.stdio; int main() { return foo(3); } int foo(int a) { return 1 + bar(a - 3); } int bar(int b) { return 1 + car(b - 3); } int car(int c) { return 1 + dar(c - 3); } int dar(int d) { return 1 + * cast(int*) d; // null pointer exception } Turns out I got zilch! I have DMD on Fedora 10, and used dmd -g -debug -v read2.d to compile. Incidentally, using dmd -gc -debug -v read2.d does seem to give the same stack trace.
Apr 02 2009
Fawzi Mohamed wrote:Well inlined functions will have no frame, also last call optimization (tail optimization) removes the frame.If I were to write a compiler, then using "-g -debug", etc. would make sure neither happens!the backtrace typically gets the return address (i.e. the adress of the next instruction, not of the calling instruction). Normally the code tries to guess the calling instruction as the one before the return instruction, but it does not always work.A first idea is to have the compiler insert a few NOPs when compiling with -debug, but then again if it were that easy, somebody else would've thought of it already.So one has to expect that the backtrace might miss some frames. But normally this is not a problem.While I've seldom needed debuggin tools or stack tracing, I can imagine they're indispensable for people who have to quickly fix others' code. I guess most folks here, especially Walter(?) really do most of their coding on "new" and "own" things, where there's less need for such? But in a busy corporate environment with dozens of coders on the project, and people having to debug (or actually ending up because the called function doesn't work right) each other's code, it's different.The tracing of tango svn version (that uses libc backtrace) seems to work rather well. It does not give you the names, but as said that is due to a license problem.Aarrghhh. What most frustrates me is when something obvious can't be done because of external trivialities.gdb uses the same tools (and libbdf), that as jive has shown works well (but is GPL). So I think that things are working as expected, even if maybe not as you would like :)It's a shame.
Apr 02 2009
== Quote from Georg Wrede (georg.wrede iki.fi)'s articleFawzi Mohamed wrote:The Tango plugin architecture for backtrace was designed so that the backtrace code doesn't have to be integrated into Tango itself, eliminating the license problem. But I can see how this might be a problem if you want to bundle a backtrace library with Tango :-)The tracing of tango svn version (that uses libc backtrace) seems to work rather well. It does not give you the names, but as said that is due to a license problem.Aarrghhh. What most frustrates me is when something obvious can't be done because of external trivialities.
Apr 02 2009
On 2009-04-02 21:18:55 +0200, Sean Kelly <sean invisibleduck.org> said:== Quote from Georg Wrede (georg.wrede iki.fi)'s articlehaving some stacktracing by default there was the number one request at the tango reference, and also in the wish list for a while. The idea is not to disallow external solutions, but to have something working there by default. Please note that something using GPL code even as plugin forces the whole application to be GPL, which is not acceptable for anyone not wanting to release its application as GPL. FawziFawzi Mohamed wrote:The Tango plugin architecture for backtrace was designed so that the backtrace code doesn't have to be integrated into Tango itself, eliminating the license problem. But I can see how this might be a problem if you want to bundle a backtrace library with Tango :-)The tracing of tango svn version (that uses libc backtrace) seems to work rather well. It does not give you the names, but as said that is due to a license problem.Aarrghhh. What most frustrates me is when something obvious can't be done because of external trivialities.
Apr 03 2009
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Fawzi Mohamed wrote:On 2009-04-02 21:18:55 +0200, Sean Kelly <sean invisibleduck.org> said:The glibc has functions for stack tracing (backtrace and backtrace_symbols) and it's licensed under the LGPL, so there should be no problem... Jerome - -- mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEARECAAYFAknXbuQACgkQd0kWM4JG3k8AxQCeOws+fxLtAa0wbZ0YDiVgFyaQ ht4AoLODMa7nV9eNtyRKoDbqrymcJcPQ =BzNy -----END PGP SIGNATURE-----== Quote from Georg Wrede (georg.wrede iki.fi)'s articlehaving some stacktracing by default there was the number one request at the tango reference, and also in the wish list for a while. The idea is not to disallow external solutions, but to have something working there by default. Please note that something using GPL code even as plugin forces the whole application to be GPL, which is not acceptable for anyone not wanting to release its application as GPL.Fawzi Mohamed wrote:The Tango plugin architecture for backtrace was designed so that the backtrace code doesn't have to be integrated into Tango itself, eliminating the license problem. But I can see how this might be a problem if you want to bundle a backtrace library with Tango :-)The tracing of tango svn version (that uses libc backtrace) seems to work rather well. It does not give you the names, but as said that is due to a license problem.Aarrghhh. What most frustrates me is when something obvious can't be done because of external trivialities.
Apr 04 2009
Georg Wrede wrote:Fawzi Mohamed wrote:However, closures in D1 have a stack frame that is within the creating function's stack frame, and gdb assumes that means a corrupt stack. There's no real way around this.Well inlined functions will have no frame, also last call optimization (tail optimization) removes the frame.If I were to write a compiler, then using "-g -debug", etc. would make sure neither happens!
Apr 03 2009
On 2009-04-03 19:24:25 +0200, Christopher Wright <dhasenan gmail.com> said:Georg Wrede wrote:Now this is more clear, thanks!Fawzi Mohamed wrote:However, closures in D1 have a stack frame that is within the creating function's stack frame, and gdb assumes that means a corrupt stack. There's no real way around this.Well inlined functions will have no frame, also last call optimization (tail optimization) removes the frame.If I were to write a compiler, then using "-g -debug", etc. would make sure neither happens!
Apr 03 2009
Fawzi Mohamed wrote:On 2009-04-03 19:24:25 +0200, Christopher Wright <dhasenan gmail.com> said:If the current D closure architecture is considered stable and permanent, then maybe the gdb or glibc folks might want to look at it? And while at it, they'd probably know right off the bat what seems to be the problem with D stack traces not currently showing properly.Georg Wrede wrote:Now this is more clear, thanks!Fawzi Mohamed wrote:However, closures in D1 have a stack frame that is within the creating function's stack frame, and gdb assumes that means a corrupt stack. There's no real way around this.Well inlined functions will have no frame, also last call optimization (tail optimization) removes the frame.If I were to write a compiler, then using "-g -debug", etc. would make sure neither happens!
Apr 10 2009