From f7923457fda613cbe67c642710d228ba132c41b4 Mon Sep 17 00:00:00 2001 From: Chris Miles Date: Thu, 14 Jul 2022 02:17:18 -0500 Subject: [PATCH] [Crash] Linux Crash Dump Improvements (#2296) * [Crash] Linux Crash Dump Improvements * Change LogError for LogCrash --- common/crash.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/common/crash.cpp b/common/crash.cpp index cecb52f02..681f55c4f 100644 --- a/common/crash.cpp +++ b/common/crash.cpp @@ -2,6 +2,33 @@ #include "eqemu_logsys.h" #include "crash.h" +std::string execute(const std::string &cmd, bool return_result = true) +{ + const char *file_name = "exec-result"; + + if (return_result) { +#ifdef _WINDOWS + std::system((cmd + " > " + file_name + " 2>&1").c_str()); +#else + std::system((cmd + " > " + file_name + " 2>&1").c_str()); +#endif + } + else { + std::system((cmd).c_str()); + } + + std::string result; + + if (return_result) { + std::ifstream file(file_name); + result = {std::istreambuf_iterator(file), std::istreambuf_iterator()}; + std::remove(file_name); + + } + + return result; +} + #if defined(_WINDOWS) && defined(CRASH_LOGGING) #include "StackWalker.h" @@ -125,10 +152,24 @@ void set_exception_handler() { void print_trace() { - auto uid = geteuid(); + bool does_gdb_exist = execute("gdb -v").find("GNU") != std::string::npos; + if (!does_gdb_exist) { + LogCrash("[Error] GDB is not installed, if you want crash dumps on Linux to work properly you will need GDB installed"); + std::exit(1); + } + auto uid = geteuid(); std::string temp_output_file = "/tmp/dump-output"; + // check for passwordless sudo if not root + if (uid != 0) { + bool has_passwordless_sudo = execute("sudo -n true").find("a password is required") == std::string::npos; + if (!has_passwordless_sudo) { + LogCrash("[Error] Current user does not have passwordless sudo installed. It is required to automatically process crash dumps with GDB as non-root."); + std::exit(1); + } + } + char pid_buf[30]; sprintf(pid_buf, "%d", getpid()); char name_buf[512]; @@ -136,7 +177,6 @@ void print_trace() 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) {