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__
30 extern "C" {
31 static const char *__crashreporter_info__ = 0;
32 asm(".desc ___crashreporter_info__, 0x10");
33 }
34 #endif
35 
36 
37 /// Serializes error output, destructed by the gROOT destructor via ReleaseDefaultErrorHandler()
38 static std::mutex *GetErrorMutex() {
39  static std::mutex *m = new std::mutex();
40  return m;
41 }
42 
43 
44 namespace ROOT {
45 namespace 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.
57 static void DebugPrint(const char *fmt, ...)
58 {
59  TTHREAD_TLS(Int_t) buf_size = 2048;
60  TTHREAD_TLS(char*) buf = 0;
61 
62  va_list ap;
63  va_start(ap, fmt);
64 
65 again:
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 = 0;
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 void 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 
106  gErrorIgnoreLevel = 0;
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 = 0;
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) {
174  gSystem->StackTrace();
175  gSystem->Abort();
176  } else {
177  abort();
178  }
179  }
180 }
kSysError
const Int_t kSysError
Definition: TError.h:50
m
auto * m
Definition: textangle.C:8
kFatal
const Int_t kFatal
Definition: TError.h:51
n
const Int_t n
Definition: legend1.C:16
gEnv
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
TSystem::StackTrace
virtual void StackTrace()
Print a stack trace.
Definition: TSystem.cxx:733
kWarning
const Int_t kWarning
Definition: TError.h:47
kError
const Int_t kError
Definition: TError.h:48
ROOT::Internal::ReleaseDefaultErrorHandler
void ReleaseDefaultErrorHandler()
Destructs resources that are taken by using the default error handler.
Definition: TErrorDefaultHandler.cxx:47
Int_t
int Int_t
Definition: RtypesCore.h:45
TEnv::GetValue
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
TEnv.h
Varargs.h
Bool_t
bool Bool_t
Definition: RtypesCore.h:63
TSystem.h
DefaultErrorHandler
void DefaultErrorHandler(Int_t level, Bool_t abort_bool, const char *location, const char *msg)
The default error handler function.
Definition: TErrorDefaultHandler.cxx:101
gSystem
R__EXTERN TSystem * gSystem
Definition: TSystem.h:559
gErrorIgnoreLevel
R__EXTERN Int_t gErrorIgnoreLevel
Definition: TError.h:129
TSystem::Abort
virtual void Abort(int code=0)
Abort the application.
Definition: TSystem.cxx:725
GetErrorMutex
static std::mutex * GetErrorMutex()
Serializes error output, destructed by the gROOT destructor via ReleaseDefaultErrorHandler()
Definition: TErrorDefaultHandler.cxx:38
kBreak
const Int_t kBreak
Definition: TError.h:49
kInfo
const Int_t kInfo
Definition: TError.h:46
type
int type
Definition: TGX11.cxx:121
DebugPrint
static void DebugPrint(const char *fmt,...)
Print debugging message to stderr and, on Windows, to the system debugger.
Definition: TErrorDefaultHandler.cxx:57
ROOT
VSD Structures.
Definition: StringConv.hxx:21
ThreadLocalStorage.h
kUnset
const Int_t kUnset
Definition: TError.h:44
kPrint
const Int_t kPrint
Definition: TError.h:45
TError.h