b311480e |
1 | // Copyright (c) 1998-1999 Matra Datavision |
973c2be1 |
2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
3 | // |
973c2be1 |
4 | // This file is part of Open CASCADE Technology software library. |
b311480e |
5 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
11 | // |
973c2be1 |
12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. |
7fd59977 |
14 | |
7fb9d6d5 |
15 | #include <Standard_Failure.hxx> |
42cf5bc1 |
16 | |
7fd59977 |
17 | #include <Standard_ErrorHandler.hxx> |
7fd59977 |
18 | #include <Standard_Macro.hxx> |
42cf5bc1 |
19 | #include <Standard_NoSuchObject.hxx> |
7fd59977 |
20 | #include <Standard_PCharacter.hxx> |
42cf5bc1 |
21 | #include <Standard_Type.hxx> |
22 | #include <Standard_TypeMismatch.hxx> |
7fd59977 |
23 | |
42cf5bc1 |
24 | #include <string.h> |
7fb9d6d5 |
25 | |
92efcf78 |
26 | IMPLEMENT_STANDARD_RTTIEXT(Standard_Failure,Standard_Transient) |
27 | |
7fb9d6d5 |
28 | namespace |
7fd59977 |
29 | { |
7fb9d6d5 |
30 | //! Global parameter defining default length of stack trace. |
31 | static Standard_Integer Standard_Failure_DefaultStackTraceLength = 0; |
32 | } |
33 | |
34 | // ======================================================================= |
35 | // function : StringRef::allocate_message |
36 | // purpose : |
37 | // ======================================================================= |
38 | Standard_Failure::StringRef* Standard_Failure::StringRef::allocate_message (const Standard_CString theString) |
39 | { |
40 | if (theString == NULL |
41 | || *theString == '\0') |
42 | { |
43 | return NULL; |
7fd59977 |
44 | } |
7fb9d6d5 |
45 | |
46 | const Standard_Size aLen = strlen (theString); |
47 | StringRef* aStrPtr = (StringRef* )malloc (aLen + sizeof(Standard_Integer) + 1); |
48 | if (aStrPtr != NULL) |
49 | { |
50 | strcpy ((char* )&aStrPtr->Message[0], theString); |
51 | aStrPtr->Counter = 1; |
52 | } |
53 | return aStrPtr; |
7fd59977 |
54 | } |
55 | |
7fb9d6d5 |
56 | // ======================================================================= |
57 | // function : StringRef::copy_message |
58 | // purpose : |
59 | // ======================================================================= |
60 | Standard_Failure::StringRef* Standard_Failure::StringRef::copy_message (Standard_Failure::StringRef* theString) |
7fd59977 |
61 | { |
7fb9d6d5 |
62 | if (theString == NULL) |
63 | { |
64 | return NULL; |
7fd59977 |
65 | } |
7fb9d6d5 |
66 | |
67 | ++theString->Counter; |
68 | return theString; |
7fd59977 |
69 | } |
70 | |
7fb9d6d5 |
71 | // ======================================================================= |
72 | // function : StringRef::deallocate_message |
73 | // purpose : |
74 | // ======================================================================= |
75 | void Standard_Failure::StringRef::deallocate_message (Standard_Failure::StringRef* theString) |
7fd59977 |
76 | { |
7fb9d6d5 |
77 | if (theString != NULL) |
78 | { |
79 | if (--theString->Counter == 0) |
80 | { |
81 | free ((void* )theString); |
82 | } |
7fd59977 |
83 | } |
84 | } |
85 | |
7fb9d6d5 |
86 | // ======================================================================= |
87 | // function : Standard_Failure |
88 | // purpose : |
89 | // ======================================================================= |
90 | Standard_Failure::Standard_Failure() |
91 | : myMessage (NULL), |
92 | myStackTrace (NULL) |
93 | { |
94 | const Standard_Integer aStackLength = Standard_Failure_DefaultStackTraceLength; |
95 | if (aStackLength > 0) |
96 | { |
97 | int aStackBufLen = Max (aStackLength * 200, 2048); |
98 | char* aStackBuffer = (char* )alloca (aStackBufLen); |
99 | if (aStackBuffer != NULL) |
100 | { |
101 | memset (aStackBuffer, 0, aStackBufLen); |
102 | if (Standard::StackTrace (aStackBuffer, aStackBufLen, aStackLength, NULL, 1)) |
103 | { |
104 | myStackTrace = StringRef::allocate_message (aStackBuffer); |
105 | } |
106 | } |
107 | } |
108 | } |
9775fa61 |
109 | |
7fb9d6d5 |
110 | // ======================================================================= |
111 | // function : Standard_Failure |
112 | // purpose : |
113 | // ======================================================================= |
114 | Standard_Failure::Standard_Failure (const Standard_CString theDesc) |
115 | : myMessage (NULL), |
116 | myStackTrace (NULL) |
7fd59977 |
117 | { |
7fb9d6d5 |
118 | myMessage = StringRef::allocate_message (theDesc); |
119 | const Standard_Integer aStackLength = Standard_Failure_DefaultStackTraceLength; |
120 | if (aStackLength > 0) |
121 | { |
122 | int aStackBufLen = Max (aStackLength * 200, 2048); |
123 | char* aStackBuffer = (char* )alloca (aStackBufLen); |
124 | if (aStackBuffer != NULL) |
125 | { |
126 | memset (aStackBuffer, 0, aStackBufLen); |
127 | Standard::StackTrace (aStackBuffer, aStackBufLen, aStackLength, NULL, 1); |
128 | myStackTrace = StringRef::allocate_message (aStackBuffer); |
129 | } |
130 | } |
7fd59977 |
131 | } |
132 | |
7fb9d6d5 |
133 | // ======================================================================= |
134 | // function : Standard_Failure |
135 | // purpose : |
136 | // ======================================================================= |
137 | Standard_Failure::Standard_Failure (const Standard_CString theDesc, |
138 | const Standard_CString theStackTrace) |
139 | : myMessage (NULL), |
140 | myStackTrace (NULL) |
7fd59977 |
141 | { |
7fb9d6d5 |
142 | myMessage = StringRef::allocate_message (theDesc); |
143 | myStackTrace = StringRef::allocate_message (theStackTrace); |
7fd59977 |
144 | } |
145 | |
7fb9d6d5 |
146 | // ======================================================================= |
147 | // function : Standard_Failure |
148 | // purpose : |
149 | // ======================================================================= |
150 | Standard_Failure::Standard_Failure (const Standard_Failure& theFailure) |
151 | : Standard_Transient (theFailure), |
152 | myMessage (NULL), |
153 | myStackTrace (NULL) |
7fd59977 |
154 | { |
7fb9d6d5 |
155 | myMessage = StringRef::copy_message (theFailure.myMessage); |
156 | myStackTrace = StringRef::copy_message (theFailure.myStackTrace); |
7fd59977 |
157 | } |
158 | |
7fb9d6d5 |
159 | // ======================================================================= |
160 | // function : ~Standard_Failure |
161 | // purpose : |
162 | // ======================================================================= |
4db4247a |
163 | Standard_Failure::~Standard_Failure() |
7fd59977 |
164 | { |
7fb9d6d5 |
165 | StringRef::deallocate_message (myMessage); |
166 | StringRef::deallocate_message (myStackTrace); |
7fd59977 |
167 | } |
168 | |
7fb9d6d5 |
169 | // ======================================================================= |
170 | // function : GetMessageString |
171 | // purpose : |
172 | // ======================================================================= |
173 | Standard_CString Standard_Failure::GetMessageString() const |
7fd59977 |
174 | { |
7fb9d6d5 |
175 | return myMessage != NULL |
176 | ? myMessage->GetMessage() |
177 | : ""; |
7fd59977 |
178 | } |
179 | |
7fb9d6d5 |
180 | // ======================================================================= |
181 | // function : SetMessageString |
182 | // purpose : |
183 | // ======================================================================= |
184 | void Standard_Failure::SetMessageString (const Standard_CString theDesc) |
7fd59977 |
185 | { |
7fb9d6d5 |
186 | if (theDesc == GetMessageString()) |
187 | { |
188 | return; |
189 | } |
190 | |
191 | StringRef::deallocate_message (myMessage); |
192 | myMessage = StringRef::allocate_message (theDesc); |
7fd59977 |
193 | } |
194 | |
7fb9d6d5 |
195 | // ======================================================================= |
196 | // function : GetStackString |
197 | // purpose : |
198 | // ======================================================================= |
199 | Standard_CString Standard_Failure::GetStackString() const |
200 | { |
201 | return myStackTrace != NULL |
202 | ? myStackTrace->GetMessage() |
203 | : ""; |
204 | } |
205 | |
206 | // ======================================================================= |
207 | // function : SetStackString |
208 | // purpose : |
209 | // ======================================================================= |
210 | void Standard_Failure::SetStackString (const Standard_CString theStack) |
211 | { |
212 | if (theStack == GetStackString()) |
213 | { |
214 | return; |
215 | } |
216 | |
217 | StringRef::deallocate_message (myStackTrace); |
218 | myStackTrace = StringRef::allocate_message (theStack); |
219 | } |
220 | |
7fb9d6d5 |
221 | // ======================================================================= |
222 | // function : Raise |
223 | // purpose : |
224 | // ======================================================================= |
225 | void Standard_Failure::Raise (const Standard_CString theDesc) |
7fd59977 |
226 | { |
7fb9d6d5 |
227 | Handle(Standard_Failure) aFailure = new Standard_Failure(); |
228 | aFailure->Reraise (theDesc); |
7fd59977 |
229 | } |
230 | |
7fb9d6d5 |
231 | // ======================================================================= |
232 | // function : Raise |
233 | // purpose : |
234 | // ======================================================================= |
235 | void Standard_Failure::Raise (const Standard_SStream& theReason) |
7fd59977 |
236 | { |
7fb9d6d5 |
237 | Handle(Standard_Failure) aFailure = new Standard_Failure(); |
238 | aFailure->Reraise (theReason); |
7fd59977 |
239 | } |
240 | |
7fb9d6d5 |
241 | // ======================================================================= |
242 | // function : Reraise |
243 | // purpose : |
244 | // ======================================================================= |
245 | void Standard_Failure::Reraise (const Standard_CString theDesc) |
7fd59977 |
246 | { |
7fb9d6d5 |
247 | SetMessageString (theDesc); |
7fd59977 |
248 | Reraise(); |
249 | } |
250 | |
7fb9d6d5 |
251 | // ======================================================================= |
252 | // function : Reraise |
253 | // purpose : |
254 | // ======================================================================= |
255 | void Standard_Failure::Reraise (const Standard_SStream& theReason) |
7fd59977 |
256 | { |
7fb9d6d5 |
257 | SetMessageString (theReason.str().c_str()); |
7fd59977 |
258 | Reraise(); |
259 | } |
260 | |
7fb9d6d5 |
261 | // ======================================================================= |
262 | // function : Reraise |
263 | // purpose : |
264 | // ======================================================================= |
265 | void Standard_Failure::Reraise() |
7fd59977 |
266 | { |
7fd59977 |
267 | Throw(); |
7fd59977 |
268 | } |
269 | |
7fb9d6d5 |
270 | // ======================================================================= |
271 | // function : Jump |
272 | // purpose : |
273 | // ======================================================================= |
69ff08ff |
274 | void Standard_Failure::Jump() |
7fd59977 |
275 | { |
9775fa61 |
276 | #if defined (OCC_CONVERT_SIGNALS) |
a01039b9 |
277 | Standard_ErrorHandler::Error (this); |
278 | Standard_ErrorHandler::Abort (this); |
7fd59977 |
279 | #else |
7fd59977 |
280 | Throw(); |
281 | #endif |
282 | } |
283 | |
7fb9d6d5 |
284 | // ======================================================================= |
285 | // function : Throw |
286 | // purpose : |
287 | // ======================================================================= |
7fd59977 |
288 | void Standard_Failure::Throw() const |
289 | { |
7fd59977 |
290 | throw *this; |
7fd59977 |
291 | } |
292 | |
7fb9d6d5 |
293 | // ======================================================================= |
294 | // function : Print |
295 | // purpose : |
296 | // ======================================================================= |
297 | void Standard_Failure::Print (Standard_OStream& theStream) const |
298 | { |
299 | if (myMessage != NULL) |
300 | { |
301 | theStream << DynamicType() << ": " << GetMessageString(); |
302 | } |
303 | else |
304 | { |
305 | theStream << DynamicType(); |
306 | } |
307 | if (myStackTrace != NULL) |
308 | { |
309 | theStream << GetStackString(); |
310 | } |
311 | } |
312 | |
313 | // ======================================================================= |
314 | // function : NewInstance |
315 | // purpose : |
316 | // ======================================================================= |
317 | Handle(Standard_Failure) Standard_Failure::NewInstance (Standard_CString theString) |
7fd59977 |
318 | { |
7fb9d6d5 |
319 | return new Standard_Failure (theString); |
7fd59977 |
320 | } |
321 | |
7fb9d6d5 |
322 | // ======================================================================= |
323 | // function : NewInstance |
324 | // purpose : |
325 | // ======================================================================= |
326 | Handle(Standard_Failure) Standard_Failure::NewInstance (Standard_CString theMessage, |
327 | Standard_CString theStackTrace) |
7fd59977 |
328 | { |
7fb9d6d5 |
329 | return new Standard_Failure (theMessage, theStackTrace); |
7fd59977 |
330 | } |
4db4247a |
331 | |
7fb9d6d5 |
332 | // ======================================================================= |
333 | // function : GetNbStackTraces |
334 | // purpose : |
335 | // ======================================================================= |
336 | Standard_Integer Standard_Failure::DefaultStackTraceLength() |
4db4247a |
337 | { |
7fb9d6d5 |
338 | return Standard_Failure_DefaultStackTraceLength; |
4db4247a |
339 | } |
340 | |
7fb9d6d5 |
341 | // ======================================================================= |
342 | // function : SetNbStackTraces |
343 | // purpose : |
344 | // ======================================================================= |
345 | void Standard_Failure::SetDefaultStackTraceLength (Standard_Integer theNbStackTraces) |
346 | { |
347 | Standard_Failure_DefaultStackTraceLength = theNbStackTraces; |
348 | } |