Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.
/ druntime Public archive
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions mak/SRCS
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ SRCS=\
src\rt\trace.d \
src\rt\tracegc.d \
\
src\rt\backtrace\dwarf.d \
src\rt\backtrace\elf.d \
\
src\rt\util\array.d \
src\rt\util\hash.d \
src\rt\util\random.d \
Expand Down
63 changes: 45 additions & 18 deletions src/core/runtime.d
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,9 @@ Throwable.TraceInfo defaultTraceHandler( void* ptr = null )
stackPtr < stackBottom &&
numframes < MAXFRAMES; )
{
callstack[numframes++] = *(stackPtr + 1);
enum CALL_INSTRUCTION_SIZE = 1; // it may not be 1 but it is good enough to get
// in CALL instruction address range for backtrace
callstack[numframes++] = *(stackPtr + 1) - CALL_INSTRUCTION_SIZE;
stackPtr = cast(void**) *stackPtr;
}
}
Expand All @@ -509,39 +511,64 @@ Throwable.TraceInfo defaultTraceHandler( void* ptr = null )

override int opApply( scope int delegate(ref size_t, ref const(char[])) dg ) const
{
version( Posix )
version(Posix)
{
// NOTE: The first 5 frames with the current implementation are
// NOTE: The first 4 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;
enum FIRSTFRAME = 4;
}
else version( Windows )
else version(Windows)
{
// 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;
enum FIRSTFRAME = 0;
}
int ret = 0;

const framelist = backtrace_symbols( callstack.ptr, numframes );
scope(exit) free(cast(void*) framelist);
version(linux)
{
import core.internal.traits : externDFunc;

alias traceHandlerOpApplyImpl = externDFunc!(
"rt.backtrace.dwarf.traceHandlerOpApplyImpl",
int function(const void*[], scope int delegate(ref size_t, ref const(char[])))
);

for( int i = FIRSTFRAME; i < numframes; ++i )
if (numframes >= FIRSTFRAME)
{
return traceHandlerOpApplyImpl(
callstack[FIRSTFRAME .. numframes],
dg
);
}
else
{
return 0;
}
}
else
{
char[4096] fixbuf;
auto buf = framelist[i][0 .. strlen(framelist[i])];
auto pos = cast(size_t)(i - FIRSTFRAME);
buf = fixline( buf, fixbuf );
ret = dg( pos, buf );
if( ret )
break;
const framelist = backtrace_symbols( callstack.ptr, numframes );
scope(exit) free(cast(void*) framelist);

int ret = 0;
for( int i = FIRSTFRAME; i < numframes; ++i )
{
char[4096] fixbuf;
auto buf = framelist[i][0 .. strlen(framelist[i])];
auto pos = cast(size_t)(i - FIRSTFRAME);
buf = fixline( buf, fixbuf );
ret = dg( pos, buf );
if( ret )
break;
}
return ret;
}
return ret;

}

override string toString() const
Expand Down
Loading