Skip to content

Instantly share code, notes, and snippets.

@jpf91
Created March 30, 2012 17:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jpf91/2253215 to your computer and use it in GitHub Desktop.
Save jpf91/2253215 to your computer and use it in GitHub Desktop.
diff --git a/libphobos/libdruntime/core/runtime.d b/libphobos/libdruntime/core/runtime.d
index 42e09ac..cc426dd 100644
--- a/libphobos/libdruntime/core/runtime.d
+++ b/libphobos/libdruntime/core/runtime.d
@@ -42,11 +42,14 @@ private
version(GNU)
{
- import gcc.unwind;
- import core.demangle;
- import core.stdc.stdio : snprintf, printf;
- import core.stdc.string : strlen;
- import core.sys.posix.signal; // segv handler
+ version(Posix)
+ {
+ import gcc.unwind;
+ import core.demangle;
+ import core.stdc.stdio : snprintf, printf;
+ import core.stdc.string : strlen;
+ import core.sys.posix.signal; // segv handler
+ }
}
version(Android)
@@ -363,60 +366,63 @@ extern (C) bool runModuleUnitTests()
}
else version(GNU)
{
- /*
- * core.demangle may allocate, so no demangling here
- *
- * FIXME: At least on ARM this prints only the signal handler's
- * stack. This is of course useless..
- */
- static extern (C) void unittestSegvHandler( int signum, siginfo_t* info, void* ptr )
+ version(Posix)
{
- gdcBacktraceData stackframe = gdcBacktrace();
- btSymbolData syms = gdcBacktraceSymbols(stackframe);
-
- for(size_t i = 0; i < syms.entries; i++)
+ /*
+ * core.demangle may allocate, so no demangling here
+ *
+ * FIXME: At least on ARM this prints only the signal handler's
+ * stack. This is of course useless..
+ */
+ static extern (C) void unittestSegvHandler( int signum, siginfo_t* info, void* ptr )
{
- auto sym = syms.symbols[i];
- if(sym.fileName)
- {
- if(sym.name)
- {
- printf("%s(%s+%#x) [%p]\n", sym.fileName, sym.name,
- sym.offset, sym.address);
- }
- else
- {
- printf("%s() [%p]\n", sym.fileName, sym.address);
- }
- }
- else
+ gdcBacktraceData stackframe = gdcBacktrace();
+ btSymbolData syms = gdcBacktraceSymbols(stackframe);
+
+ for(size_t i = 0; i < syms.entries; i++)
{
- if(sym.name)
+ auto sym = syms.symbols[i];
+ if(sym.fileName)
{
- printf("(%s+%#x) [%p]\n", sym.name, sym.offset, sym.address);
+ if(sym.name)
+ {
+ printf("%s(%s+%#x) [%p]\n", sym.fileName, sym.name,
+ sym.offset, sym.address);
+ }
+ else
+ {
+ printf("%s() [%p]\n", sym.fileName, sym.address);
+ }
}
else
{
- printf("() [%p]\n", sym.address);
+ if(sym.name)
+ {
+ printf("(%s+%#x) [%p]\n", sym.name, sym.offset, sym.address);
+ }
+ else
+ {
+ printf("() [%p]\n", sym.address);
+ }
}
}
}
- }
-
- sigaction_t action = void;
- sigaction_t oldseg = void;
- sigaction_t oldbus = void;
-
- (cast(byte*) &action)[0 .. action.sizeof] = 0;
- sigfillset( &action.sa_mask ); // block other signals
- action.sa_flags = SA_SIGINFO | SA_RESETHAND;
- action.sa_sigaction = &unittestSegvHandler;
- sigaction( SIGSEGV, &action, &oldseg );
- sigaction( SIGBUS, &action, &oldbus );
- scope( exit )
- {
- sigaction( SIGSEGV, &oldseg, null );
- sigaction( SIGBUS, &oldbus, null );
+
+ sigaction_t action = void;
+ sigaction_t oldseg = void;
+ sigaction_t oldbus = void;
+
+ (cast(byte*) &action)[0 .. action.sizeof] = 0;
+ sigfillset( &action.sa_mask ); // block other signals
+ action.sa_flags = SA_SIGINFO | SA_RESETHAND;
+ action.sa_sigaction = &unittestSegvHandler;
+ sigaction( SIGSEGV, &action, &oldseg );
+ sigaction( SIGBUS, &action, &oldbus );
+ scope( exit )
+ {
+ sigaction( SIGSEGV, &oldseg, null );
+ sigaction( SIGBUS, &oldbus, null );
+ }
}
}
@@ -650,131 +656,138 @@ Throwable.TraceInfo defaultTraceHandler( void* ptr = null )
}
else version(GNU)
{
- class DefaultTraceInfo : Throwable.TraceInfo
+ version(Posix)
{
- this()
+ class DefaultTraceInfo : Throwable.TraceInfo
{
- callstack = gdcBacktrace();
- framelist = gdcBacktraceSymbols(callstack);
- }
-
- override int opApply( scope int delegate(ref char[]) dg )
- {
- return opApply( (ref size_t, ref char[] buf)
- {
- return dg( buf );
- } );
- }
-
- override int opApply( scope int delegate(ref size_t, ref char[]) dg )
- {
- version( Posix )
+ this()
{
- // NOTE: The first 5 frames with the current implementation are
- // inside core.runtime and the object code, so eliminate
- // these for readability. The alternative would be to
- // exclude the first N frames that are in a list of
- // mangled function names.
- static enum FIRSTFRAME = 5;
+ callstack = gdcBacktrace();
+ framelist = gdcBacktraceSymbols(callstack);
}
- else
- {
- // NOTE: On Windows, the number of frames to exclude is based on
- // whether the exception is user or system-generated, so
- // it may be necessary to exclude a list of function names
- // instead.
- static enum FIRSTFRAME = 0;
- }
- int ret = 0;
-
- for( int i = FIRSTFRAME; i < framelist.entries; ++i )
+
+ override int opApply( scope int delegate(ref char[]) dg )
{
- auto pos = cast(size_t)(i - FIRSTFRAME);
- auto buf = formatLine(framelist.symbols[i]);
- ret = dg( pos, buf );
- if( ret )
- break;
+ return opApply( (ref size_t, ref char[] buf)
+ {
+ return dg( buf );
+ } );
}
- return ret;
- }
-
- override string toString()
- {
- string buf;
- foreach( i, line; this )
- buf ~= i ? "\n" ~ line : line;
- return buf;
- }
-
- private:
- btSymbolData framelist;
- gdcBacktraceData callstack;
-
- private:
- char[4096] fixbuf;
-
- /*Do not put \n at end of line!*/
- char[] formatLine(backtraceSymbol sym)
- {
- int ret;
-
- if(sym.fileName)
+
+ override int opApply( scope int delegate(ref size_t, ref char[]) dg )
{
- if(sym.name)
+ version( Posix )
{
- ret = snprintf(fixbuf.ptr, fixbuf.sizeof,
- "%s(", sym.fileName);
- if(ret >= fixbuf.sizeof)
- return fixbuf[];
-
- auto demangled = demangle(sym.name[0 .. strlen(sym.name)],
- fixbuf[ret .. $]);
-
- ret += demangled.length;
- if(ret >= fixbuf.sizeof)
- return fixbuf[];
-
- ret += snprintf(fixbuf.ptr + ret, fixbuf.sizeof - ret,
- "+%#x) [%p]", sym.offset, sym.address);
+ // NOTE: The first 5 frames with the current implementation are
+ // inside core.runtime and the object code, so eliminate
+ // these for readability. The alternative would be to
+ // exclude the first N frames that are in a list of
+ // mangled function names.
+ static enum FIRSTFRAME = 5;
}
else
{
- ret = snprintf(fixbuf.ptr, fixbuf.sizeof,
- "%s() [%p]", sym.fileName, sym.address);
+ // NOTE: On Windows, the number of frames to exclude is based on
+ // whether the exception is user or system-generated, so
+ // it may be necessary to exclude a list of function names
+ // instead.
+ static enum FIRSTFRAME = 0;
}
+ int ret = 0;
+
+ for( int i = FIRSTFRAME; i < framelist.entries; ++i )
+ {
+ auto pos = cast(size_t)(i - FIRSTFRAME);
+ auto buf = formatLine(framelist.symbols[i]);
+ ret = dg( pos, buf );
+ if( ret )
+ break;
+ }
+ return ret;
}
- else
+
+ override string toString()
{
- if(sym.name)
+ string buf;
+ foreach( i, line; this )
+ buf ~= i ? "\n" ~ line : line;
+ return buf;
+ }
+
+ private:
+ btSymbolData framelist;
+ gdcBacktraceData callstack;
+
+ private:
+ char[4096] fixbuf;
+
+ /*Do not put \n at end of line!*/
+ char[] formatLine(backtraceSymbol sym)
+ {
+ int ret;
+
+ if(sym.fileName)
{
- fixbuf[0] = '(';
- ret = 1;
-
- auto demangled = demangle(sym.name[0 .. strlen(sym.name)],
- fixbuf[ret .. $]);
-
- ret += demangled.length;
- if(ret >= fixbuf.sizeof)
- return fixbuf[];
-
- ret += snprintf(fixbuf.ptr + ret, fixbuf.sizeof - ret,
- "+%#x) [%p]", sym.offset, sym.address);
+ if(sym.name)
+ {
+ ret = snprintf(fixbuf.ptr, fixbuf.sizeof,
+ "%s(", sym.fileName);
+ if(ret >= fixbuf.sizeof)
+ return fixbuf[];
+
+ auto demangled = demangle(sym.name[0 .. strlen(sym.name)],
+ fixbuf[ret .. $]);
+
+ ret += demangled.length;
+ if(ret >= fixbuf.sizeof)
+ return fixbuf[];
+
+ ret += snprintf(fixbuf.ptr + ret, fixbuf.sizeof - ret,
+ "+%#x) [%p]", sym.offset, sym.address);
+ }
+ else
+ {
+ ret = snprintf(fixbuf.ptr, fixbuf.sizeof,
+ "%s() [%p]", sym.fileName, sym.address);
+ }
}
else
{
- ret = snprintf(fixbuf.ptr, fixbuf.sizeof, "() [%p]",
- sym.address);
+ if(sym.name)
+ {
+ fixbuf[0] = '(';
+ ret = 1;
+
+ auto demangled = demangle(sym.name[0 .. strlen(sym.name)],
+ fixbuf[ret .. $]);
+
+ ret += demangled.length;
+ if(ret >= fixbuf.sizeof)
+ return fixbuf[];
+
+ ret += snprintf(fixbuf.ptr + ret, fixbuf.sizeof - ret,
+ "+%#x) [%p]", sym.offset, sym.address);
+ }
+ else
+ {
+ ret = snprintf(fixbuf.ptr, fixbuf.sizeof, "() [%p]",
+ sym.address);
+ }
}
+
+ if(ret >= fixbuf.sizeof)
+ return fixbuf[];
+ else
+ return fixbuf[0 .. ret];
}
-
- if(ret >= fixbuf.sizeof)
- return fixbuf[];
- else
- return fixbuf[0 .. ret];
}
+
+ return new DefaultTraceInfo;
+ }
+ else
+ {
+ return null;
}
-
- return new DefaultTraceInfo;
}
else
{
@@ -784,69 +797,77 @@ Throwable.TraceInfo defaultTraceHandler( void* ptr = null )
version(GNU)
{
- import gcc.unwind;
-
- static enum MAXFRAMES = 128;
-
- struct gdcBacktraceData
- {
- void*[MAXFRAMES] callstack;
- int numframes = 0;
- }
-
- struct backtraceSymbol
- {
- const(char)* name, fileName;
- size_t offset;
- void* address;
- }
-
- struct btSymbolData
+ version(Posix)
{
- size_t entries;
- backtraceSymbol[MAXFRAMES] symbols;
- }
+ import gcc.unwind;
- static extern (C) _Unwind_Reason_Code unwindCB(_Unwind_Context *ctx, void *d)
- {
- gdcBacktraceData* bt = cast(gdcBacktraceData*)d;
- if(bt.numframes >= MAXFRAMES)
+ static enum MAXFRAMES = 128;
+
+ struct gdcBacktraceData
+ {
+ void*[MAXFRAMES] callstack;
+ int numframes = 0;
+ }
+
+ struct backtraceSymbol
+ {
+ const(char)* name, fileName;
+ size_t offset;
+ void* address;
+ }
+
+ struct btSymbolData
+ {
+ size_t entries;
+ backtraceSymbol[MAXFRAMES] symbols;
+ }
+
+ static extern (C) _Unwind_Reason_Code unwindCB(_Unwind_Context *ctx, void *d)
+ {
+ gdcBacktraceData* bt = cast(gdcBacktraceData*)d;
+ if(bt.numframes >= MAXFRAMES)
+ return _URC_NO_REASON;
+
+ bt.callstack[bt.numframes] = cast(void*)_Unwind_GetIP(ctx);
+ bt.numframes++;
return _URC_NO_REASON;
-
- bt.callstack[bt.numframes] = cast(void*)_Unwind_GetIP(ctx);
- bt.numframes++;
- return _URC_NO_REASON;
- }
-
- gdcBacktraceData gdcBacktrace()
- {
- gdcBacktraceData stackframe;
- _Unwind_Backtrace(&unwindCB, &stackframe);
- return stackframe;
- }
-
- btSymbolData gdcBacktraceSymbols(gdcBacktraceData data)
- {
- btSymbolData symData;
-
- for(auto i = 0; i < data.numframes; i++)
+ }
+
+ gdcBacktraceData gdcBacktrace()
+ {
+ gdcBacktraceData stackframe;
+ _Unwind_Backtrace(&unwindCB, &stackframe);
+ return stackframe;
+ }
+
+ btSymbolData gdcBacktraceSymbols(gdcBacktraceData data)
{
- version(haveDLADDR)
+ btSymbolData symData;
+
+ for(auto i = 0; i < data.numframes; i++)
{
- Dl_info funcInfo;
-
- if(data.callstack[i] !is null && dladdr(data.callstack[i], &funcInfo) != 0)
+ version(haveDLADDR)
{
- symData.symbols[symData.entries].name = funcInfo.dli_sname;
- symData.symbols[symData.entries].fileName = funcInfo.dli_fname;
-
- if(funcInfo.dli_saddr is null)
- symData.symbols[symData.entries].offset = 0;
+ Dl_info funcInfo;
+
+ if(data.callstack[i] !is null && dladdr(data.callstack[i], &funcInfo) != 0)
+ {
+ symData.symbols[symData.entries].name = funcInfo.dli_sname;
+ symData.symbols[symData.entries].fileName = funcInfo.dli_fname;
+
+ if(funcInfo.dli_saddr is null)
+ symData.symbols[symData.entries].offset = 0;
+ else
+ symData.symbols[symData.entries].offset = data.callstack[i] - funcInfo.dli_saddr;
+
+ symData.symbols[symData.entries].address = data.callstack[i];
+ symData.entries++;
+ }
else
- symData.symbols[symData.entries].offset = data.callstack[i] - funcInfo.dli_saddr;
-
- symData.symbols[symData.entries].address = data.callstack[i];
- symData.entries++;
+ {
+ symData.symbols[symData.entries].address = data.callstack[i];
+ symData.entries++;
+ }
}
else
{
@@ -854,13 +875,8 @@ version(GNU)
symData.entries++;
}
}
- else
- {
- symData.symbols[symData.entries].address = data.callstack[i];
- symData.entries++;
- }
+
+ return symData;
}
-
- return symData;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment