diff --git a/libunwind/src/Unwind-seh.cpp b/libunwind/src/Unwind-seh.cpp --- a/libunwind/src/Unwind-seh.cpp +++ b/libunwind/src/Unwind-seh.cpp @@ -104,7 +104,7 @@ if (!ctx) { __unw_init_seh(&cursor, disp->ContextRecord); __unw_seh_set_disp_ctx(&cursor, disp); - __unw_set_reg(&cursor, UNW_REG_IP, disp->ControlPc - 1); + __unw_set_reg(&cursor, UNW_REG_IP, disp->ControlPc); ctx = (struct _Unwind_Context *)&cursor; if (!IS_UNWINDING(ms_exc->ExceptionFlags)) { diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp --- a/libunwind/src/UnwindCursor.hpp +++ b/libunwind/src/UnwindCursor.hpp @@ -518,6 +518,14 @@ pint_t getLastPC() const { return _dispContext.ControlPc; } void setLastPC(pint_t pc) { _dispContext.ControlPc = pc; } RUNTIME_FUNCTION *lookUpSEHUnwindInfo(pint_t pc, pint_t *base) { +#ifdef __arm__ + // Remove the thumb bit; FunctionEntry ranges don't include the thumb bit. + pc &= ~1U; +#endif + // If pc points exactly at the end of the range, we might resolve the + // next function instead. Decrement pc by 1 to fit inside the current + // function. + pc -= 1; _dispContext.FunctionEntry = RtlLookupFunctionEntry(pc, &_dispContext.ImageBase, _dispContext.HistoryTable);