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.
101/// @note `abort()` is only called if `abort_bool` is `true` and `level < gErrorIgnoreLevel`
102void DefaultErrorHandler(Int_t level, Bool_t abort_bool, const char *location, const char *msg)
103{
104 if (gErrorIgnoreLevel == kUnset) {
105 if (gEnv) {
106 // This can also print error messages, so we need to do it outside the lock
107 auto cstrlevel = gEnv->GetValue("Root.ErrorIgnoreLevel", "Print");
108
109 std::lock_guard<std::mutex> guard(*GetErrorMutex());
110
112 std::string slevel;
113 while (cstrlevel && *cstrlevel) {
114 slevel.push_back(tolower(*cstrlevel));
115 cstrlevel++;
116 }
117
118 if (slevel == "print")
120 else if (slevel == "info")
122 else if (slevel == "warning")
124 else if (slevel == "error")
126 else if (slevel == "break")
128 else if (slevel == "syserror")
130 else if (slevel == "fatal")
132 }
133 }
134
135 if (level < gErrorIgnoreLevel)
136 return;
137
138 const char *type = "?";
139
140 if (level >= kInfo)
141 type = "Info";
142 if (level >= kWarning)
143 type = "Warning";
144 if (level >= kError)
145 type = "Error";
146 if (level >= kBreak)
147 type = "\n *** Break ***";
148 if (level >= kSysError)
149 type = "SysError";
150 if (level >= kFatal)
151 type = "Fatal";
152
153 std::string smsg;
154 if (level >= kPrint && level < kInfo)
155 smsg = msg;
156 else if (level >= kBreak && level < kSysError)
157 smsg = std::string(type) + " " + msg;
158 else if (!location || !location[0])
159 smsg = std::string(type) + ": " + msg;
160 else
161 smsg = std::string(type) + " in <" + location + ">: " + msg;
162
163 DebugPrint("%s\n", smsg.c_str());
164
165 fflush(stderr);
166 if (abort_bool) {
167
168#ifdef __APPLE__
169 if (__crashreporter_info__)
170 delete [] __crashreporter_info__;
171 __crashreporter_info__ = strdup(smsg.c_str());
172#endif
173
174 DebugPrint("aborting\n");
175 fflush(stderr);
176 if (gSystem) {
178 gSystem->Abort();
179 } else {
180 abort();
181 }
182 }
183}
bool Bool_t
Definition: RtypesCore.h:63
int Int_t
Definition: RtypesCore.h:45
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
Int_t gErrorIgnoreLevel
Definition: TError.cxx:34
constexpr Int_t kSysError
Definition: TError.h:48
constexpr Int_t kUnset
Definition: TError.h:42
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:560
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:728
virtual void StackTrace()
Print a stack trace.
Definition: TSystem.cxx:737
const Int_t n
Definition: legend1.C:16
void ReleaseDefaultErrorHandler()
Destructs resources that are taken by using the default error handler.
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
TMarker m
Definition: textangle.C:8