diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2021-12-02 21:02:54 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2021-12-02 21:02:54 +0000 |
| commit | f65dcba83ce5035ab88a85fe17628b447eb56e1b (patch) | |
| tree | 35f37bb72b3cfc6060193e66c76ee7c9478969b0 /libunwind | |
| parent | 846a2208a8ab099f595fe7e8b2e6d54a7b5e67fb (diff) | |
Diffstat (limited to 'libunwind')
| -rw-r--r-- | libunwind/src/Unwind-EHABI.cpp | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/libunwind/src/Unwind-EHABI.cpp b/libunwind/src/Unwind-EHABI.cpp index d3577c9f7cf8..5959d2a25fea 100644 --- a/libunwind/src/Unwind-EHABI.cpp +++ b/libunwind/src/Unwind-EHABI.cpp @@ -187,9 +187,14 @@ static _Unwind_Reason_Code unwindOneFrame(_Unwind_State state, if (result != _URC_CONTINUE_UNWIND) return result; - if (__unw_step(reinterpret_cast<unw_cursor_t *>(context)) != UNW_STEP_SUCCESS) + switch (__unw_step(reinterpret_cast<unw_cursor_t *>(context))) { + case UNW_STEP_SUCCESS: + return _URC_CONTINUE_UNWIND; + case UNW_STEP_END: + return _URC_END_OF_STACK; + default: return _URC_FAILURE; - return _URC_CONTINUE_UNWIND; + } } // Generates mask discriminator for _Unwind_VRS_Pop, e.g. for _UVRSC_CORE / @@ -678,12 +683,13 @@ static _Unwind_Reason_Code unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object, _Unwind_Stop_Fn stop, void *stop_parameter) { + bool endOfStack = false; // See comment at the start of unwind_phase1 regarding VRS integrity. __unw_init_local(cursor, uc); _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_force(ex_ojb=%p)", static_cast<void *>(exception_object)); // Walk each frame until we reach where search phase said to stop - while (true) { + while (!endOfStack) { // Update info about this frame. unw_proc_info_t frameInfo; if (__unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { @@ -756,6 +762,14 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, // We may get control back if landing pad calls _Unwind_Resume(). __unw_resume(cursor); break; + case _URC_END_OF_STACK: + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " + "personality returned " + "_URC_END_OF_STACK", + (void *)exception_object); + // Personalty routine did the step and it can't step forward. + endOfStack = true; + break; default: // Personality routine returned an unknown result code. _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " @@ -1133,9 +1147,14 @@ extern "C" _LIBUNWIND_EXPORT _Unwind_Reason_Code __gnu_unwind_frame(_Unwind_Exception *exception_object, struct _Unwind_Context *context) { unw_cursor_t *cursor = (unw_cursor_t *)context; - if (__unw_step(cursor) != UNW_STEP_SUCCESS) + switch (__unw_step(cursor)) { + case UNW_STEP_SUCCESS: + return _URC_OK; + case UNW_STEP_END: + return _URC_END_OF_STACK; + default: return _URC_FAILURE; - return _URC_OK; + } } #endif // defined(_LIBUNWIND_ARM_EHABI) |
