debugger blues

Adam D. Ruppe via Digitalmars-d digitalmars-d at puremagic.com
Fri Mar 25 06:28:36 PDT 2016


On Friday, 25 March 2016 at 09:12:56 UTC, cy wrote:
>> This sort of works:
>>
>> 	try
>> 		throw new Exception(null);
>> 	catch (Exception e)
>> 		context = e.toString().splitLines()[1..$];
>
> Huh, neat... I'll have to remember that.


Better yet, the trick from the end of my book still works, with 
mild adjustment:

// put this function in your helper module
string getStackTrace() {
   import core.runtime;

   version(Posix) {
     // druntime cuts out the first few functions on the trace 
because they are internal
     // so we'll make some dummy functions here so our actual info 
doesn't get cut
     Throwable.TraceInfo f2() { return defaultTraceHandler(); }
     Throwable.TraceInfo f1() { return f2(); }
     auto trace = f1();
   } else {
     auto trace = defaultTraceHandler();
   }

   return trace.toString();
}

// and call it like this:
void foo() {
	import std.stdio;
	writeln(getStackTrace());
}

void main() {
	foo();
}






It will print the trace without an exception, showing this:


stacktrace.d:19 void stacktrace.foo() [0x8076aaf]
stacktrace.d:23 _Dmain [0x8076ac7]
??:? 
_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv 
[0x8077c32]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int 
function(char[][])*).tryExec(scope void delegate()) [0x8077b95]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int 
function(char[][])*).runAll() [0x8077bee]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int 
function(char[][])*).tryExec(scope void delegate()) [0x8077b95]
??:? _d_run_main [0x8077b1e]
??:? main [0x8076eab]
??:? __libc_start_main [0xf74fe29f]



Compile with -g to get the file and line number from your code.

You might also tweak the function to skip the last few lines too 
since they are just generic functions inside druntime itself.




string getStackTrace() {
   import core.runtime;

   version(Posix) {
     // druntime cuts out the first few functions on the trace 
because they are internal
     // so we'll make some dummy functions here so our actual info 
doesn't get cut
     Throwable.TraceInfo f2() { return defaultTraceHandler(); }
     Throwable.TraceInfo f1() { return f2(); }
     auto trace = f1();
   } else {
     auto trace = defaultTraceHandler();
   }

   // cut off the last 7 lines because they are internal
   // functions anyway
   import std.string;
   return join(splitLines(trace.toString())[0 .. $-7], "\n");
}



Which now leaves the output as a fairly simple:

$ ./stacktrace
stacktrace.d:20 void stacktrace.foo() [0x80780a7]
stacktrace.d:24 _Dmain [0x80780bf]



which might be pretty useful.


More information about the Digitalmars-d mailing list