Commit dd20bfda authored by rsesek's avatar rsesek Committed by Commit bot

[Mac] In base::mac::CxxPersonalityRoutine, delegate back to __gxx_personality_v0.

This fixes a hypothetical issue where returning _URC_END_OF_STACK in phase two
of exception processing could confuse libunwind. If this personality routine
is called in phase two, it will now delegate back to the normal C++ personality
routine. See https://crbug.com/576941#c62 for details.

BUG=576941
R=mark@chromium.org

Review-Url: https://codereview.chromium.org/2119553002
Cr-Commit-Position: refs/heads/master@{#403235}
parent d6e0fe5e
...@@ -12,27 +12,43 @@ ...@@ -12,27 +12,43 @@
namespace base { namespace base {
namespace mac { namespace mac {
#if defined(OS_IOS)
// No iOS assembly implementation exists, so just call the block directly.
void CallWithEHFrame(void (^block)(void)) {
block();
}
#else // OS_MACOSX
extern "C" _Unwind_Reason_Code __gxx_personality_v0(int,
_Unwind_Action,
uint64_t,
struct _Unwind_Exception*,
struct _Unwind_Context*);
_Unwind_Reason_Code CxxPersonalityRoutine( _Unwind_Reason_Code CxxPersonalityRoutine(
int version, int version,
_Unwind_Action actions, _Unwind_Action actions,
uint64_t exceptionClass, uint64_t exception_class,
struct _Unwind_Exception* exceptionObject, struct _Unwind_Exception* exception_object,
struct _Unwind_Context* context) { struct _Unwind_Context* context) {
// Tell libunwind that this is the end of the stack. When it encounters the // Unwinding is a two-phase process: phase one searches for an exception
// CallWithEHFrame, it will stop searching for an exception handler. The // handler, and phase two performs cleanup. For phase one, this custom
// result is that no exception handler has been found higher on the stack, // personality will terminate the search. For phase two, this should delegate
// and any that are lower on the stack (e.g. in CFRunLoopRunSpecific), will // back to the standard personality routine.
// now be skipped. Since this is reporting the end of the stack, and no
// exception handler will have been found, std::terminate() will be called.
return _URC_END_OF_STACK;
}
#if defined(OS_IOS) if ((actions & _UA_SEARCH_PHASE) != 0) {
// No iOS assembly implementation exists, so just call the block directly. // Tell libunwind that this is the end of the stack. When it encounters the
void CallWithEHFrame(void (^block)(void)) { // CallWithEHFrame, it will stop searching for an exception handler. The
block(); // result is that no exception handler has been found higher on the stack,
// and any that are lower on the stack (e.g. in CFRunLoopRunSpecific), will
// now be skipped. Since this is reporting the end of the stack, and no
// exception handler will have been found, std::terminate() will be called.
return _URC_END_OF_STACK;
}
return __gxx_personality_v0(version, actions, exception_class,
exception_object, context);
} }
#endif #endif // defined(OS_IOS)
} // namespace mac } // namespace mac
} // namespace base } // namespace base
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment