Ejemplo n.º 1
0
void KCrash::startDrKonqi(const char *argv[], int argc)
{
    int socket = openSocket();
    if(socket < -1)
    {
        startDirectly(argv, argc);
        return;
    }
    klauncher_header header;
    header.cmd = LAUNCHER_EXEC_NEW;
    const int BUFSIZE = 8192; // make sure this is big enough
    char buffer[BUFSIZE + 10];
    int pos = 0;
    long argcl = argc;
    memcpy(buffer + pos, &argcl, sizeof(argcl));
    pos += sizeof(argcl);
    for(int i = 0; i < argc; ++i)
    {
        int len = strlen(argv[i]) + 1; // include terminating \0
        if(pos + len > BUFSIZE)
        {
            fprintf(stderr, "BUFSIZE in KCrash not big enough!\n");
            startDirectly(argv, argc);
            return;
        }
        memcpy(buffer + pos, argv[i], len);
        pos += len;
    }
    long env = 0;
    memcpy(buffer + pos, &env, sizeof(env));
    pos += sizeof(env);
    long avoid_loops = 0;
    memcpy(buffer + pos, &avoid_loops, sizeof(avoid_loops));
    pos += sizeof(avoid_loops);
    header.arg_length = pos;
    write_socket(socket, (char *)&header, sizeof(header));
    write_socket(socket, buffer, pos);
    if(read_socket(socket, (char *)&header, sizeof(header)) < 0 || header.cmd != LAUNCHER_OK)
    {
        startDirectly(argv, argc);
        return;
    }
    long pid;
    read_socket(socket, buffer, header.arg_length);
    pid = *((long *)buffer);

    alarm(0); // Seems we made it....

    for(;;)
    {
        if(kill(pid, 0) < 0)
            _exit(253);
        sleep(1);
        // the debugger should stop this process anyway
    }
}
Ejemplo n.º 2
0
static bool startProcessInternal(int argc, const char *argv[], bool waitAndExit, bool directly)
{
#ifndef EMSCRIPTEN
    fprintf(stderr, "KCrash: Attempting to start %s %s\n", argv[0], directly ? "directly" : "from kdeinit");

    pid_t pid = directly ? startDirectly(argv) : startFromKdeinit(argc, argv);

    if (pid > 0 && waitAndExit) {
        // Seems we made it....
        alarm(0); //stop the pending alarm that was set at the top of the defaultCrashHandler

        // Wait forever until the started process exits. This code path is executed
        // when launching drkonqi. Note that drkonqi will stop this process in the meantime.
        if (directly) {
            //if the process was started directly, use waitpid(), as it's a child...
            while(waitpid(-1, NULL, 0) != pid) {}
        } else {
#ifdef Q_OS_LINUX
            // Declare the process that will be debugging the crashed KDE app (#245529)
#ifndef PR_SET_PTRACER
# define PR_SET_PTRACER 0x59616d61
#endif
            prctl(PR_SET_PTRACER, pid, 0, 0, 0);
#endif
            //...else poll its status using kill()
            while(kill(pid, 0) >= 0) {
                sleep(1);
            }
        }
        _exit(253);
    }

    return (pid > 0); //return true on success
#else
    return false;
#endif
}