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