Logo ROOT  
Reference Guide
TErrorDefaultHandler.cxx
Go to the documentation of this file.
1/// \file TErrorDefaultHandler.cxx
2/// \date 2020-06-14
3
4/*************************************************************************
5 * Copyright (C) 1995-2020, 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#ifdef WIN32
13#include <windows.h>
14#endif
15
16#include <TEnv.h>
17#include <TError.h>
18#include <ThreadLocalStorage.h>
19#include <TSystem.h>
20#include <Varargs.h>
21
22#include <cstdio>
23#include <cstdlib>
24#include <cctype> // for tolower
25#include <cstring> // for strdup
26#include <mutex>
27
28// Integrate with macOS crash reporter.
29#ifdef __APPLE__
30extern "C" {
31static const char *__crashreporter_info__ = 0;
32asm(".desc ___crashreporter_info__, 0x10");
33}
34#endif
35
36
37/// Serializes error output, destructed by the gROOT destructor via ReleaseDefaultErrorHandler()
38static std::mutex *GetErrorMutex() {
39 static std::mutex *m = new std::mutex();
40 return m;
41}
42
43
44namespace ROOT {
45namespace Internal {
46
48{
49 delete GetErrorMutex();
50}
51
52} // Internal namespace
53} // ROOT namespace
54
55
56/// Print debugging message to stderr and, on Windows, to the system debugger.
57static void DebugPrint(const char *fmt, ...)
58{
59 TTHREAD_TLS(Int_t) buf_size = 2048;
60 TTHREAD_TLS(char*) buf = nullptr;
61
62 va_list ap;
63 va_start(ap, fmt);
64
65again:
66 if (!buf)
67 buf = new char[buf_size];
68
69 Int_t n = vsnprintf(buf, buf_size, fmt, ap);
70 // old vsnprintf's return -1 if string is truncated new ones return
71 // total number of characters that would have been written
72 if (n == -1 || n >= buf_size) {
73 if (n == -1)
74 buf_size *= 2;
75 else
76 buf_size = n+1;
77 delete [] buf;
78 buf = nullptr;
79 va_end(ap);
80 va_start(ap, fmt);
81 goto again;
82 }
83 va_end(ap);
84
85 // Serialize the actual printing.
86 std::lock_guard<std::mutex> guard(*GetErrorMutex());
87
88 const char *toprint = buf; // Work around for older platform where we use TThreadTLSWrapper
89 fprintf(stderr, "%s", toprint);
90
91#ifdef WIN32
92 ::OutputDebugString(buf);
93#endif
94}
95
96
97/// The default error handler function. It prints the message on stderr and
98/// if abort is set it aborts the application. Replaces the minimal error handler
99/// of TError.h as part of the gROOT construction. TError's minimal handler is put
100/// back in place during the gROOT destruction.
101void DefaultErrorHandler(Int_t level, Bool_t abort_bool, const char *location, const char *msg)
102{
103 if (gErrorIgnoreLevel == kUnset) {
104 std::lock_guard<std::mutex> guard(*GetErrorMutex());
105
107 if (gEnv) {
108 std::string slevel;
109 auto cstrlevel = gEnv->GetValue("Root.ErrorIgnoreLevel", "Print");
110 while (cstrlevel && *cstrlevel) {
111 slevel.push_back(tolower(*cstrlevel));
112 cstrlevel++;
113 }
114
115 if (slevel == "print")
117 else if (slevel == "info")
119 else if (slevel == "warning")
121 else if (slevel == "error")
123 else if (slevel == "break")
125 else if (slevel == "syserror")
127 else if (slevel == "fatal")
129 }
130 }
131
132 if (level < gErrorIgnoreLevel)
133 return;
134
135 const char *type = nullptr;
136
137 if (level >= kInfo)
138 type = "Info";
139 if (level >= kWarning)
140 type = "Warning";
141 if (level >= kError)
142 type = "Error";
143 if (level >= kBreak)
144 type = "\n *** Break ***";
145 if (level >= kSysError)
146 type = "SysError";
147 if (level >= kFatal)
148 type = "Fatal";
149
150 std::string smsg;
151 if (level >= kPrint && level < kInfo)
152 smsg = msg;
153 else if (level >= kBreak && level < kSysError)
154 smsg = std::string(type) + " " + msg;
155 else if (!location || !location[0])
156 smsg = std::string(type) + ": " + msg;
157 else
158 smsg = std::string(type) + " in <" + location + ">: " + msg;
159
160 DebugPrint("%s\n", smsg.c_str());
161
162 fflush(stderr);
163 if (abort_bool) {
164
165#ifdef __APPLE__
166 if (__crashreporter_info__)
167 delete [] __crashreporter_info__;
168 __crashreporter_info__ = strdup(smsg.c_str());
169#endif
170
171 DebugPrint("aborting\n");
172 fflush(stderr);
173 if (gSystem) {
175 gSystem->Abort();
176 } else {
177 abort();
178 }
179 }
180}
int Int_t
Definition: RtypesCore.h:45
bool Bool_t
Definition: RtypesCore.h:63
R__EXTERN TEnv * gEnv
Definition: TEnv.h:170
static void DebugPrint(const char *fmt,...)
Print debugging message to stderr and, on Windows, to the system debugger.
void DefaultErrorHandler(Int_t level, Bool_t abort_bool, const char *location, const char *msg)
The default error handler function.
static std::mutex * GetErrorMutex()
Serializes error output, destructed by the gROOT destructor via ReleaseDefaultErrorHandler()
const Int_t kPrint
Definition: TError.h:43
const Int_t kError
Definition: TError.h:46
const Int_t kSysError
Definition: TError.h:48
const Int_t kUnset
Definition: TError.h:42
const Int_t kFatal
Definition: TError.h:49
const Int_t kBreak
Definition: TError.h:47
const Int_t kWarning
Definition: TError.h:45
R__EXTERN Int_t gErrorIgnoreLevel
Definition: TError.h:127
const Int_t kInfo
Definition: TError.h:44
int type
Definition: TGX11.cxx:121
R__EXTERN TSystem * gSystem
Definition: TSystem.h:559
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
virtual void Abort(int code=0)
Abort the application.
Definition: TSystem.cxx:727
virtual void StackTrace()
Print a stack trace.
Definition: TSystem.cxx:735
const Int_t n
Definition: legend1.C:16
void ReleaseDefaultErrorHandler()
Destructs resources that are taken by using the default error handler.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
auto * m
Definition: textangle.C:8