This is an automated email from the ASF dual-hosted git repository. cmcfarlen pushed a commit to branch 10.0.x in repository https://gitbox.apache.org/repos/asf/trafficserver.git
commit a805179ed8379ef54ccdd66281ec5b2ca8d69fad Author: Chris McFarlen <[email protected]> AuthorDate: Fri Jun 14 13:20:50 2024 -0500 Add exec argument to traffic_crashlog (#11447) (cherry picked from commit 9f135bfbee7341ebc3b53965cc4fd7abb16fab7d) --- .../command-line/traffic_crashlog.en.rst | 9 +++++ src/traffic_crashlog/traffic_crashlog.cc | 44 +++++++++++++++++++--- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/doc/appendices/command-line/traffic_crashlog.en.rst b/doc/appendices/command-line/traffic_crashlog.en.rst index 8f3257d44a..11a7f1c504 100644 --- a/doc/appendices/command-line/traffic_crashlog.en.rst +++ b/doc/appendices/command-line/traffic_crashlog.en.rst @@ -74,6 +74,15 @@ Options immediately after it is launched. :program:`traffic_server` will allow it to continue only when a crash occurs. +.. option:: --exec + + This option will execute the given program argument after the crashlogging + occurs, but before control is returned to traffic_server. That is, + it will run the program after traffic_server crashes, but before the process + is cleaned up. The program will be passed as single argument which is the + pid of the target traffic_server process. Output from the program will be + saved to the crashlog file. + Caveats ======= diff --git a/src/traffic_crashlog/traffic_crashlog.cc b/src/traffic_crashlog/traffic_crashlog.cc index 5b32254be6..07b8067b88 100644 --- a/src/traffic_crashlog/traffic_crashlog.cc +++ b/src/traffic_crashlog/traffic_crashlog.cc @@ -32,6 +32,7 @@ #include "tscore/BaseLogFile.h" #include "tscore/runroot.h" #include "iocore/eventsystem/RecProcess.h" +#include <unistd.h> static int syslog_mode = false; static int debug_mode = false; @@ -39,17 +40,19 @@ static int wait_mode = false; static char *host_triplet = nullptr; static int target_pid = getppid(); static char *user = nullptr; +static char *exec_pgm = nullptr; // If pid_t is not sizeof(int), we will have to jiggle argument parsing. extern char __pid_size_static_assert[sizeof(pid_t) == sizeof(int) ? 0 : -1]; static const ArgumentDescription argument_descriptions[] = { - {"target", '-', "Target process ID", "I", &target_pid, nullptr, nullptr}, - {"host", '-', "Host triplet for the process being logged", "S*", &host_triplet, nullptr, nullptr}, - {"wait", '-', "Stop until signalled at startup", "F", &wait_mode, nullptr, nullptr}, - {"syslog", '-', "Syslog after writing a crash log", "F", &syslog_mode, nullptr, nullptr}, - {"debug", '-', "Enable debugging mode", "F", &debug_mode, nullptr, nullptr}, - {"user", '-', "Username used to set privileges", "S*", &user, nullptr, nullptr}, + {"target", '-', "Target process ID", "I", &target_pid, nullptr, nullptr}, + {"host", '-', "Host triplet for the process being logged", "S*", &host_triplet, nullptr, nullptr}, + {"wait", '-', "Stop until signalled at startup", "F", &wait_mode, nullptr, nullptr}, + {"syslog", '-', "Syslog after writing a crash log", "F", &syslog_mode, nullptr, nullptr}, + {"debug", '-', "Enable debugging mode", "F", &debug_mode, nullptr, nullptr}, + {"user", '-', "Username used to set privileges", "S*", &user, nullptr, nullptr}, + {"exec", '-', "Program to execute at crash time (takes 1 pid parameter)", "S*", &exec_pgm, nullptr, nullptr}, HELP_ARGUMENT_DESCRIPTION(), VERSION_ARGUMENT_DESCRIPTION(), RUNROOT_ARGUMENT_DESCRIPTION() @@ -111,6 +114,32 @@ crashlog_write_backtrace(FILE *fp, pid_t pid, const crashlog_target &) return true; } +void +crashlog_exec_pgm(FILE *fp, pid_t pid) +{ + if (exec_pgm) { + fprintf(fp, "Executing Program `%s %d`:\n", exec_pgm, pid); + fflush(fp); + if (int chpid = fork(); chpid == 0) { + char tmp[32]; + snprintf(tmp, sizeof(tmp), "%d", pid); + char *args[3] = {exec_pgm, tmp, nullptr}; + + dup2(fileno(fp), STDOUT_FILENO); + dup2(fileno(fp), STDERR_FILENO); + + if (execv(exec_pgm, args) == -1) { + Error("Failed to exec pgm: %s\n", strerror(errno)); + } + } else { + int stat = 0; + waitpid(chpid, &stat, 0); + fflush(fp); + Note("Exec program returned status %d (pid %d)\n", stat, chpid); + } + } +} + int main(int /* argc ATS_UNUSED */, const char **argv) { @@ -224,6 +253,9 @@ main(int /* argc ATS_UNUSED */, const char **argv) fprintf(fp, "\n"); crashlog_write_regions(fp, target); + fprintf(fp, "\n"); + crashlog_exec_pgm(fp, target.pid); + Error("wrote crash log to %s", logname); ats_free(logname);
