Skip to content

Commit

Permalink
Reuse Darwin backtracing code for DRuntime_Use_Libunwind and use same…
Browse files Browse the repository at this point in the history
… code path as libexec-based backtracing.
  • Loading branch information
JohanEngelen committed Jun 30, 2024
1 parent 5fa8e0d commit 6bdefa1
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 193 deletions.
142 changes: 0 additions & 142 deletions runtime/druntime/src/core/internal/backtrace/handler.d

This file was deleted.

43 changes: 17 additions & 26 deletions runtime/druntime/src/core/internal/backtrace/unwind.d
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ version (LDC) // simplify runtime function forward declaration
else
void _Unwind_Resume(_Unwind_Exception* exception_object);
_Unwind_Reason_Code _Unwind_Resume_or_Rethrow(_Unwind_Exception* exception_object);
_Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, void*);
_Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, void*) nothrow;

version (ARM_EABI_UNWINDER)
{
Expand All @@ -160,46 +160,37 @@ version (ARM_EABI_UNWINDER)
// On ARM, these are macros resp. not visible (static inline). To avoid
// an unmaintainable amount of dependencies on implementation details,
// just use a C shim (in ldc/arm_unwind.c).
_Unwind_Word _d_eh_GetGR(_Unwind_Context* context, int index);
_Unwind_Word _d_eh_GetGR(_Unwind_Context* context, int index) nothrow;
alias _Unwind_GetGR = _d_eh_GetGR;

void _d_eh_SetGR(_Unwind_Context* context, int index, _Unwind_Word new_value);
void _d_eh_SetGR(_Unwind_Context* context, int index, _Unwind_Word new_value) nothrow;
alias _Unwind_SetGR = _d_eh_SetGR;

_Unwind_Ptr _d_eh_GetIP(_Unwind_Context* context);
_Unwind_Ptr _d_eh_GetIP(_Unwind_Context* context) nothrow;
alias _Unwind_GetIP = _d_eh_GetIP;

_Unwind_Ptr _d_eh_GetIPInfo(_Unwind_Context* context, int*);
_Unwind_Ptr _d_eh_GetIPInfo(_Unwind_Context* context, int*) nothrow;
alias _Unwind_GetIPInfo = _d_eh_GetIPInfo;

void _d_eh_SetIP(_Unwind_Context* context, _Unwind_Ptr new_value);
void _d_eh_SetIP(_Unwind_Context* context, _Unwind_Ptr new_value) nothrow;
alias _Unwind_SetIP = _d_eh_SetIP;
}
else
{
_Unwind_Word _Unwind_GetGR(_Unwind_Context* context, int index);
void _Unwind_SetGR(_Unwind_Context* context, int index, _Unwind_Word new_value);
_Unwind_Ptr _Unwind_GetIP(_Unwind_Context* context);
_Unwind_Ptr _Unwind_GetIPInfo(_Unwind_Context* context, int*);
void _Unwind_SetIP(_Unwind_Context* context, _Unwind_Ptr new_value);
_Unwind_Word _Unwind_GetGR(_Unwind_Context* context, int index) nothrow;
void _Unwind_SetGR(_Unwind_Context* context, int index, _Unwind_Word new_value) nothrow;
_Unwind_Ptr _Unwind_GetIP(_Unwind_Context* context) nothrow;
_Unwind_Ptr _Unwind_GetIPInfo(_Unwind_Context* context, int*) nothrow;
void _Unwind_SetIP(_Unwind_Context* context, _Unwind_Ptr new_value) nothrow;
}
_Unwind_Word _Unwind_GetCFA(_Unwind_Context*);
_Unwind_Word _Unwind_GetBSP(_Unwind_Context*);
void* _Unwind_GetLanguageSpecificData(_Unwind_Context*);
_Unwind_Ptr _Unwind_GetRegionStart(_Unwind_Context* context);
void* _Unwind_FindEnclosingFunction(void* pc);
_Unwind_Word _Unwind_GetCFA(_Unwind_Context*) nothrow;
_Unwind_Word _Unwind_GetBSP(_Unwind_Context*) nothrow;
void* _Unwind_GetLanguageSpecificData(_Unwind_Context*) nothrow;
_Unwind_Ptr _Unwind_GetRegionStart(_Unwind_Context* context) nothrow;
void* _Unwind_FindEnclosingFunction(void* pc) nothrow;

version (X68_64)
version (X86_64)
{
_Unwind_Ptr _Unwind_GetDataRelBase(_Unwind_Context* context)
{
return _Unwind_GetGR(context, 1);
}

_Unwind_Ptr _Unwind_GetTextRelBase(_Unwind_Context* context)
{
assert(0);
}
}
else
{
Expand Down
39 changes: 14 additions & 25 deletions runtime/druntime/src/core/runtime.d
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,17 @@ else version (TVOS)
else version (WatchOS)
version = Darwin;

version(LDC) version (Darwin)
{
// Use our own backtrace() based on _Unwind_Backtrace(), as the former (from
// execinfo) doesn't seem to handle missing frame pointers too well.
version = DefineBacktrace_using_UnwindBacktrace;
}

version (DRuntime_Use_Libunwind)
{
import core.internal.backtrace.libunwind;
version = DefineBacktrace_using_UnwindBacktrace;

// This shouldn't be necessary but ensure that code doesn't get mixed
// It does however prevent the unittest SEGV handler to be installed,
// which is desireable as it uses backtrace directly.
Expand Down Expand Up @@ -670,24 +678,11 @@ extern (C) UnitTestResult runModuleUnitTests()
return results;
}

version (LDC) version (Darwin)
version (DefineBacktrace_using_UnwindBacktrace)
{
nothrow:

extern (C)
{
enum _URC_NO_REASON = 0;
enum _URC_END_OF_STACK = 5;
import core.internal.backtrace.unwind;

alias _Unwind_Context_Ptr = void*;
alias _Unwind_Trace_Fn = int function(_Unwind_Context_Ptr, void*);
int _Unwind_Backtrace(_Unwind_Trace_Fn, void*);
ptrdiff_t _Unwind_GetIP(_Unwind_Context_Ptr context);
}

// Use our own backtrce() based on _Unwind_Backtrace(), as the former (from
// execinfo) doesn't seem to handle missing frame pointers too well.
private int backtrace(void** buffer, int maxSize)
private int backtrace(void** buffer, int maxSize) nothrow
{
if (maxSize < 0) return 0;

Expand All @@ -698,7 +693,7 @@ version (LDC) version (Darwin)
int entriesWritten = 0;
}

static extern(C) int handler(_Unwind_Context_Ptr context, void* statePtr)
static extern(C) int handler(_Unwind_Context* context, void* statePtr)
{
auto state = cast(State*)statePtr;
if (state.entriesWritten >= state.maxSize) return _URC_END_OF_STACK;
Expand Down Expand Up @@ -819,14 +814,8 @@ void defaultTraceDeallocator(Throwable.TraceInfo info) nothrow
free(cast(void *)obj);
}

version (DRuntime_Use_Libunwind)
{
import core.internal.backtrace.handler;

alias DefaultTraceInfo = LibunwindHandler;
}
/// Default implementation for most POSIX systems
else version (Posix) private class DefaultTraceInfo : Throwable.TraceInfo
version (Posix) private class DefaultTraceInfo : Throwable.TraceInfo
{
import core.demangle;
import core.stdc.stdlib : free;
Expand Down

0 comments on commit 6bdefa1

Please sign in to comment.