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 } }
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 }