0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / Standard / Standard_ErrorHandler.hxx
CommitLineData
42cf5bc1 1// Created on: 1992-09-28
2// Created by: Ramin BARRETO
3// Copyright (c) 1992-1999 Matra Datavision
4// Copyright (c) 1999-2014 OPEN CASCADE SAS
5//
6// This file is part of Open CASCADE Technology software library.
7//
8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
13//
14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
16
17#ifndef _Standard_ErrorHandler_HeaderFile
18#define _Standard_ErrorHandler_HeaderFile
19
20#include <Standard.hxx>
42cf5bc1 21#include <Standard_Handle.hxx>
22
23#include <Standard_PErrorHandler.hxx>
24#include <Standard_JmpBuf.hxx>
25#include <Standard_HandlerStatus.hxx>
26#include <Standard_ThreadId.hxx>
42cf5bc1 27#include <Standard_Type.hxx>
c9246067 28
29//! @file
30//! Support of handling of C signals as C++-style exceptions, and implementation
31//! of C++ exception handling on platforms that do not implement these natively.
32//!
33//! The implementation is based on C long jumps.
34//!
c9246067 35//! If macro OCC_CONVERT_SIGNALS is defined, this enables macro OCC_CATCH_SIGNALS
36//! that can be used in the code (often inside try {} blocks) to convert C-style
37//! signals to standard C++ exceptions. This works only when OSD::SetSignal()
38//! is called to set appropriate signal handler. In the case of signal (like
39//! access violation, division by zero, etc.) it will jump to the nearest
40//! OCC_CATCH_SIGNALS in the call stack, which will then throw a C++ exception.
41//! This method is useful for Unix and Linux systems where C++ exceptions
42//! cannot be thrown from C signal handler.
43//!
44//! On Windows with MSVC compiler, exceptions can be thrown directly from
45//! signal handler, this OCC_CONVERT_SIGNALS is not needed. Note however that
46//! this requires that compiler option /EHa is used.
47
9775fa61 48#if defined(OCC_CONVERT_SIGNALS)
c9246067 49
50 // Exceptions are raied as usual, signal cause jumps in the nearest
51 // OCC_CATCH_SIGNALS and then thrown as exceptions.
52 #define OCC_CATCH_SIGNALS Standard_ErrorHandler _aHandler; \
53 if(setjmp(_aHandler.Label())) { \
54 _aHandler.Catches(STANDARD_TYPE(Standard_Failure)); \
55 _aHandler.Error()->Reraise(); \
56 }
57
6fab2d4f 58 // Suppress GCC warning "variable ... might be clobbered by 'longjmp' or 'vfork'"
f2139a7f 59 #if defined(__GNUC__) && ! defined(__INTEL_COMPILER) && ! defined(__clang__)
6fab2d4f 60 #pragma GCC diagnostic ignored "-Wclobbered"
61 #endif
62
c9246067 63#else
64
65 // Normal Exceptions (for example WNT with MSVC and option /GHa)
66 #define OCC_CATCH_SIGNALS
67
68#endif
69
42cf5bc1 70class Standard_Failure;
42cf5bc1 71
c9246067 72//! Class implementing mechanics of conversion of signals to exceptions.
73//!
74//! Each instance of it stores data for jump placement, thread id,
75//! and callbacks to be called during jump (for proper resource release).
76//!
77//! The active handlers are stored in the global stack, which is used
78//! to find appropriate handler when signal is raised.
42cf5bc1 79
80class Standard_ErrorHandler
81{
82public:
83
84 DEFINE_STANDARD_ALLOC
85
86
87 //! Create a ErrorHandler (to be used with try{}catch(){}).
88 //! It uses the "setjmp" and "longjmp" routines.
89 Standard_EXPORT Standard_ErrorHandler();
90
91 //! Unlinks and checks if there is a raised exception.
92 Standard_EXPORT void Destroy();
c9246067 93
94 //! Destructor
95 ~Standard_ErrorHandler()
96 {
97 Destroy();
98 }
42cf5bc1 99
100 //! Removes handler from the handlers list
101 Standard_EXPORT void Unlink();
102
103 //! Returns "True" if the caught exception has the same type
104 //! or inherits from "aType"
105 Standard_EXPORT Standard_Boolean Catches (const Handle(Standard_Type)& aType);
106
107 //! Returns label for jump
c9246067 108 Standard_JmpBuf& Label() { return myLabel; }
42cf5bc1 109
110 //! Returns the current Error.
111 Standard_EXPORT Handle(Standard_Failure) Error() const;
112
113 //! Returns the caught exception.
114 Standard_EXPORT static Handle(Standard_Failure) LastCaughtError();
115
116 //! Test if the code is currently running in a try block
117 Standard_EXPORT static Standard_Boolean IsInTryBlock();
118
42cf5bc1 119private:
42cf5bc1 120
121 //! A exception is raised but it is not yet caught.
122 //! So Abort the current function and transmit the exception
123 //! to "calling routines".
124 //! Warning: If no catch is prepared for this exception, it displays the
125 //! exception name and calls "exit(1)".
126 Standard_EXPORT static void Abort (const Handle(Standard_Failure)& theError);
127
128 //! Set the Error which will be transmitted to "calling routines".
129 Standard_EXPORT static void Error (const Handle(Standard_Failure)& aError);
130
c9246067 131 //! Returns the current handler (closest in the stack in the current execution thread)
42cf5bc1 132 Standard_EXPORT static Standard_PErrorHandler FindHandler (const Standard_HandlerStatus theStatus, const Standard_Boolean theUnlink);
133
536a3cb8 134public:
135 //! Defines a base class for callback objects that can be registered
136 //! in the OCC error handler (the class simulating C++ exceptions)
137 //! so as to be correctly destroyed when error handler is activated.
138 //!
139 //! Note that this is needed only when Open CASCADE is compiled with
9775fa61 140 //! OCC_CONVERT_SIGNALS options (i.e. on UNIX/Linux).
536a3cb8 141 //! In that case, raising OCC exception and/or signal will not cause
142 //! C++ stack unwinding and destruction of objects created in the stack.
143 //!
144 //! This class is intended to protect critical objects and operations in
145 //! the try {} catch {} block from being bypassed by OCC signal or exception.
146 //!
147 //! Inherit your object from that class, implement DestroyCallback() function,
148 //! and call Register/Unregister in critical points.
149 //!
150 //! Note that you must ensure that your object has life span longer than
151 //! that of the try {} block in which it calls Register().
152 class Callback
153 {
154 public:
155 DEFINE_STANDARD_ALLOC
156
157 //! Registers this callback object in the current error handler (if found).
59cfb82b 158 #if defined(OCC_CONVERT_SIGNALS)
159 Standard_EXPORT
160 #endif
161 void RegisterCallback();
536a3cb8 162
163 //! Unregisters this callback object from the error handler.
59cfb82b 164 #if defined(OCC_CONVERT_SIGNALS)
165 Standard_EXPORT
166 #endif
167 void UnregisterCallback();
536a3cb8 168
169 //! Destructor
59cfb82b 170 #if defined(OCC_CONVERT_SIGNALS)
171 Standard_EXPORT
172 #endif
173 virtual ~Callback();
536a3cb8 174
175 //! The callback function to perform necessary callback action.
176 //! Called by the exception handler when it is being destroyed but
177 //! still has this callback registered.
178 Standard_EXPORT virtual void DestroyCallback() = 0;
179
180 protected:
181
182 //! Empty constructor
59cfb82b 183 #if defined(OCC_CONVERT_SIGNALS)
184 Standard_EXPORT
185 #endif
186 Callback();
536a3cb8 187
188 private:
189 Standard_Address myHandler;
190 Standard_Address myPrev;
191 Standard_Address myNext;
192
193 friend class Standard_ErrorHandler;
194 };
195
c9246067 196private:
42cf5bc1 197
198 Standard_PErrorHandler myPrevious;
199 Handle(Standard_Failure) myCaughtError;
200 Standard_JmpBuf myLabel;
201 Standard_HandlerStatus myStatus;
202 Standard_ThreadId myThread;
536a3cb8 203 Callback* myCallbackPtr;
42cf5bc1 204
c9246067 205 friend class Standard_Failure;
42cf5bc1 206};
207
9775fa61 208// If OCC_CONVERT_SIGNALS is not defined,
536a3cb8 209// provide empty inline implementation
9775fa61 210#if ! defined(OCC_CONVERT_SIGNALS)
536a3cb8 211inline Standard_ErrorHandler::Callback::Callback ()
212 : myHandler(0), myPrev(0), myNext(0)
213{
214}
215inline Standard_ErrorHandler::Callback::~Callback ()
216{
1bd04b5a 217 (void)myHandler;
218 (void)myPrev;
536a3cb8 219}
220inline void Standard_ErrorHandler::Callback::RegisterCallback ()
221{
222}
223inline void Standard_ErrorHandler::Callback::UnregisterCallback ()
224{
225}
226#endif
227
228// Definition of the old name "Standard_ErrorHandlerCallback" was kept for compatibility
229typedef Standard_ErrorHandler::Callback Standard_ErrorHandlerCallback;
230
42cf5bc1 231#endif // _Standard_ErrorHandler_HeaderFile