Merge pull request #903 from EQEmu/feature/linux-crash-dumps

Automated Linux GDB crash dumps before process dies that follow the same pipeline as Windows
This commit is contained in:
Chris Miles 2019-09-24 01:02:16 -05:00 committed by GitHub
commit 9a4a49fc9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -111,7 +111,60 @@ void set_exception_handler() {
SetUnhandledExceptionFilter(windows_exception_handler);
}
#else
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/fcntl.h>
void print_trace()
{
auto uid = geteuid();
std::string temp_output_file = "/tmp/dump-output";
char pid_buf[30];
sprintf(pid_buf, "%d", getpid());
char name_buf[512];
name_buf[readlink("/proc/self/exe", name_buf, 511)] = 0;
int child_pid = fork();
if (!child_pid) {
int fd = open(temp_output_file.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
dup2(fd, 1); // redirect output to stderr
fprintf(stdout, "stack trace for %s pid=%s\n", name_buf, pid_buf);
if (uid == 0) {
execlp("gdb", "gdb", "--batch", "-n", "-ex", "thread", "-ex", "bt", name_buf, pid_buf, NULL);
}
else {
execlp("sudo", "gdb", "gdb", "--batch", "-n", "-ex", "thread", "-ex", "bt", name_buf, pid_buf, NULL);
}
close(fd);
abort(); /* If gdb failed to start */
}
else {
waitpid(child_pid, NULL, 0);
}
std::ifstream input(temp_output_file);
for (std::string line; getline(input, line);) {
LogCrash("{}", line);
}
std::remove(temp_output_file.c_str());
exit(1);
}
// crash is off or an unhandled platform
void set_exception_handler() {
void set_exception_handler()
{
signal(SIGABRT, reinterpret_cast<void (*)(int)>(print_trace));
signal(SIGFPE, reinterpret_cast<void (*)(int)>(print_trace));
signal(SIGFPE, reinterpret_cast<void (*)(int)>(print_trace));
signal(SIGSEGV, reinterpret_cast<void (*)(int)>(print_trace));
}
#endif