00001
00002
00003 #include "Iguana/Framework/interface/IgOnCrashService.h"
00004 #include "classlib/utils/DebugAids.h"
00005 #include <iostream>
00006 #include <stdio.h>
00007 #include <cstring>
00008
00009
00010
00011 #define IGUANA_APP "iguana"
00012 #define IGUANA_VERSION "undefined"
00013 #define IGUANA_UNAME "undefined"
00014 #define IGUANA_HOST "undefined"
00015 #define IGUANA_CXX "undefined"
00016 #define IGUANA_COMPILER "undefined"
00017 #define IGUANA_WHO "undefined"
00018
00019
00020
00021
00022
00023
00024
00025 IgOnCrashService::FatalSignalHook
00026 IgOnCrashService::s_signalHook = defaultFatalSignal;
00027
00028 IgOnCrashService::FatalExceptionHook
00029 IgOnCrashService::s_exceptionHook = defaultFatalException;
00030
00031
00032
00033
00034
00035 bool
00036 IgOnCrashService::init (const char *appname)
00037 {
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 ASSERT (s_signalHook == defaultFatalSignal);
00062 ASSERT (s_exceptionHook == defaultFatalException);
00063 lat::Signal::handleFatal (appname, -1, fatalSignal);
00064 return true;
00065 }
00066
00074 IgOnCrashService::FatalSignalHook
00075 IgOnCrashService::fatalSignalHook (FatalSignalHook hook)
00076 {
00077 FatalSignalHook old = s_signalHook;
00078 if (hook)
00079 s_signalHook = hook;
00080 return old;
00081 }
00082
00090 IgOnCrashService::FatalExceptionHook
00091 IgOnCrashService::fatalExceptionHook (FatalExceptionHook hook)
00092 {
00093 FatalExceptionHook old = s_exceptionHook;
00094 if (hook)
00095 s_exceptionHook = hook;
00096 return old;
00097 }
00098
00102
00103 const char *
00104 IgOnCrashService::fatalTitle (void)
00105 {
00106 return "\n%s (%s).\n\n";
00107 }
00108
00110 const char *
00111 IgOnCrashService::fatalMessage (void)
00112 {
00113
00114 return "Oh dear! You have found a bug in CMSSW.\n\n"
00115
00116 "If you can reproduce this bug, please send a bug report\n"
00117 "to <iguana-developers@cern.ch>, giving a subject like\n\n"
00118
00119 " %s in " IGUANA_APP " " IGUANA_VERSION " (" IGUANA_HOST ")\n\n"
00120
00121 "To enable us to fix the bug, please include the following information:\n"
00122 "* What you were doing to get this message. Please report all the facts.\n"
00123 "* The following build configuration information:\n"
00124 " " IGUANA_UNAME "\n"
00125 " " IGUANA_CXX " (" IGUANA_COMPILER ")\n"
00126 " built by " IGUANA_WHO " on " __DATE__ " " __TIME__ "\n"
00127 "* The stack trace and loaded libraries list following this message.\n"
00128 "Please read also the section \"Reporting Bugs\" in the " IGUANA_APP " manual.\n\n"
00129
00130 "We thank you for your support and our apologies for the inconvenience.\n\n";
00131 }
00132
00136 void
00137 IgOnCrashService::printFatalMessage (const char *topic, const char *title,
00138 const char *reason)
00139 {
00140 std::cerr.flush ();
00141 fprintf (stderr, fatalTitle (), topic, title);
00142 fprintf (stderr, fatalMessage (), reason);
00143 }
00144
00145 bool
00146 IgOnCrashService::fatalSignal (int sig, siginfo_t *info, void *x)
00147 {
00148
00149
00150
00151
00152 ASSERT (s_signalHook);
00153 return s_signalHook (sig, info, x);
00154 }
00155
00156 bool
00157 IgOnCrashService::defaultFatalSignal (int sig, siginfo_t *info, void *x)
00158 {
00159 char buf [128];
00160 int signum = sig < 0 ? -sig : sig;
00161 bool have_core = sig < 0;
00162 const char *name = lat::Signal::name (signum);
00163
00164 if (name)
00165 sprintf (buf, "`%.100s' signal", name);
00166 else
00167 sprintf (buf, "Signal %d", signum);
00168
00169 if (have_core)
00170 strcat (buf, " (core dumped)");
00171
00172 printFatalMessage ("Internal error", buf, buf);
00173 return lat::Signal::fatalDump (sig, info, x);
00174 }
00175
00179 void
00180 IgOnCrashService::explainException (const char *type,
00181 const char *what,
00182 std::string &topic,
00183 std::string &title,
00184 std::string &reason)
00185 {
00186 if (! what || ! *what)
00187 what = "C++ exception";
00188
00189 topic = "Internal error";
00190 title = what;
00191 reason = what;
00192
00193
00194 while (type && isdigit (*type))
00195 type++;
00196
00197 if (type && *type)
00198 topic = type;
00199
00200
00201 std::string::size_type pos = topic.find ('_');
00202 while (pos != std::string::npos)
00203 {
00204 topic.replace (pos, 1, 1, ' ');
00205 pos = topic.find ('_');
00206 }
00207
00208
00209 topic[0] = toupper (topic[0]);
00210 if (type && *type)
00211 reason.insert (0, topic + ": ");
00212 }
00213
00214 void
00215 IgOnCrashService::printFatalException (const char *type, const char *what)
00216 {
00217 std::string title;
00218 std::string reason;
00219 std::string topic;
00220
00221 explainException (type, what, title, reason, topic);
00222 printFatalMessage (title.c_str (), reason.c_str (), topic.c_str ());
00223 }
00224
00225 void
00226 IgOnCrashService::fatalException (const char *type, const char *what)
00227 {
00228
00229
00230
00231
00232 ASSERT (s_exceptionHook);
00233 s_exceptionHook (type, what);
00234 }
00235
00236 void
00237 IgOnCrashService::defaultFatalException (const char *type, const char *what)
00238 {
00239 printFatalException (type, what);
00240 }