mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-05-31 11:15:31 +03:00
232 lines
7.7 KiB
C++
232 lines
7.7 KiB
C++
// Created on: 1992-09-28
|
|
// Created by: Ramin BARRETO
|
|
// Copyright (c) 1992-1999 Matra Datavision
|
|
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
// by the Free Software Foundation, with special exception defined in the file
|
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
// distribution for complete text of the license and disclaimer of any warranty.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
#ifndef _Standard_ErrorHandler_HeaderFile
|
|
#define _Standard_ErrorHandler_HeaderFile
|
|
|
|
#include <Standard.hxx>
|
|
#include <Standard_Handle.hxx>
|
|
|
|
#include <Standard_PErrorHandler.hxx>
|
|
#include <Standard_JmpBuf.hxx>
|
|
#include <Standard_HandlerStatus.hxx>
|
|
#include <Standard_ThreadId.hxx>
|
|
#include <Standard_Type.hxx>
|
|
|
|
//! @file
|
|
//! Support of handling of C signals as C++-style exceptions, and implementation
|
|
//! of C++ exception handling on platforms that do not implement these natively.
|
|
//!
|
|
//! The implementation is based on C long jumps.
|
|
//!
|
|
//! If macro OCC_CONVERT_SIGNALS is defined, this enables macro OCC_CATCH_SIGNALS
|
|
//! that can be used in the code (often inside try {} blocks) to convert C-style
|
|
//! signals to standard C++ exceptions. This works only when OSD::SetSignal()
|
|
//! is called to set appropriate signal handler. In the case of signal (like
|
|
//! access violation, division by zero, etc.) it will jump to the nearest
|
|
//! OCC_CATCH_SIGNALS in the call stack, which will then throw a C++ exception.
|
|
//! This method is useful for Unix and Linux systems where C++ exceptions
|
|
//! cannot be thrown from C signal handler.
|
|
//!
|
|
//! On Windows with MSVC compiler, exceptions can be thrown directly from
|
|
//! signal handler, this OCC_CONVERT_SIGNALS is not needed. Note however that
|
|
//! this requires that compiler option /EHa is used.
|
|
|
|
#if defined(OCC_CONVERT_SIGNALS)
|
|
|
|
// Exceptions are raied as usual, signal cause jumps in the nearest
|
|
// OCC_CATCH_SIGNALS and then thrown as exceptions.
|
|
#define OCC_CATCH_SIGNALS Standard_ErrorHandler _aHandler; \
|
|
if(setjmp(_aHandler.Label())) { \
|
|
_aHandler.Catches(STANDARD_TYPE(Standard_Failure)); \
|
|
_aHandler.Error()->Reraise(); \
|
|
}
|
|
|
|
// Suppress GCC warning "variable ... might be clobbered by 'longjmp' or 'vfork'"
|
|
#if defined(__GNUC__) && ! defined(__INTEL_COMPILER) && ! defined(__clang__)
|
|
#pragma GCC diagnostic ignored "-Wclobbered"
|
|
#endif
|
|
|
|
#else
|
|
|
|
// Normal Exceptions (for example WNT with MSVC and option /GHa)
|
|
#define OCC_CATCH_SIGNALS
|
|
|
|
#endif
|
|
|
|
class Standard_Failure;
|
|
|
|
//! Class implementing mechanics of conversion of signals to exceptions.
|
|
//!
|
|
//! Each instance of it stores data for jump placement, thread id,
|
|
//! and callbacks to be called during jump (for proper resource release).
|
|
//!
|
|
//! The active handlers are stored in the global stack, which is used
|
|
//! to find appropriate handler when signal is raised.
|
|
|
|
class Standard_ErrorHandler
|
|
{
|
|
public:
|
|
|
|
DEFINE_STANDARD_ALLOC
|
|
|
|
|
|
//! Create a ErrorHandler (to be used with try{}catch(){}).
|
|
//! It uses the "setjmp" and "longjmp" routines.
|
|
Standard_EXPORT Standard_ErrorHandler();
|
|
|
|
//! Unlinks and checks if there is a raised exception.
|
|
Standard_EXPORT void Destroy();
|
|
|
|
//! Destructor
|
|
~Standard_ErrorHandler()
|
|
{
|
|
Destroy();
|
|
}
|
|
|
|
//! Removes handler from the handlers list
|
|
Standard_EXPORT void Unlink();
|
|
|
|
//! Returns "True" if the caught exception has the same type
|
|
//! or inherits from "aType"
|
|
Standard_EXPORT Standard_Boolean Catches (const Handle(Standard_Type)& aType);
|
|
|
|
//! Returns label for jump
|
|
Standard_JmpBuf& Label() { return myLabel; }
|
|
|
|
//! Returns the current Error.
|
|
Standard_EXPORT Handle(Standard_Failure) Error() const;
|
|
|
|
//! Returns the caught exception.
|
|
Standard_EXPORT static Handle(Standard_Failure) LastCaughtError();
|
|
|
|
//! Test if the code is currently running in a try block
|
|
Standard_EXPORT static Standard_Boolean IsInTryBlock();
|
|
|
|
private:
|
|
|
|
//! A exception is raised but it is not yet caught.
|
|
//! So Abort the current function and transmit the exception
|
|
//! to "calling routines".
|
|
//! Warning: If no catch is prepared for this exception, it displays the
|
|
//! exception name and calls "exit(1)".
|
|
Standard_EXPORT static void Abort (const Handle(Standard_Failure)& theError);
|
|
|
|
//! Set the Error which will be transmitted to "calling routines".
|
|
Standard_EXPORT static void Error (const Handle(Standard_Failure)& aError);
|
|
|
|
//! Returns the current handler (closest in the stack in the current execution thread)
|
|
Standard_EXPORT static Standard_PErrorHandler FindHandler (const Standard_HandlerStatus theStatus, const Standard_Boolean theUnlink);
|
|
|
|
public:
|
|
//! Defines a base class for callback objects that can be registered
|
|
//! in the OCC error handler (the class simulating C++ exceptions)
|
|
//! so as to be correctly destroyed when error handler is activated.
|
|
//!
|
|
//! Note that this is needed only when Open CASCADE is compiled with
|
|
//! OCC_CONVERT_SIGNALS options (i.e. on UNIX/Linux).
|
|
//! In that case, raising OCC exception and/or signal will not cause
|
|
//! C++ stack unwinding and destruction of objects created in the stack.
|
|
//!
|
|
//! This class is intended to protect critical objects and operations in
|
|
//! the try {} catch {} block from being bypassed by OCC signal or exception.
|
|
//!
|
|
//! Inherit your object from that class, implement DestroyCallback() function,
|
|
//! and call Register/Unregister in critical points.
|
|
//!
|
|
//! Note that you must ensure that your object has life span longer than
|
|
//! that of the try {} block in which it calls Register().
|
|
class Callback
|
|
{
|
|
public:
|
|
DEFINE_STANDARD_ALLOC
|
|
|
|
//! Registers this callback object in the current error handler (if found).
|
|
#if defined(OCC_CONVERT_SIGNALS)
|
|
Standard_EXPORT
|
|
#endif
|
|
void RegisterCallback();
|
|
|
|
//! Unregisters this callback object from the error handler.
|
|
#if defined(OCC_CONVERT_SIGNALS)
|
|
Standard_EXPORT
|
|
#endif
|
|
void UnregisterCallback();
|
|
|
|
//! Destructor
|
|
#if defined(OCC_CONVERT_SIGNALS)
|
|
Standard_EXPORT
|
|
#endif
|
|
virtual ~Callback();
|
|
|
|
//! The callback function to perform necessary callback action.
|
|
//! Called by the exception handler when it is being destroyed but
|
|
//! still has this callback registered.
|
|
Standard_EXPORT virtual void DestroyCallback() = 0;
|
|
|
|
protected:
|
|
|
|
//! Empty constructor
|
|
#if defined(OCC_CONVERT_SIGNALS)
|
|
Standard_EXPORT
|
|
#endif
|
|
Callback();
|
|
|
|
private:
|
|
Standard_Address myHandler;
|
|
Standard_Address myPrev;
|
|
Standard_Address myNext;
|
|
|
|
friend class Standard_ErrorHandler;
|
|
};
|
|
|
|
private:
|
|
|
|
Standard_PErrorHandler myPrevious;
|
|
Handle(Standard_Failure) myCaughtError;
|
|
Standard_JmpBuf myLabel;
|
|
Standard_HandlerStatus myStatus;
|
|
Standard_ThreadId myThread;
|
|
Callback* myCallbackPtr;
|
|
|
|
friend class Standard_Failure;
|
|
};
|
|
|
|
// If OCC_CONVERT_SIGNALS is not defined,
|
|
// provide empty inline implementation
|
|
#if ! defined(OCC_CONVERT_SIGNALS)
|
|
inline Standard_ErrorHandler::Callback::Callback ()
|
|
: myHandler(0), myPrev(0), myNext(0)
|
|
{
|
|
}
|
|
inline Standard_ErrorHandler::Callback::~Callback ()
|
|
{
|
|
(void)myHandler;
|
|
(void)myPrev;
|
|
}
|
|
inline void Standard_ErrorHandler::Callback::RegisterCallback ()
|
|
{
|
|
}
|
|
inline void Standard_ErrorHandler::Callback::UnregisterCallback ()
|
|
{
|
|
}
|
|
#endif
|
|
|
|
// Definition of the old name "Standard_ErrorHandlerCallback" was kept for compatibility
|
|
typedef Standard_ErrorHandler::Callback Standard_ErrorHandlerCallback;
|
|
|
|
#endif // _Standard_ErrorHandler_HeaderFile
|