Logo ROOT   6.10/09
Reference Guide
TError.cxx
Go to the documentation of this file.
1 // @(#)root/base:$Id$
2 // Author: Fons Rademakers 29/07/95
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /**
13 Error handling routines.
14 
15 This file defines a number of global error handling routines:
16 Warning(), Error(), SysError() and Fatal(). They all take a
17 location string (where the error happened) and a printf style format
18 string plus vararg's. In the end these functions call an
19 errorhandler function. By default DefaultErrorHandler() is used.
20 */
21 
22 #ifdef WIN32
23 #include <windows.h>
24 #endif
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include "snprintf.h"
29 #include "Varargs.h"
30 #include "Riostream.h"
31 #include "TError.h"
32 #include "TSystem.h"
33 #include "TString.h"
34 #include "TEnv.h"
35 #include "TVirtualMutex.h"
36 #include "ThreadLocalStorage.h"
37 
38 // Mutex for error and error format protection
39 // (exported to be used for similar cases in other classes)
40 
42 
46 
47 const char *kAssertMsg = "%s violated at line %d of `%s'";
48 const char *kCheckMsg = "%s not true at line %d of `%s'";
49 
50 // Integrate with crash reporter.
51 #ifdef __APPLE__
52 extern "C" {
53 static const char *__crashreporter_info__ = 0;
54 asm(".desc ___crashreporter_info__, 0x10");
55 }
56 #endif
57 
59 
60 
61 ////////////////////////////////////////////////////////////////////////////////
62 /// Print debugging message to stderr and, on Windows, to the system debugger.
63 
64 static void DebugPrint(const char *fmt, ...)
65 {
66  TTHREAD_TLS(Int_t) buf_size = 2048;
67  TTHREAD_TLS(char*) buf = 0;
68 
69  va_list ap;
70  va_start(ap, fmt);
71 
72 again:
73  if (!buf)
74  buf = new char[buf_size];
75 
76  Int_t n = vsnprintf(buf, buf_size, fmt, ap);
77  // old vsnprintf's return -1 if string is truncated new ones return
78  // total number of characters that would have been written
79  if (n == -1 || n >= buf_size) {
80  if (n == -1)
81  buf_size *= 2;
82  else
83  buf_size = n+1;
84  delete [] buf;
85  buf = 0;
86  va_end(ap);
87  va_start(ap, fmt);
88  goto again;
89  }
90  va_end(ap);
91 
92  // Serialize the actual printing.
93  R__LOCKGUARD2(gErrorMutex);
94 
95  const char *toprint = buf; // Work around for older platform where we use TThreadTLSWrapper
96  fprintf(stderr, "%s", toprint);
97 
98 #ifdef WIN32
99  ::OutputDebugString(buf);
100 #endif
101 }
102 
103 ////////////////////////////////////////////////////////////////////////////////
104 /// Set an errorhandler function. Returns the old handler.
105 
107 {
108  ErrorHandlerFunc_t oldhandler = gErrorHandler;
109  gErrorHandler = newhandler;
110  return oldhandler;
111 }
112 
113 ////////////////////////////////////////////////////////////////////////////////
114 /// Returns the current error handler function.
115 
117 {
118  return gErrorHandler;
119 }
120 
121 ////////////////////////////////////////////////////////////////////////////////
122 /// The default error handler function. It prints the message on stderr and
123 /// if abort is set it aborts the application.
124 
125 void DefaultErrorHandler(Int_t level, Bool_t abort_bool, const char *location, const char *msg)
126 {
127  if (gErrorIgnoreLevel == kUnset) {
128  R__LOCKGUARD2(gErrorMutex);
129 
130  gErrorIgnoreLevel = 0;
131  if (gEnv) {
132  TString slevel = gEnv->GetValue("Root.ErrorIgnoreLevel", "Print");
133  if (!slevel.CompareTo("Print", TString::kIgnoreCase))
135  else if (!slevel.CompareTo("Info", TString::kIgnoreCase))
137  else if (!slevel.CompareTo("Warning", TString::kIgnoreCase))
139  else if (!slevel.CompareTo("Error", TString::kIgnoreCase))
141  else if (!slevel.CompareTo("Break", TString::kIgnoreCase))
143  else if (!slevel.CompareTo("SysError", TString::kIgnoreCase))
145  else if (!slevel.CompareTo("Fatal", TString::kIgnoreCase))
147  }
148  }
149 
150  if (level < gErrorIgnoreLevel)
151  return;
152 
153  const char *type = 0;
154 
155  if (level >= kInfo)
156  type = "Info";
157  if (level >= kWarning)
158  type = "Warning";
159  if (level >= kError)
160  type = "Error";
161  if (level >= kBreak)
162  type = "\n *** Break ***";
163  if (level >= kSysError)
164  type = "SysError";
165  if (level >= kFatal)
166  type = "Fatal";
167 
168  TString smsg;
169  if (level >= kPrint && level < kInfo)
170  smsg.Form("%s", msg);
171  else if (level >= kBreak && level < kSysError)
172  smsg.Form("%s %s", type, msg);
173  else if (!location || !location[0])
174  smsg.Form("%s: %s", type, msg);
175  else
176  smsg.Form("%s in <%s>: %s", type, location, msg);
177 
178  DebugPrint("%s\n", smsg.Data());
179 
180  fflush(stderr);
181  if (abort_bool) {
182 
183 #ifdef __APPLE__
184  if (__crashreporter_info__)
185  delete [] __crashreporter_info__;
186  __crashreporter_info__ = StrDup(smsg);
187 #endif
188 
189  DebugPrint("aborting\n");
190  fflush(stderr);
191  if (gSystem) {
192  gSystem->StackTrace();
193  gSystem->Abort();
194  } else
195  abort();
196  }
197 }
198 
199 ////////////////////////////////////////////////////////////////////////////////
200 /// General error handler function. It calls the user set error handler.
201 
202 void ErrorHandler(Int_t level, const char *location, const char *fmt, va_list ap)
203 {
204  TTHREAD_TLS(Int_t) buf_size(256);
205  TTHREAD_TLS(char*) buf_storage(0);
206 
207  char small_buf[256];
208  char *buf = buf_storage ? buf_storage : small_buf;
209 
210  int vc = 0;
211  va_list sap;
212  R__VA_COPY(sap, ap);
213 
214 again:
215  if (!buf) {
216  buf_storage = buf = new char[buf_size];
217  }
218 
219  if (!fmt)
220  fmt = "no error message provided";
221 
222  Int_t n = vsnprintf(buf, buf_size, fmt, ap);
223  // old vsnprintf's return -1 if string is truncated new ones return
224  // total number of characters that would have been written
225  if (n == -1 || n >= buf_size) {
226  if (n == -1)
227  buf_size *= 2;
228  else
229  buf_size = n+1;
230  if (buf != &(small_buf[0])) delete [] buf;
231  buf = 0;
232  va_end(ap);
233  R__VA_COPY(ap, sap);
234  vc = 1;
235  goto again;
236  }
237  va_end(sap);
238  if (vc)
239  va_end(ap);
240 
241  char *bp;
242  if (level >= kSysError && level < kFatal) {
243  const char *toprint = buf; // Work around for older platform where we use TThreadTLSWrapper
244  bp = Form("%s (%s)", toprint, gSystem->GetError());
245  } else
246  bp = buf;
247 
248  if (level != kFatal)
249  gErrorHandler(level, level >= gErrorAbortLevel, location, bp);
250  else
251  gErrorHandler(level, kTRUE, location, bp);
252 }
253 
254 ////////////////////////////////////////////////////////////////////////////////
255 /// This function can be used in abstract base classes in case one does
256 /// not want to make the class a "real" (in C++ sense) ABC. If this
257 /// function is called it will warn the user that the function should
258 /// have been overridden.
259 
260 void AbstractMethod(const char *method)
261 {
262  Warning(method, "this method must be overridden!");
263 }
264 
265 ////////////////////////////////////////////////////////////////////////////////
266 /// This function can be used in classes that should override a certain
267 /// function, but in the inherited class the function makes no sense.
268 
269 void MayNotUse(const char *method)
270 {
271  Warning(method, "may not use this method");
272 }
273 
274 ////////////////////////////////////////////////////////////////////////////////
275 /// Use this function to declare a function obsolete. Specify as of which version
276 /// the method is obsolete and as from which version it will be removed.
277 
278 void Obsolete(const char *function, const char *asOfVers, const char *removedFromVers)
279 {
280  TString mess;
281  mess.Form("obsolete as of %s and will be removed from %s", asOfVers, removedFromVers);
282  Warning(function, "%s", mess.Data());
283 }
284 
285 ////////////////////////////////////////////////////////////////////////////////
286 /// Use this function in case an error occurred.
287 
288 void Error(const char *location, const char *va_(fmt), ...)
289 {
290  va_list ap;
291  va_start(ap,va_(fmt));
292  ErrorHandler(kError, location, va_(fmt), ap);
293  va_end(ap);
294 }
295 
296 ////////////////////////////////////////////////////////////////////////////////
297 /// Use this function in case a system (OS or GUI) related error occurred.
298 
299 void SysError(const char *location, const char *va_(fmt), ...)
300 {
301  va_list ap;
302  va_start(ap, va_(fmt));
303  ErrorHandler(kSysError, location, va_(fmt), ap);
304  va_end(ap);
305 }
306 
307 ////////////////////////////////////////////////////////////////////////////////
308 /// Use this function in case an error occurred.
309 
310 void Break(const char *location, const char *va_(fmt), ...)
311 {
312  va_list ap;
313  va_start(ap,va_(fmt));
314  ErrorHandler(kBreak, location, va_(fmt), ap);
315  va_end(ap);
316 }
317 
318 ////////////////////////////////////////////////////////////////////////////////
319 /// Use this function for informational messages.
320 
321 void Info(const char *location, const char *va_(fmt), ...)
322 {
323  va_list ap;
324  va_start(ap,va_(fmt));
325  ErrorHandler(kInfo, location, va_(fmt), ap);
326  va_end(ap);
327 }
328 
329 ////////////////////////////////////////////////////////////////////////////////
330 /// Use this function in warning situations.
331 
332 void Warning(const char *location, const char *va_(fmt), ...)
333 {
334  va_list ap;
335  va_start(ap,va_(fmt));
336  ErrorHandler(kWarning, location, va_(fmt), ap);
337  va_end(ap);
338 }
339 
340 ////////////////////////////////////////////////////////////////////////////////
341 /// Use this function in case of a fatal error. It will abort the program.
342 
343 // Fatal() *might* not abort the program (if gAbortLevel > kFatal) - but for all
344 // reasonable settings it *will* abort. So let's be reasonable wrt Coverity:
345 // coverity[+kill]
346 void Fatal(const char *location, const char *va_(fmt), ...)
347 {
348  va_list ap;
349  va_start(ap,va_(fmt));
350  ErrorHandler(kFatal, location, va_(fmt), ap);
351  va_end(ap);
352 }
static ErrorHandlerFunc_t gErrorHandler
Definition: TError.cxx:58
void DefaultErrorHandler(Int_t level, Bool_t abort_bool, const char *location, const char *msg)
The default error handler function.
Definition: TError.cxx:125
void SysError(const char *location, const char *va_(fmt),...)
Use this function in case a system (OS or GUI) related error occurred.
Definition: TError.cxx:299
virtual void StackTrace()
Print a stack trace.
Definition: TSystem.cxx:739
const char * kCheckMsg
Definition: TError.cxx:48
void MayNotUse(const char *method)
This function can be used in classes that should override a certain function, but in the inherited cl...
Definition: TError.cxx:269
This class implements a mutex interface.
Definition: TVirtualMutex.h:32
Basic string class.
Definition: TString.h:129
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
ErrorHandlerFunc_t GetErrorHandler()
Returns the current error handler function.
Definition: TError.cxx:116
Int_t gErrorAbortLevel
Definition: TError.cxx:44
const Int_t kBreak
Definition: TError.h:40
void Warning(const char *location, const char *va_(fmt),...)
Use this function in warning situations.
Definition: TError.cxx:332
const Int_t kSysError
Definition: TError.h:41
const Int_t kFatal
Definition: TError.h:42
#define va_(arg)
Definition: Varargs.h:41
void Error(const char *location, const char *va_(fmt),...)
Use this function in case an error occurred.
Definition: TError.cxx:288
TVirtualMutex * gErrorMutex
Error handling routines.
Definition: TError.cxx:41
void Fatal(const char *location, const char *va_(fmt),...)
Use this function in case of a fatal error. It will abort the program.
Definition: TError.cxx:346
const Int_t kUnset
Definition: TError.h:35
static void DebugPrint(const char *fmt,...)
Print debugging message to stderr and, on Windows, to the system debugger.
Definition: TError.cxx:64
const Int_t kPrint
Definition: TError.h:36
#define R__VA_COPY(to, from)
Definition: Varargs.h:58
const Int_t kInfo
Definition: TError.h:37
R__EXTERN TSystem * gSystem
Definition: TSystem.h:539
virtual Int_t GetValue(const char *name, Int_t dflt)
Returns the integer value for a resource.
Definition: TEnv.cxx:482
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2332
char * Form(const char *fmt,...)
const Int_t kWarning
Definition: TError.h:38
virtual void Abort(int code=0)
Abort the application.
Definition: TSystem.cxx:731
char * StrDup(const char *str)
Duplicate the string str.
Definition: TString.cxx:2524
#define R__LOCKGUARD2(mutex)
const Bool_t kFALSE
Definition: RtypesCore.h:92
void Obsolete(const char *function, const char *asOfVers, const char *removedFromVers)
Use this function to declare a function obsolete.
Definition: TError.cxx:278
int type
Definition: TGX11.cxx:120
R__EXTERN TEnv * gEnv
Definition: TEnv.h:170
void(* ErrorHandlerFunc_t)(int level, Bool_t abort, const char *location, const char *msg)
Definition: TError.h:46
ErrorHandlerFunc_t SetErrorHandler(ErrorHandlerFunc_t newhandler)
Set an errorhandler function. Returns the old handler.
Definition: TError.cxx:106
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition: TString.cxx:396
void AbstractMethod(const char *method)
This function can be used in abstract base classes in case one does not want to make the class a "rea...
Definition: TError.cxx:260
Int_t gErrorIgnoreLevel
Definition: TError.cxx:43
void Info(const char *location, const char *va_(fmt),...)
Use this function for informational messages.
Definition: TError.cxx:321
const Int_t kError
Definition: TError.h:39
void Break(const char *location, const char *va_(fmt),...)
Use this function in case an error occurred.
Definition: TError.cxx:310
const char * kAssertMsg
Definition: TError.cxx:47
const Bool_t kTRUE
Definition: RtypesCore.h:91
void ErrorHandler(Int_t level, const char *location, const char *fmt, va_list ap)
General error handler function. It calls the user set error handler.
Definition: TError.cxx:202
const Int_t n
Definition: legend1.C:16
Bool_t gPrintViaErrorHandler
Definition: TError.cxx:45
virtual const char * GetError()
Return system error string.
Definition: TSystem.cxx:257
const char * Data() const
Definition: TString.h:347