kcrash.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "config.h"
00029
00030 #include <string.h>
00031 #include <signal.h>
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <unistd.h>
00035 #include "kcrash.h"
00036
00037 #include <sys/types.h>
00038 #include <sys/time.h>
00039 #include <sys/resource.h>
00040 #include <sys/wait.h>
00041
00042 #include <qwindowdefs.h>
00043 #include <kglobal.h>
00044 #include <kinstance.h>
00045 #include <kaboutdata.h>
00046 #include <kdebug.h>
00047 #include <kapplication.h>
00048 #include <dcopclient.h>
00049
00050 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00051 #include <X11/Xlib.h>
00052 #endif
00053
00054 KCrash::HandlerType KCrash::_emergencySaveFunction = 0;
00055 KCrash::HandlerType KCrash::_crashHandler = 0;
00056 const char *KCrash::appName = 0;
00057 const char *KCrash::appPath = 0;
00058 bool KCrash::safer = false;
00059
00060
00061
00062
00063 void
00064 KCrash::setEmergencySaveFunction (HandlerType saveFunction)
00065 {
00066 _emergencySaveFunction = saveFunction;
00067
00068
00069
00070
00071
00072 if (_emergencySaveFunction && !_crashHandler)
00073 _crashHandler = defaultCrashHandler;
00074 }
00075
00076
00077
00078
00079 void
00080 KCrash::setCrashHandler (HandlerType handler)
00081 {
00082 if (!handler)
00083 handler = SIG_DFL;
00084
00085 sigset_t mask;
00086 sigemptyset(&mask);
00087
00088 #ifdef SIGSEGV
00089 signal (SIGSEGV, handler);
00090 sigaddset(&mask, SIGSEGV);
00091 #endif
00092 #ifdef SIGFPE
00093 signal (SIGFPE, handler);
00094 sigaddset(&mask, SIGFPE);
00095 #endif
00096 #ifdef SIGILL
00097 signal (SIGILL, handler);
00098 sigaddset(&mask, SIGILL);
00099 #endif
00100 #ifdef SIGABRT
00101 signal (SIGABRT, handler);
00102 sigaddset(&mask, SIGABRT);
00103 #endif
00104
00105 sigprocmask(SIG_UNBLOCK, &mask, 0);
00106
00107 _crashHandler = handler;
00108 }
00109
00110 void
00111 KCrash::defaultCrashHandler (int sig)
00112 {
00113
00114
00115 static int crashRecursionCounter = 0;
00116 crashRecursionCounter++;
00117
00118 signal(SIGALRM, SIG_DFL);
00119 alarm(3);
00120
00121 if (crashRecursionCounter < 2) {
00122 if (_emergencySaveFunction) {
00123 _emergencySaveFunction (sig);
00124 }
00125 crashRecursionCounter++;
00126 }
00127
00128
00129 DCOPClient::emergencyClose();
00130
00131 struct rlimit rlp;
00132 getrlimit(RLIMIT_NOFILE, &rlp);
00133 for (int i = 3; i < (int)rlp.rlim_cur; i++)
00134 close(i);
00135
00136 bool shuttingDown = false;
00137
00138
00139 if ( !shuttingDown )
00140 {
00141 if (crashRecursionCounter < 3)
00142 {
00143 if (appName)
00144 {
00145 #ifndef NDEBUG
00146 fprintf(stderr, "KCrash: crashing... crashRecursionCounter = %d\n", crashRecursionCounter);
00147 fprintf(stderr, "KCrash: Application Name = %s path = %s pid = %d\n", appName ? appName : "<unknown>" , appPath ? appPath : "<unknown>", getpid());
00148 #else
00149 fprintf(stderr, "KCrash: Application '%s' crashing...\n", appName ? appName : "<unknown>");
00150 #endif
00151
00152 pid_t pid = fork();
00153
00154 if (pid <= 0) {
00155
00156
00157 char * argv[24];
00158 int i = 0;
00159
00160
00161 argv[i++] = qstrdup("drkonqi");
00162
00163
00164 argv[i++] = qstrdup("-display");
00165 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00166 if ( qt_xdisplay() )
00167 argv[i++] = XDisplayString(qt_xdisplay());
00168 else
00169 argv[i++] = getenv("DISPLAY");
00170 #elif defined(Q_WS_QWS)
00171 argv[i++] = getenv("QWS_DISPLAY");
00172 #endif
00173
00174
00175 argv[i++] = qstrdup("--appname");
00176 argv[i++] = qstrdup(appName);
00177 if (KApplication::loadedByKdeinit)
00178 argv[i++] = qstrdup("--kdeinit");
00179
00180
00181 if (appPath) {
00182 argv[i++] = qstrdup("--apppath");
00183 argv[i++] = qstrdup(appPath);
00184 }
00185
00186
00187 QCString tmp;
00188 tmp.setNum(sig);
00189 argv[i++] = qstrdup("--signal");
00190 argv[i++] = qstrdup(tmp.data());
00191
00192
00193
00194 if (pid == 0) {
00195 tmp.setNum(getppid());
00196 argv[i++] = qstrdup("--pid");
00197 argv[i++] = qstrdup(tmp.data());
00198 }
00199
00200 const KInstance *instance = KGlobal::_instance;
00201 const KAboutData *about = instance ? instance->aboutData() : 0;
00202 if (about) {
00203 if (!about->version().isNull()) {
00204 argv[i++] = qstrdup("--appversion");
00205 argv[i++] = qstrdup(about->version().utf8());
00206 }
00207
00208 if (!about->programName().isNull()) {
00209 argv[i++] = qstrdup("--programname");
00210 argv[i++] = qstrdup(about->programName().utf8());
00211 }
00212
00213 if (!about->bugAddress().isNull()) {
00214 argv[i++] = qstrdup("--bugaddress");
00215 argv[i++] = qstrdup(about->bugAddress().utf8());
00216 }
00217 }
00218
00219 if ( kapp && !kapp->startupId().isNull()) {
00220 argv[i++] = qstrdup("--startupid");
00221 argv[i++] = qstrdup(kapp->startupId());
00222 }
00223
00224 if ( safer )
00225 argv[i++] = qstrdup("--safer");
00226
00227
00228 argv[i++] = NULL;
00229
00230 setgid(getgid());
00231 setuid(getuid());
00232
00233 execvp("drkonqi", argv);
00234
00235
00236
00237
00238
00239 }
00240 else
00241 {
00242
00243 alarm(0);
00244
00245
00246 waitpid(pid, NULL, 0);
00247 _exit(253);
00248 }
00249 }
00250 else {
00251 fprintf(stderr, "Unknown appname\n");
00252 }
00253 }
00254
00255 if (crashRecursionCounter < 4)
00256 {
00257 fprintf(stderr, "Unable to start Dr. Konqi\n");
00258 }
00259 }
00260
00261 _exit(255);
00262 }
This file is part of the documentation for kdecore Library Version 3.2.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Mar 4 22:43:30 2004 by
doxygen 1.3.6-20040222 written by
Dimitri van Heesch, © 1997-2003