1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #include <Standard_Failure.hxx>
17 #include <Standard_ErrorHandler.hxx>
18 #include <Standard_Macro.hxx>
19 #include <Standard_NoSuchObject.hxx>
20 #include <Standard_PCharacter.hxx>
21 #include <Standard_Type.hxx>
22 #include <Standard_TypeMismatch.hxx>
26 IMPLEMENT_STANDARD_RTTIEXT(Standard_Failure,Standard_Transient)
30 //! Global parameter defining default length of stack trace.
31 static Standard_Integer Standard_Failure_DefaultStackTraceLength = 0;
34 // =======================================================================
35 // function : StringRef::allocate_message
37 // =======================================================================
38 Standard_Failure::StringRef* Standard_Failure::StringRef::allocate_message (const Standard_CString theString)
41 || *theString == '\0')
46 const Standard_Size aLen = strlen (theString);
47 StringRef* aStrPtr = (StringRef* )malloc (aLen + sizeof(Standard_Integer) + 1);
50 strcpy ((char* )&aStrPtr->Message[0], theString);
56 // =======================================================================
57 // function : StringRef::copy_message
59 // =======================================================================
60 Standard_Failure::StringRef* Standard_Failure::StringRef::copy_message (Standard_Failure::StringRef* theString)
62 if (theString == NULL)
71 // =======================================================================
72 // function : StringRef::deallocate_message
74 // =======================================================================
75 void Standard_Failure::StringRef::deallocate_message (Standard_Failure::StringRef* theString)
77 if (theString != NULL)
79 if (--theString->Counter == 0)
81 free ((void* )theString);
86 // =======================================================================
87 // function : Standard_Failure
89 // =======================================================================
90 Standard_Failure::Standard_Failure()
94 const Standard_Integer aStackLength = Standard_Failure_DefaultStackTraceLength;
97 int aStackBufLen = Max (aStackLength * 200, 2048);
98 char* aStackBuffer = (char* )alloca (aStackBufLen);
99 if (aStackBuffer != NULL)
101 memset (aStackBuffer, 0, aStackBufLen);
102 if (Standard::StackTrace (aStackBuffer, aStackBufLen, aStackLength, NULL, 1))
104 myStackTrace = StringRef::allocate_message (aStackBuffer);
110 // =======================================================================
111 // function : Standard_Failure
113 // =======================================================================
114 Standard_Failure::Standard_Failure (const Standard_CString theDesc)
118 myMessage = StringRef::allocate_message (theDesc);
119 const Standard_Integer aStackLength = Standard_Failure_DefaultStackTraceLength;
120 if (aStackLength > 0)
122 int aStackBufLen = Max (aStackLength * 200, 2048);
123 char* aStackBuffer = (char* )alloca (aStackBufLen);
124 if (aStackBuffer != NULL)
126 memset (aStackBuffer, 0, aStackBufLen);
127 Standard::StackTrace (aStackBuffer, aStackBufLen, aStackLength, NULL, 1);
128 myStackTrace = StringRef::allocate_message (aStackBuffer);
133 // =======================================================================
134 // function : Standard_Failure
136 // =======================================================================
137 Standard_Failure::Standard_Failure (const Standard_CString theDesc,
138 const Standard_CString theStackTrace)
142 myMessage = StringRef::allocate_message (theDesc);
143 myStackTrace = StringRef::allocate_message (theStackTrace);
146 // =======================================================================
147 // function : Standard_Failure
149 // =======================================================================
150 Standard_Failure::Standard_Failure (const Standard_Failure& theFailure)
151 : Standard_Transient (theFailure),
155 myMessage = StringRef::copy_message (theFailure.myMessage);
156 myStackTrace = StringRef::copy_message (theFailure.myStackTrace);
159 // =======================================================================
160 // function : ~Standard_Failure
162 // =======================================================================
163 Standard_Failure::~Standard_Failure()
165 StringRef::deallocate_message (myMessage);
166 StringRef::deallocate_message (myStackTrace);
169 // =======================================================================
170 // function : GetMessageString
172 // =======================================================================
173 Standard_CString Standard_Failure::GetMessageString() const
175 return myMessage != NULL
176 ? myMessage->GetMessage()
180 // =======================================================================
181 // function : SetMessageString
183 // =======================================================================
184 void Standard_Failure::SetMessageString (const Standard_CString theDesc)
186 if (theDesc == GetMessageString())
191 StringRef::deallocate_message (myMessage);
192 myMessage = StringRef::allocate_message (theDesc);
195 // =======================================================================
196 // function : GetStackString
198 // =======================================================================
199 Standard_CString Standard_Failure::GetStackString() const
201 return myStackTrace != NULL
202 ? myStackTrace->GetMessage()
206 // =======================================================================
207 // function : SetStackString
209 // =======================================================================
210 void Standard_Failure::SetStackString (const Standard_CString theStack)
212 if (theStack == GetStackString())
217 StringRef::deallocate_message (myStackTrace);
218 myStackTrace = StringRef::allocate_message (theStack);
221 // =======================================================================
224 // =======================================================================
225 void Standard_Failure::Raise (const Standard_CString theDesc)
227 Handle(Standard_Failure) aFailure = new Standard_Failure();
228 aFailure->Reraise (theDesc);
231 // =======================================================================
234 // =======================================================================
235 void Standard_Failure::Raise (const Standard_SStream& theReason)
237 Handle(Standard_Failure) aFailure = new Standard_Failure();
238 aFailure->Reraise (theReason);
241 // =======================================================================
242 // function : Reraise
244 // =======================================================================
245 void Standard_Failure::Reraise (const Standard_CString theDesc)
247 SetMessageString (theDesc);
251 // =======================================================================
252 // function : Reraise
254 // =======================================================================
255 void Standard_Failure::Reraise (const Standard_SStream& theReason)
257 SetMessageString (theReason.str().c_str());
261 // =======================================================================
262 // function : Reraise
264 // =======================================================================
265 void Standard_Failure::Reraise()
270 // =======================================================================
273 // =======================================================================
274 void Standard_Failure::Jump()
276 #if defined (OCC_CONVERT_SIGNALS)
277 Standard_ErrorHandler::Error (this);
278 Standard_ErrorHandler::Abort (this);
284 // =======================================================================
287 // =======================================================================
288 void Standard_Failure::Throw() const
293 // =======================================================================
296 // =======================================================================
297 void Standard_Failure::Print (Standard_OStream& theStream) const
299 if (myMessage != NULL)
301 theStream << DynamicType() << ": " << GetMessageString();
305 theStream << DynamicType();
307 if (myStackTrace != NULL)
309 theStream << GetStackString();
313 // =======================================================================
314 // function : NewInstance
316 // =======================================================================
317 Handle(Standard_Failure) Standard_Failure::NewInstance (Standard_CString theString)
319 return new Standard_Failure (theString);
322 // =======================================================================
323 // function : NewInstance
325 // =======================================================================
326 Handle(Standard_Failure) Standard_Failure::NewInstance (Standard_CString theMessage,
327 Standard_CString theStackTrace)
329 return new Standard_Failure (theMessage, theStackTrace);
332 // =======================================================================
333 // function : GetNbStackTraces
335 // =======================================================================
336 Standard_Integer Standard_Failure::DefaultStackTraceLength()
338 return Standard_Failure_DefaultStackTraceLength;
341 // =======================================================================
342 // function : SetNbStackTraces
344 // =======================================================================
345 void Standard_Failure::SetDefaultStackTraceLength (Standard_Integer theNbStackTraces)
347 Standard_Failure_DefaultStackTraceLength = theNbStackTraces;