D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 5118 - Stack traces should properly handle nested functions
Summary: Stack traces should properly handle nested functions
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: druntime (show other issues)
Version: D2
Hardware: Other Linux
: P2 normal
Assignee: Sean Kelly
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2010-10-25 14:40 UTC by David Simcha
Modified: 2016-10-20 11:38 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description David Simcha 2010-10-25 14:40:26 UTC
When an exception causes a stack trace to be printed on Linux, only top-level functions are shown.  If nested functions are to become idiomatic D style (I use them a ton) then nested functions should be printed as well.  Test case:

void main() {
    doIt();
}

void doIt() {
    void nested() {
         throw new Exception("Test.");
    }

    nested();
}

Stack trace:

object.Exception: Test.
----------------
./test(void test.doIt()) [0x8057cf9]
./test(_Dmain+0x8) [0x8057ccc]
./test(extern (C) int rt.dmain2.main(int, char**)) [0x805a456]
./test(extern (C) int rt.dmain2.main(int, char**)) [0x805a3b0]
./test(extern (C) int rt.dmain2.main(int, char**)) [0x805a49a]
./test(extern (C) int rt.dmain2.main(int, char**)) [0x805a3b0]
./test(main+0x96) [0x805a356]
/lib/tls/libc.so.6(__libc_start_main+0xd3) [0x8c3e93]
./test [0x8057c21]
Comment 1 hsteoh 2014-08-07 22:45:09 UTC
If I run the program under gdb and set a breakpoint on the throw, gdb is able to display the nested function as part of the call stack. So obviously all necessary info is there, it's just a matter of incorporating it into the stacktrace generated by the throw.
Comment 2 Nemanja Boric 2016-10-20 11:38:22 UTC
I think the problem here is that previous exception handler was using BPs stored
on stack to walk the stack frame, and nested functions were not doing this properly (if I remember correctly, they were not using *BP for the stack frame, or something similar).

With the new exception handler, this issue is gone:

object.Exception@test.d(8): Test.
----------------
??:? void test.doIt().nested() [0x422ae9]
??:? void test.doIt() [0x422a92]
??:? _Dmain [0x422a80]
??:? _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv [0x423126]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [0x423070]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll() [0x4230e2]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [0x423070]
??:? _d_run_main [0x422fe1]
??:? main [0x422b75]
??:? __libc_start_main [0x935bb82f]