示例#1
0
文件: kcrash.cpp 项目: KDE/kcrash
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);
    }
}
示例#2
0
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
}
示例#3
0
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);
        }
    }
}
示例#4
0
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);
    }
}
示例#5
0
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);
    }
}
示例#6
0
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);
}