CMS 3D CMS Logo

IgOnCrashService.cc

Go to the documentation of this file.
00001 //<<<<<< INCLUDES                                                       >>>>>>
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 //<<<<<< PRIVATE DEFINES                                                >>>>>>
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 //<<<<<< PRIVATE CONSTANTS                                              >>>>>>
00020 //<<<<<< PRIVATE TYPES                                                  >>>>>>
00021 //<<<<<< PRIVATE VARIABLE DEFINITIONS                                   >>>>>>
00022 //<<<<<< PUBLIC VARIABLE DEFINITIONS                                    >>>>>>
00023 //<<<<<< CLASS STRUCTURE INITIALIZATION                                 >>>>>>
00024 
00025 IgOnCrashService::FatalSignalHook
00026 IgOnCrashService::s_signalHook = defaultFatalSignal;
00027 
00028 IgOnCrashService::FatalExceptionHook
00029 IgOnCrashService::s_exceptionHook = defaultFatalException;
00030 
00031 //<<<<<< PRIVATE FUNCTION DEFINITIONS                                   >>>>>>
00032 //<<<<<< PUBLIC FUNCTION DEFINITIONS                                    >>>>>>
00033 //<<<<<< MEMBER FUNCTION DEFINITIONS                                    >>>>>>
00034 
00035 bool
00036 IgOnCrashService::init (const char *appname)
00037 {
00038     // FIXME: For GUI app drivers, install fatal X error handler too
00039     // (or redirect whatever Qt has already), and hook it into
00040     // fatal_error_hook structure.
00041 
00042     // FIXME: Maybe install a graphical notification dialog in the app
00043     // driver?  If yes, create the dialog beforehand, and when showing
00044     // it, make sure the dialog is mapped and X is synchronised before
00045     // returning from the equivalent of the fatal_error_hook().  This
00046     // will allow us to exit if we get another signal (or an X error?)
00047     // during that time.
00048 
00049     // FIXME: If we have subprocesses that we are communicating with
00050     // (or a thread, or another interruptable subunit), the SIGINT
00051     // handler should send an interrupt to it (a C-c character for
00052     // example).
00053 
00054     // FIXME: App driver should disable core dump on fatal signals
00055     // while in the main event loop (that is, allow them from init
00056     // till exit sequence begins) -- except if the user has requested
00057     // otherwise.
00058 
00059     // FIXME: Install a quit cleanup handler?
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     // FIXME: put in apps etc. from service constructor args?
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     // FIXME: should interrupt here any subprocesses/threads
00149     // FIXME: should this be a service others can hook into?
00150     // FIXME: deal with recursive crashes
00151     // FIXME: be smarter about SIGINT
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     // GCC prepends the name length to type names, strip them off
00194     while (type && isdigit (*type))
00195         type++;
00196 
00197     if (type && *type)
00198         topic = type;
00199 
00200     // Convert underscores to spaces
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     // Uppercase first character
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     // FIXME: should be dialog in a graphical app!
00229     // FIXME: should interrupt here any subprocesses/threads
00230     // FIXME: should this be a service others can hook into?
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 }

Generated on Tue Jun 9 17:38:29 2009 for CMSSW by  doxygen 1.5.4