#include <iostream>
#include <regex>
#include <sstream>
+#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
return result.str();
}
-void runChild()
+void runChild(pid_t ppid)
{
try {
+ if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0)) // Don't outlive parent process
+ exit(EXIT_FAILURE);
+ // If the parent died before prctl(), we won't be SIGKILLed
+ if (ppid != getppid())
+ std::terminate();
std::string filename = TMP_FILE_PREFIX + std::to_string(getpid());
int devnullWrite = TEMP_FAILURE_RETRY(open(DEV_NULL.c_str(), O_WRONLY));
if (-1 == devnullWrite)
exit(EXIT_FAILURE);
if (-1 == TEMP_FAILURE_RETRY(dup2(devnullRead, STDIN_FILENO)))
exit(EXIT_FAILURE);
- std::string ppid = std::to_string(getppid());
- execl("/usr/bin/gdb", "gdb", "--batch", "-n", "-ex", "bt", "--pid", ppid.c_str(),
+ std::string ppidStr = std::to_string(ppid);
+ execl("/usr/bin/gdb", "gdb", "--batch", "-n", "-ex", "bt", "--pid", ppidStr.c_str(),
(char*)nullptr);
// gdb failed to start...
} catch (...) {
// Try to become root again so gdb and unlink is possible
setegid(0);
seteuid(0);
+ pid_t parentPid = getpid();
pid_t childPid = fork();
switch (childPid) {
case -1:
printColor("fork() failed", errno);
return ret;
case 0:
- runChild();
+ runChild(parentPid);
default:
break;
}