Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
Merge pull request #74 from CyberShadow/manual-backtrace
Browse files Browse the repository at this point in the history
When backtrace() fails, perform a manual backtrace.
  • Loading branch information
complexmath committed Sep 24, 2011
2 parents 9270d5a + 621a2b5 commit 7134f38
Showing 1 changed file with 34 additions and 3 deletions.
37 changes: 34 additions & 3 deletions src/core/runtime.d
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ private
extern (C) void* rt_loadLibrary( in char[] name );
extern (C) bool rt_unloadLibrary( void* ptr );

extern (C) void* rt_stackBottom();

extern (C) string[] rt_args();

version( linux )
Expand Down Expand Up @@ -395,8 +397,33 @@ Throwable.TraceInfo defaultTraceHandler( void* ptr = null )
{
static enum MAXFRAMES = 128;
void*[MAXFRAMES] callstack;

numframes = backtrace( callstack, MAXFRAMES );
if (numframes < 2) // backtrace() failed, do it ourselves
{
static void** getBasePtr()
{
version( D_InlineAsm_X86 )
asm { naked; mov EAX, EBP; ret; }
else
version( D_InlineAsm_X86_64 )
asm { naked; mov RAX, RBP; ret; }
else
return null;
}

void** stackTop = getBasePtr(), stackBottom = cast(void**)rt_stackBottom();
void* dummy;
if (stackTop && &dummy < stackTop && stackTop < stackBottom)
{
void** stackPtr = stackTop;
numframes = 0;
while (stackTop <= stackPtr && stackPtr < stackBottom && numframes < MAXFRAMES)
{
callstack[numframes++] = *(stackPtr+1);
stackPtr = cast(void**)*stackPtr;
}
}
}
framelist = backtrace_symbols( callstack, numframes );
}

Expand Down Expand Up @@ -490,10 +517,14 @@ Throwable.TraceInfo defaultTraceHandler( void* ptr = null )
}
else version( linux )
{
// format is:
// module(_D6module4funcAFZv) [0x00000000]
// format is: module(_D6module4funcAFZv) [0x00000000]
// or: module(_D6module4funcAFZv+0x78) [0x00000000]
auto bptr = cast(char*) memchr( buf.ptr, '(', buf.length );
auto eptr = cast(char*) memchr( buf.ptr, ')', buf.length );
auto pptr = cast(char*) memchr( buf.ptr, '+', buf.length );

if (pptr && pptr < eptr)
eptr = pptr;

if( bptr++ && eptr )
{
Expand Down

0 comments on commit 7134f38

Please sign in to comment.