This is an automated email from the ASF dual-hosted git repository.

cmcfarlen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new 9f135bfbee Add exec argument to traffic_crashlog (#11447)
9f135bfbee is described below

commit 9f135bfbee7341ebc3b53965cc4fd7abb16fab7d
Author: Chris McFarlen <[email protected]>
AuthorDate: Fri Jun 14 13:20:50 2024 -0500

    Add exec argument to traffic_crashlog (#11447)
---
 .../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);

Reply via email to