void KCrash::setEmergencySaveFunction(HandlerType saveFunction) { s_emergencySaveFunction = saveFunction; /* * We need at least the default crash handler for * emergencySaveFunction to be called */ if (s_emergencySaveFunction && !s_crashHandler) { setCrashHandler(defaultCrashHandler); } }
SocketExternalInstance::SocketExternalInstance() : ExternalInstance(), memory_(new QSharedMemory(GLOG_SERVICE_NAME) ) { if ( !memory_->attach( QSharedMemory::ReadOnly ) ) { throw CantCreateExternalErr(); } #ifdef Q_OS_UNIX // Handle any further termination signals to ensure the // QSharedMemory block is deleted even if the process crashes setCrashHandler(memory_); #endif }
void KCrash::setFlags(KCrash::CrashFlags flags) { s_flags = flags; if (s_flags & AutoRestart) { // We need at least the default crash handler for autorestart to work. if (!s_crashHandler) { KCmdLineArgs *args = KCmdLineArgs::parsedArgs("kde"); if (!args->isSet("crashhandler")) // --nocrashhandler was passed, probably due to a crash, delay restart handler new KCrashDelaySetHandler; else // probably because KDE_DEBUG=1. set restart handler immediately. setCrashHandler(defaultCrashHandler); } } }
void SocketExternalCommunicator::startListening() { if ( memory_->create(sizeof(qint32))) { #ifdef Q_OS_UNIX // Handle any further termination signals to ensure the // QSharedMemory block is deleted even if the process crashes setCrashHandler(memory_); #endif *reinterpret_cast<qint32*>(memory_->data()) = version(); QLocalServer::removeServer(GLOG_SERVICE_NAME); connect(server_, SIGNAL(newConnection()), SLOT(onConnection())); server_->listen(GLOG_SERVICE_NAME); } }
void KCrash::setDrKonqiEnabled(bool enabled) { s_launchDrKonqi = enabled; if (s_launchDrKonqi && !s_drkonqiPath) { s_drkonqiPath = qstrdup(QFile::encodeName(KStandardDirs::findExe("drkonqi")).constData()); if (!s_drkonqiPath) { kError() << "Could not find drkonqi"; s_launchDrKonqi = false; } } //we need at least the default crash handler to launch drkonqi if (s_launchDrKonqi && !s_crashHandler) { setCrashHandler(defaultCrashHandler); } }
void KCrash::defaultCrashHandler (int sig) { // WABA: Do NOT use kDebug() in this function because it is much too risky! // Handle possible recursions static int crashRecursionCounter = 0; crashRecursionCounter++; // Nothing before this, please ! #if !defined(Q_OS_WIN) signal(SIGALRM, SIG_DFL); alarm(3); // Kill me... (in case we deadlock in malloc) #endif #ifdef Q_OS_SOLARIS (void) printstack(2 /* stderr, assuming it's still open. */); #endif if (crashRecursionCounter < 2) { if (s_emergencySaveFunction) { s_emergencySaveFunction (sig); } if ((s_flags & AutoRestart) && s_autoRestartCommand) { sleep(1); startProcess(s_autoRestartArgc, const_cast<const char**>(s_autoRestartCommandLine), false); } crashRecursionCounter++; } #if !defined(Q_OS_WIN) if (!(s_flags & KeepFDs)) closeAllFDs(); # if defined(Q_WS_X11) else if (QX11Info::display()) close(ConnectionNumber(QX11Info::display())); # endif #endif if (crashRecursionCounter < 3) { #ifndef NDEBUG fprintf(stderr, "KCrash: crashing... crashRecursionCounter = %d\n", crashRecursionCounter); fprintf(stderr, "KCrash: Application Name = %s path = %s pid = %lld\n", s_appName ? s_appName : "<unknown>" , s_appPath ? s_appPath : "<unknown>", QCoreApplication::applicationPid()); fprintf(stderr, "KCrash: Arguments: "); for (int i = 0; s_autoRestartCommandLine[i]; ++i) { fprintf(stderr, "%s ", s_autoRestartCommandLine[i]); } fprintf(stderr, "\n"); #else fprintf(stderr, "KCrash: Application '%s' crashing...\n", s_appName ? s_appName : "<unknown>"); #endif if (!s_launchDrKonqi) { setCrashHandler(0); #if !defined(Q_OS_WIN) raise(sig); // dump core, or whatever is the default action for this signal. #endif return; } const char * argv[27]; // don't forget to update this int i = 0; // argument 0 has to be drkonqi argv[i++] = s_drkonqiPath; #if defined Q_WS_X11 // start up on the correct display argv[i++] = "-display"; if ( QX11Info::display() ) argv[i++] = XDisplayString(QX11Info::display()); else argv[i++] = getenv("DISPLAY"); #elif defined(Q_WS_QWS) // start up on the correct display argv[i++] = "-display"; argv[i++] = getenv("QWS_DISPLAY"); #endif argv[i++] = "--appname"; argv[i++] = s_appName ? s_appName : "<unknown>"; if (KApplication::loadedByKdeinit) argv[i++] = "--kdeinit"; // only add apppath if it's not NULL if (s_appPath && *s_appPath) { argv[i++] = "--apppath"; argv[i++] = s_appPath; } // signal number -- will never be NULL char sigtxt[ 10 ]; sprintf( sigtxt, "%d", sig ); argv[i++] = "--signal"; argv[i++] = sigtxt; char pidtxt[ 20 ]; sprintf( pidtxt, "%lld", QCoreApplication::applicationPid()); argv[i++] = "--pid"; argv[i++] = pidtxt; const KComponentData componentData = KGlobal::mainComponent(); const KAboutData *about = componentData.isValid() ? componentData.aboutData() : 0; if (about) { if (about->internalVersion()) { argv[i++] = "--appversion"; argv[i++] = about->internalVersion(); } if (about->internalProgramName()) { argv[i++] = "--programname"; argv[i++] = about->internalProgramName(); } if (about->internalBugAddress()) { argv[i++] = "--bugaddress"; argv[i++] = about->internalBugAddress(); } } char sidtxt[256]; if ( kapp && !kapp->startupId().isNull()) { argv[i++] = "--startupid"; strlcpy(sidtxt, kapp->startupId().constData(), sizeof(sidtxt)); argv[i++] = sidtxt; } if ( s_flags & SaferDialog ) argv[i++] = "--safer"; if ((s_flags & AutoRestart) && s_autoRestartCommand) argv[i++] = "--restarted"; //tell drkonqi if the app has been restarted #if defined(Q_OS_WIN) char threadId[8] = { 0 }; sprintf( threadId, "%d", GetCurrentThreadId() ); argv[i++] = "--thread"; argv[i++] = threadId; #endif // NULL terminated list argv[i] = NULL; startProcess(i, argv, true); } if (crashRecursionCounter < 4) { fprintf(stderr, "Unable to start Dr. Konqi\n"); } _exit(255); }