// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/mac/call_with_eh_frame.h" #include #include #include "build/build_config.h" namespace base { 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( int version, _Unwind_Action actions, uint64_t exception_class, struct _Unwind_Exception* exception_object, struct _Unwind_Context* context) { // Unwinding is a two-phase process: phase one searches for an exception // handler, and phase two performs cleanup. For phase one, this custom // personality will terminate the search. For phase two, this should delegate // back to the standard personality routine. if ((actions & _UA_SEARCH_PHASE) != 0) { // Tell libunwind that this is the end of the stack. When it encounters the // CallWithEHFrame, it will stop searching for an exception handler. The // 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 // defined(OS_IOS) } // namespace mac } // namespace base