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.

Reply via email to