Logo ROOT  
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/**
13Error handling routines.
14
15This file defines a number of global error handling routines:
16Warning(), Error(), SysError() and Fatal(). They all take a
17location string (where the error happened) and a printf style format
18string plus vararg's. In the end these functions call an
19errorhandler 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
47const char *kAssertMsg = "%s violated at line %d of `%s'";
48const char *kCheckMsg = "%s not true at line %d of `%s'";
49
50// Integrate with crash reporter.
51#ifdef __APPLE__
52extern "C" {
53static const char *__crashreporter_info__ = 0;
54asm(".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
64static 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
72again:
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.
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{
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
125void DefaultErrorHandler(Int_t level, Bool_t abort_bool, const char *location, const char *msg)
126{
127 if (gErrorIgnoreLevel == kUnset) {
129
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) {
193 gSystem->Abort();
194 } else
195 abort();
196 }
197}
198
199////////////////////////////////////////////////////////////////////////////////
200/// General error handler function. It calls the user set error handler.
201
202void 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
214again:
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
260void 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
269void 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
278void 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
288void 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
299void 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
310void 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
321void 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
332void 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]
346void 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}
int Int_t
Definition: CPyCppyy.h:43
const Bool_t kFALSE
Definition: RtypesCore.h:90
bool Bool_t
Definition: RtypesCore.h:61
const Bool_t kTRUE
Definition: RtypesCore.h:89
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
void Warning(const char *location, const char *va_(fmt),...)
Use this function in warning situations.
Definition: TError.cxx:332
Int_t gErrorAbortLevel
Definition: TError.cxx:44
static void DebugPrint(const char *fmt,...)
Print debugging message to stderr and, on Windows, to the system debugger.
Definition: TError.cxx:64
const char * kAssertMsg
Definition: TError.cxx:47
void DefaultErrorHandler(Int_t level, Bool_t abort_bool, const char *location, const char *msg)
The default error handler function.
Definition: TError.cxx:125
ErrorHandlerFunc_t GetErrorHandler()
Returns the current error handler function.
Definition: TError.cxx:116
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
static ErrorHandlerFunc_t gErrorHandler
Definition: TError.cxx:58
void Break(const char *location, const char *va_(fmt),...)
Use this function in case an error occurred.
Definition: TError.cxx:310
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 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
void Info(const char *location, const char *va_(fmt),...)
Use this function for informational messages.
Definition: TError.cxx:321
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
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
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
Int_t gErrorIgnoreLevel
Definition: TError.cxx:43
const char * kCheckMsg
Definition: TError.cxx:48
void Obsolete(const char *function, const char *asOfVers, const char *removedFromVers)
Use this function to declare a function obsolete.
Definition: TError.cxx:278
ErrorHandlerFunc_t SetErrorHandler(ErrorHandlerFunc_t newhandler)
Set an errorhandler function. Returns the old handler.
Definition: TError.cxx:106
Bool_t gPrintViaErrorHandler
Definition: TError.cxx:45
const Int_t kPrint
Definition: TError.h:36
const Int_t kError
Definition: TError.h:39
const Int_t kSysError
Definition: TError.h:41
const Int_t kUnset
Definition: TError.h:35
const Int_t kFatal
Definition: TError.h:42
const Int_t kBreak
Definition: TError.h:40
const Int_t kWarning
Definition: TError.h:38
void(* ErrorHandlerFunc_t)(int level, Bool_t abort, const char *location, const char *msg)
Definition: TError.h:46
const Int_t kInfo
Definition: TError.h:37
char * Form(const char *fmt,...)
char * StrDup(const char *str)
Duplicate the string str.
Definition: TString.cxx:2490
R__EXTERN TSystem * gSystem
Definition: TSystem.h:556
#define R__LOCKGUARD2(mutex)
#define R__VA_COPY(to, from)
Definition: Varargs.h:58
#define va_(arg)
Definition: Varargs.h:41
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
Basic string class.
Definition: TString.h:131
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition: TString.cxx:418
@ kIgnoreCase
Definition: TString.h:263
const char * Data() const
Definition: TString.h:364
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2289
virtual void Abort(int code=0)
Abort the application.
Definition: TSystem.cxx:722
virtual const char * GetError()
Return system error string.
Definition: TSystem.cxx:248
virtual void StackTrace()
Print a stack trace.
Definition: TSystem.cxx:730
This class implements a mutex interface.
Definition: TVirtualMutex.h:34
const Int_t n
Definition: legend1.C:16