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 <TVirtualMutex.h>
21
22#include <cstdarg>
23#include <cstdio>
24#include <cstdlib>
25#include <cctype> // for tolower
26#include <cstring> // for strdup
27#include <mutex>
28
29// Integrate with macOS crash reporter.
30#ifdef __APPLE__
31extern "C" {
32static const char *__crashreporter_info__ = 0;
33asm(".desc ___crashreporter_info__, 0x10");
34}
35#endif
36
37
38/// Serializes error output, destructed by the gROOT destructor via ReleaseDefaultErrorHandler()
39static std::mutex *GetErrorMutex() {
40 static std::mutex *m = new std::mutex();
41 return m;
42}
43
44
45namespace ROOT {
46namespace Internal {
47
49{
50 delete GetErrorMutex();
51}
52
53} // Internal namespace
54} // ROOT namespace
55
56
57/// Print debugging message to stderr and, on Windows, to the system debugger.
58static void DebugPrint(const char *fmt, ...)
59{
60 TTHREAD_TLS(Int_t) buf_size = 2048;
61 TTHREAD_TLS(char*) buf = nullptr;
62
63 va_list ap;
64 va_start(ap, fmt);
65
66again:
67 if (!buf)
68 buf = new char[buf_size];
69
70 Int_t n = vsnprintf(buf, buf_size, fmt, ap);
71 // old vsnprintf's return -1 if string is truncated new ones return
72 // total number of characters that would have been written
73 if (n == -1 || n >= buf_size) {
74 if (n == -1)
75 buf_size *= 2;
76 else
77 buf_size = n+1;
78 delete [] buf;
79 buf = nullptr;
80 va_end(ap);
81 va_start(ap, fmt);
82 goto again;
83 }
84 va_end(ap);
85
86 // Serialize the actual printing.
87 std::lock_guard<std::mutex> guard(*GetErrorMutex());
88
89 const char *toprint = buf; // Work around for older platform where we use TThreadTLSWrapper
90 fprintf(stderr, "%s", toprint);
91
92#ifdef WIN32
93 ::OutputDebugString(buf);
94#endif
95}
96
97
98/// The default error handler function. It prints the message on stderr and
99/// if abort is set it aborts the application. Replaces the minimal error handler
100/// of TError.h as part of the gROOT construction. TError's minimal handler is put
101/// back in place during the gROOT destruction.
102/// @note `abort()` is only called if `abort_bool` is `true` and `level >= gErrorIgnoreLevel`
103void DefaultErrorHandler(Int_t level, Bool_t abort_bool, const char *location, const char *msg)
104{
105 if (gErrorIgnoreLevel == kUnset) {
106 if (gEnv) {
107 // This can also print error messages, so we need to do it outside the lock
108 auto cstrlevel = gEnv->GetValue("Root.ErrorIgnoreLevel", "Print");
109
110 std::lock_guard<std::mutex> guard(*GetErrorMutex());
111
113 std::string slevel;
114 while (cstrlevel && *cstrlevel) {
115 slevel.push_back(tolower(*cstrlevel));
116 cstrlevel++;
117 }
118
119 if (slevel == "print")
121 else if (slevel == "info")
123 else if (slevel == "warning")
125 else if (slevel == "error")
127 else if (slevel == "break")
129 else if (slevel == "syserror")
131 else if (slevel == "fatal")
133 }
134 }
135
136 if (level < gErrorIgnoreLevel)
137 return;
138
139 const char *type = "?";
140
141 if (level >= kInfo)
142 type = "Info";
143 if (level >= kWarning)
144 type = "Warning";
145 if (level >= kError)
146 type = "Error";
147 if (level >= kBreak)
148 type = "\n *** Break ***";
149 if (level >= kSysError)
150 type = "SysError";
151 if (level >= kFatal)
152 type = "Fatal";
153
154 std::string smsg;
155 if (level >= kPrint && level < kInfo)
156 smsg = msg;
157 else if (level >= kBreak && level < kSysError)
158 smsg = std::string(type) + " " + msg;
159 else if (!location || !location[0])
160 smsg = std::string(type) + ": " + msg;
161 else
162 smsg = std::string(type) + " in <" + location + ">: " + msg;
163
164 DebugPrint("%s\n", smsg.c_str());
165
166 fflush(stderr);
167 if (abort_bool) {
168
169#ifdef __APPLE__
170 if (__crashreporter_info__)
171 delete [] __crashreporter_info__;
172 __crashreporter_info__ = strdup(smsg.c_str());
173#endif
174
175 DebugPrint("aborting\n");
176 fflush(stderr);
177 if (gSystem) {
179 gSystem->Abort();
180 } else {
181 abort();
182 }
183 }
184}
185
186namespace {
187ROOT::Internal::WarningHandlerFunc_t gWarningHandler = nullptr;
188
189void WarningHandlerErrorHandler(Int_t level, Bool_t abort, const char *location, const char *msg)
190{
191 // Initialize gErrorIgnoreLevel from gEnv: the default handler prints
192 // nothing for a level that low
194 DefaultErrorHandler(kUnset - 1, kFALSE, "", "");
195
196 if (level < gErrorIgnoreLevel)
197 return;
198
199 if (level >= kWarning && level < kError && !gGlobalMutex && gWarningHandler(location ? location : "", msg))
200 return;
201
202 DefaultErrorHandler(level, abort, location, msg);
203}
204} // namespace
205
207{
208 gWarningHandler = handler;
209 SetErrorHandler(&WarningHandlerErrorHandler);
210}
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:78
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:60
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
R__EXTERN TEnv * gEnv
Definition TEnv.h:126
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:47
constexpr Int_t kFatal
Definition TError.h:50
constexpr Int_t kWarning
Definition TError.h:46
constexpr Int_t kBreak
Definition TError.h:48
constexpr Int_t kPrint
Definition TError.h:44
constexpr Int_t kInfo
Definition TError.h:45
Int_t gErrorIgnoreLevel
errors with level below this value will be ignored. Default is kUnset.
Definition TError.cxx:33
constexpr Int_t kSysError
Definition TError.h:49
ErrorHandlerFunc_t SetErrorHandler(ErrorHandlerFunc_t newhandler)
Set an errorhandler function. Returns the old handler.
Definition TError.cxx:92
constexpr Int_t kUnset
Definition TError.h:43
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
R__EXTERN TSystem * gSystem
Definition TSystem.h:582
R__EXTERN TVirtualMutex * gGlobalMutex
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition TEnv.cxx:511
virtual void Abort(int code=0)
Abort the application.
Definition TSystem.cxx:739
virtual void StackTrace()
Print a stack trace.
Definition TSystem.cxx:748
const Int_t n
Definition legend1.C:16
bool(*)(const char *location, const char *msg) WarningHandlerFunc_t
Definition TError.h:68
void ReleaseDefaultErrorHandler()
Destructs resources that are taken by using the default error handler.
void SetWarningHandler(WarningHandlerFunc_t handler)
For the Python bindings: install an error handler that passes warnings to handler,...
TMarker m
Definition textangle.C:8