Merge pull request #313 from pgavlin/LibUnwindCheck
authorPat Gavlin <pgavlin@gmail.com>
Sat, 21 Feb 2015 00:41:27 +0000 (16:41 -0800)
committerPat Gavlin <pgavlin@gmail.com>
Sat, 21 Feb 2015 00:41:27 +0000 (16:41 -0800)
Move the error that is emitted when libunwind is missing into CMake.

1  2 
src/pal/src/exception/seh-unwind.cpp

@@@ -160,13 -199,299 +160,9 @@@ BOOL PAL_VirtualUnwind(CONTEXT *context
      return TRUE;
  }
  #else
- #if __LINUX__
- #error Cannot find libuwind.  Try installing libunwind8 and libunwind8-dev
- #else
  #error don't know how to unwind on this platform
  #endif
- #endif
  
 -#if _DEBUG
 -//----------------------------------------------------------------------
 -// Virtual Unwinding Debugging Assertions
 -//----------------------------------------------------------------------
 -
 -// Print a trace of virtually unwinding the stack.
 -// This helps us diagnose non-unwindable stacks.
 -// Unfortunately, calling this function from gdb will not be very useful,
 -// since gdb makes it look like it had been called directly from "start"
 -// (whose unwind info says we reached the end of the stack).
 -// You can still call it from, say, RaiseTheExceptionInternalOnly.
 -
 -// (non-static to ease debugging)
 -void DisplayContext(_Unwind_Context *context)
 -{
 -    fprintf(stderr, "  ip =%p", _Unwind_GetIP(context));
 -    fprintf(stderr, "  cfa=%p", _Unwind_GetCFA(context));
 -#if defined(_X86_)
 -    // TODO: display more registers
 -#endif
 -    fprintf(stderr, "\n");
 -}
 -
 -static _Unwind_Reason_Code PrintVirtualUnwindCallback(_Unwind_Context *context, void *pvParam)
 -{
 -    int *pFrameNumber = (int *) pvParam;
 -
 -    void *ip = _Unwind_GetIP(context);
 -    const char *module = NULL;
 -    const char *name = 0;
 -    int offset = 0;
 -
 -    Dl_info dl_info;
 -    if (dladdr(ip, &dl_info))
 -    {
 -        module = dl_info.dli_fname;
 -        if (dl_info.dli_sname)
 -        {
 -            name = dl_info.dli_sname;
 -            offset = (char *) ip - (char *) dl_info.dli_saddr;
 -        }
 -        else
 -        {
 -            name = "<img-base>";
 -            offset = (char *) ip - (char *) dl_info.dli_fbase;
 -        }
 -    }
 -
 -    if (module)
 -        fprintf(stderr, "#%-3d  %s!%s+%d\n", *pFrameNumber, module, name, offset);
 -    else
 -        fprintf(stderr, "#%-3d  ??\n", *pFrameNumber);
 -    DisplayContext(context);
 -    (*pFrameNumber)++;
 -    return _URC_NO_REASON;
 -}
 -
 -extern "C" void PAL_PrintVirtualUnwind()
 -{
 -    BOOL fEntered = PAL_ReenterForEH();
 -
 -    fprintf(stderr, "\nVirtual unwind of PAL thread %p\n", InternalGetCurrentThread());
 -    int frameNumber = 0;
 -    _Unwind_Reason_Code urc = _Unwind_Backtrace(PrintVirtualUnwindCallback, &frameNumber);
 -    fprintf(stderr, "End of stack (return code=%d).\n", urc);
 -
 -    if (fEntered)
 -    {
 -        PAL_Leave(PAL_BoundaryEH);
 -    }
 -}
 -
 -static const char *PAL_CHECK_UNWINDABLE_STACKS = "PAL_CheckUnwindableStacks";
 -
 -enum CheckUnwindableStacksMode
 -{
 -    // special value to indicate we've not initialized yet
 -    CheckUnwindableStacks_Uninitialized = -1,
 -
 -    CheckUnwindableStacks_Off           = 0,
 -    CheckUnwindableStacks_On            = 1,
 -    CheckUnwindableStacks_Thorough      = 2,
 -
 -    CheckUnwindableStacks_Default       = CheckUnwindableStacks_On
 -};
 -
 -static CheckUnwindableStacksMode s_mode = CheckUnwindableStacks_Uninitialized;
 -
 -// A variant of the above.  This one's not meant for CLR developers to use for tracing,
 -// but implements debug checks to assert stack consistency.
 -static _Unwind_Reason_Code CheckVirtualUnwindCallback(_Unwind_Context *context, void *pvParam)
 -{
 -    void *ip = _Unwind_GetIP(context);
 -
 -    // If we reach an IP that we cannot find a module for,
 -    // then we ended up in dynamically-generated code and
 -    // the stack will not be unwindable past this point.
 -    Dl_info dl_info;
 -    if (dladdr(ip, &dl_info) == 0 ||
 -        ((s_mode == CheckUnwindableStacks_Thorough) &&
 -        ( dl_info.dli_sname == NULL ||
 -          ( _Unwind_Find_FDE(ip, NULL) == NULL &&
 -            strcmp(dl_info.dli_sname, "start") &&
 -            strcmp(dl_info.dli_sname, "_thread_create_running")))))
 -    {
 -        *(BOOL *) pvParam = FALSE;
 -    }
 -
 -    return _URC_NO_REASON;
 -}
 -
 -extern "C" void PAL_CheckVirtualUnwind()
 -{
 -    if (s_mode == CheckUnwindableStacks_Uninitialized)
 -    {
 -        const char *checkUnwindableStacks = getenv(PAL_CHECK_UNWINDABLE_STACKS);
 -        s_mode = checkUnwindableStacks ?
 -            (CheckUnwindableStacksMode) atoi(checkUnwindableStacks) : CheckUnwindableStacks_Default;
 -    }
 -
 -    if (s_mode != CheckUnwindableStacks_Off)
 -    {
 -        BOOL fUnwindable = TRUE;
 -        _ASSERTE(_Unwind_Backtrace(CheckVirtualUnwindCallback, &fUnwindable) == _URC_END_OF_STACK);
 -        if (!fUnwindable)
 -        {
 -            PAL_PrintVirtualUnwind();
 -            ASSERT("Stack not unwindable.  Throwing may terminate the process.\n");
 -        }
 -    }
 -}
 -#endif // _DEBUG
 -
 -//----------------------------------------------------------------------
 -// Registering Vectored Handlers
 -//----------------------------------------------------------------------
 -
 -static PVECTORED_EXCEPTION_HANDLER VectoredExceptionHandler = NULL;
 -static PVECTORED_EXCEPTION_HANDLER VectoredContinueHandler = NULL;
 -
 -void SetVectoredExceptionHandler(PVECTORED_EXCEPTION_HANDLER pHandler)
 -{
 -    PERF_ENTRY(SetVectoredExceptionHandler);
 -    ENTRY("SetVectoredExceptionHandler(pHandler=%p)\n", pHandler);
 -
 -    _ASSERTE(VectoredExceptionHandler == NULL);
 -    VectoredExceptionHandler = pHandler;
 -
 -    LOGEXIT("SetVectoredExceptionHandler returns\n");
 -    PERF_EXIT(SetVectoredExceptionHandler);
 -
 -}
 -
 -void SetVectoredContinueHandler(PVECTORED_EXCEPTION_HANDLER pHandler)
 -{
 -    PERF_ENTRY(SetVectoredContinueHandler);
 -    ENTRY("SetVectoredContinueHandler(pHandler=%p)\n", pHandler);
 -
 -    _ASSERTE(VectoredContinueHandler == NULL);
 -    VectoredContinueHandler = pHandler;
 -
 -    LOGEXIT("SetVectoredContinueHandler returns\n");
 -    PERF_EXIT(SetVectoredContinueHandler);
 -}
 -
 -//----------------------------------------------------------------------
 -// Representation of an SEH Exception as a C++ object
 -//----------------------------------------------------------------------
 -
 -struct PAL_SEHException
 -{
 -public:
 -    // Note that the following two are actually embedded in this heap-allocated
 -    // instance - in contrast to Win32, where the exception record would usually
 -    // be allocated on the stack.  This is needed because foreign cleanup handlers
 -    // partially unwind the stack on the second pass.
 -    EXCEPTION_POINTERS ExceptionPointers;
 -    EXCEPTION_RECORD ExceptionRecord;
 -    CONTEXT ContextRecord;
 -
 -    PAL_SEHException(EXCEPTION_RECORD *pExceptionRecord, CONTEXT *pContextRecord)
 -    {
 -        ExceptionPointers.ExceptionRecord = &ExceptionRecord;
 -        ExceptionPointers.ContextRecord = &ContextRecord;
 -        ExceptionRecord = *pExceptionRecord;
 -        ContextRecord = *pContextRecord;
 -        nestedExceptionEstablisherFrame = NULL;
 -    }
 -
 -    static PAL_SEHException *FromExceptionObject(_Unwind_Exception *exceptionObject)
 -    {
 -        if (exceptionObject->exception_class == Class)
 -        {
 -            if (*((__cxa_exception *) (exceptionObject + 1) - 1)->exceptionType == typeid(PAL_SEHException))
 -            {
 -                return (PAL_SEHException *) (exceptionObject + 1);
 -            }
 -        }
 -        return NULL;
 -    }
 -
 -    void NestedIn(_Unwind_Context *context)
 -    {
 -        nestedExceptionEstablisherFrame = _Unwind_GetCFA(context);
 -        ExceptionRecord.ExceptionFlags |= EXCEPTION_NESTED_CALL;
 -    }
 -
 -    void RanThroughFilter(_Unwind_Context *context)
 -    {
 -        if (nestedExceptionEstablisherFrame == _Unwind_GetCFA(context))
 -        {
 -            // We were processing a nested exception, and we have repeated
 -            // the search phase past the filter that threw the nested exception.
 -            // Thus, clear the corresponding flag now.
 -            ExceptionRecord.ExceptionFlags &= ~EXCEPTION_NESTED_CALL;
 -        }
 -    }
 -
 -private:
 -#ifdef __GNUC__
 -    static const __uint64_t Class = 0x474e5543432b2b00ULL; // vendor = GNUC, language = C++\0
 -#else
 -#error Vendor code not defined for this platform.
 -#endif
 -
 -    // If we encountered a nested exception, the EXCEPTION_NESTED_CALL flag must
 -    // remain set on the exception while unwinding to the frame with the CFA
 -    // stored below.  Note that this will always be a PAL_TryExcept frame.
 -    void *nestedExceptionEstablisherFrame;
 -};
 -
 -EXCEPTION_POINTERS *
 -PALAPI
 -PAL_GetExceptionPointers(_Unwind_Exception *exceptionObject)
 -{
 -    PAL_SEHException *pSEHException = PAL_SEHException::FromExceptionObject(exceptionObject);
 -    if (pSEHException)
 -    {
 -        return &pSEHException->ExceptionPointers;
 -    }
 -    return NULL;
 -}
 -
 -//----------------------------------------------------------------------
 -// Raising Exceptions
 -//----------------------------------------------------------------------
 -
 -static void DeleteThrownException(_Unwind_Exception *exceptionObject)
 -{
 -    // The argument exception has been thrown.
 -    _ASSERTE(std::uncaught_exception());
 -
 -    // Deleting it in this way will adjust the uncaught exceptions count.
 -    __cxa_begin_catch(exceptionObject);
 -    __cxa_end_catch();
 -}
 -
 -static void RunVectoredHandler(EXCEPTION_POINTERS *pExceptionPointers, _Unwind_Exception *exceptionObject, PVECTORED_EXCEPTION_HANDLER pHandler)
 -{
 -    if (pHandler != NULL)
 -    {
 -        EXCEPTION_DISPOSITION disposition = pHandler(pExceptionPointers);
 -        switch (disposition)
 -        {
 -        case EXCEPTION_CONTINUE_EXECUTION:
 -            {
 -                BOOL fNonContinuable = pExceptionPointers->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE;
 -                CONTEXT *context = pExceptionPointers->ContextRecord;
 -                if (fNonContinuable)
 -                {
 -                    RaiseException(EXCEPTION_NONCONTINUABLE_EXCEPTION,
 -                                   EXCEPTION_NONCONTINUABLE, 0, NULL);
 -                }
 -                else
 -                {
 -                    SetThreadContext(PAL_GetCurrentThread(), context);
 -                }
 -            }
 -            abort(); // should never reach here
 -        case EXCEPTION_CONTINUE_SEARCH:
 -            break;
 -        default:
 -            DeleteThrownException(exceptionObject);
 -            RaiseException(EXCEPTION_INVALID_DISPOSITION,
 -                           EXCEPTION_NONCONTINUABLE, 0, NULL);
 -            abort(); // should never reach here
 -        }
 -    }
 -}
 -
  PAL_NORETURN
  static void RtlpRaiseException(EXCEPTION_RECORD *ExceptionRecord)
  {