aboutsummaryrefslogtreecommitdiff
path: root/libunwind
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-12-02 21:02:54 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-12-02 21:02:54 +0000
commitf65dcba83ce5035ab88a85fe17628b447eb56e1b (patch)
tree35f37bb72b3cfc6060193e66c76ee7c9478969b0 /libunwind
parent846a2208a8ab099f595fe7e8b2e6d54a7b5e67fb (diff)
Diffstat (limited to 'libunwind')
-rw-r--r--libunwind/src/Unwind-EHABI.cpp29
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)