Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 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;
- }
- }
Add Comment
Please, Sign In to add comment