Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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 if (gEnv) {
105 // This can also print error messages, so we need to do it outside the lock
106 auto cstrlevel = gEnv->GetValue("Root.ErrorIgnoreLevel", "Print");
107
108 std::lock_guard<std::mutex> guard(*GetErrorMutex());
109
111 std::string slevel;
112 while (cstrlevel && *cstrlevel) {
113 slevel.push_back(tolower(*cstrlevel));
114 cstrlevel++;
115 }
116
117 if (slevel == "print")
119 else if (slevel == "info")
121 else if (slevel == "warning")
123 else if (slevel == "error")
125 else if (slevel == "break")
127 else if (slevel == "syserror")
129 else if (slevel == "fatal")
131 }
132 }
133
134 if (level < gErrorIgnoreLevel)
135 return;
136
137 const char *type = nullptr;
138
139 if (level >= kInfo)
140 type = "Info";
141 if (level >= kWarning)
142 type = "Warning";
143 if (level >= kError)
144 type = "Error";
145 if (level >= kBreak)
146 type = "\n *** Break ***";
147 if (level >= kSysError)
148 type = "SysError";
149 if (level >= kFatal)
150 type = "Fatal";
151
152 std::string smsg;
153 if (level >= kPrint && level < kInfo)
154 smsg = msg;
155 else if (level >= kBreak && level < kSysError)
156 smsg = std::string(type) + " " + msg;
157 else if (!location || !location[0])
158 smsg = std::string(type) + ": " + msg;
159 else
160 smsg = std::string(type) + " in <" + location + ">: " + msg;
161
162 DebugPrint("%s\n", smsg.c_str());
163
164 fflush(stderr);
165 if (abort_bool) {
166
167#ifdef __APPLE__
168 if (__crashreporter_info__)
169 delete [] __crashreporter_info__;
170 __crashreporter_info__ = strdup(smsg.c_str());
171#endif
172
173 DebugPrint("aborting\n");
174 fflush(stderr);
175 if (gSystem) {
177 gSystem->Abort();
178 } else {
179 abort();
180 }
181 }
182}
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()
constexpr Int_t kError
Definition TError.h:46
constexpr Int_t kFatal
Definition TError.h:49
constexpr Int_t kWarning
Definition TError.h:45
constexpr Int_t kBreak
Definition TError.h:47
constexpr Int_t kPrint
Definition TError.h:43
constexpr Int_t kInfo
Definition TError.h:44
constexpr Int_t kSysError
Definition TError.h:48
R__EXTERN Int_t gErrorIgnoreLevel
Definition TError.h:127
constexpr Int_t kUnset
Definition TError.h:42
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