1 module runtime.stacktrace; 2 3 struct StackTraceInfo 4 { 5 String symbol; 6 String file; 7 uint line; 8 ulong lineAddress; 9 ulong symbolAddress; 10 } 11 12 StackTraceInfo[Amount] traceGetStackTrace(size_t Amount)(uint toSkip, out size_t count) 13 { 14 return getStackTraceImpl!Amount(toSkip, count); 15 } 16 17 void traceFormatStackTrace(OutputT)(ref OutputT output, const StackTraceInfo[] traces) 18 { 19 import libd.data.conv; 20 21 output.reserve(100 * traces.length); 22 output.put("Stack Trace:\n"); 23 foreach(trace; traces) 24 { 25 output.put(trace.lineAddress.to!String[]); 26 output.put(" ["); 27 output.put(trace.file[]); 28 output.put(':'); 29 output.put(trace.line.to!String[]); 30 output.put("] "); 31 output.put(trace.symbol[]); 32 output.put(" @ "); 33 output.put(trace.symbolAddress.to!String[]); 34 output.put('\n'); 35 } 36 } 37 38 version(Windows) 39 { 40 StackTraceInfo[Amount] getStackTraceImpl(size_t Amount)(uint toSkip, out size_t count) 41 { 42 import runtime.system.windows; 43 44 typeof(return) ret; 45 46 g_debugHelp.access((scope ref help) 47 { 48 // + 4 = __lambda, .access, getStackTraceImpl, traceGetStackTrace 49 auto results = help.backtrace!Amount(4 + toSkip, count); 50 foreach(i, result; results[0..count]) 51 ret[i] = StackTraceInfo(result.symbol, result.file, result.line, result.lineAddress, result.symbolAddress); 52 }); 53 54 return ret; 55 } 56 } 57 else version(Posix) 58 { 59 StackTraceInfo[Amount] getStackTraceImpl(size_t Amount)(uint toSkip, out size_t count) 60 { 61 typeof(return) ret; 62 return ret; 63 } 64 }