]> Zhao Yanbai Git Server - minix.git/commitdiff
gcore command to coredump a process
authorAdriana Szekeres <adriana.szekeres@gmail.com>
Tue, 22 Nov 2011 15:41:47 +0000 (16:41 +0100)
committerBen Gras <ben@minix3.org>
Tue, 22 Nov 2011 21:07:41 +0000 (22:07 +0100)
commands/Makefile
commands/gcore/Makefile [new file with mode: 0644]
commands/gcore/gcore.c [new file with mode: 0644]
common/include/minix/com.h
include/sys/ptrace.h
nbsd_include/sys/ptrace.h
servers/pm/forkexit.c
servers/pm/main.c
servers/pm/trace.c
servers/vfs/main.c
servers/vfs/misc.c

index 7ef211f589ed5f556bf0647202fc01b8a9d338bc..99c1586f710ea77cff0407b90fa5b9799f8c5a69 100644 (file)
@@ -12,7 +12,7 @@ SUBDIR=       aal add_route arp ash at autil awk \
        dhrystone diff dirname  dis386 dis88 diskctl du dumpcore \
        ed eject elle elvis env expand factor file \
        find finger fingerd fix fold format fortune fsck.mfs \
-       ftp101 gcov-pull getty grep head hexdump host \
+       ftp101 gcore gcov-pull getty grep head hexdump host \
        hostaddr id ifconfig ifdef install \
        intr ipcrm ipcs irdpd isoread join kill last leave \
        less lex loadkeys loadramdisk logger login look lp \
diff --git a/commands/gcore/Makefile b/commands/gcore/Makefile
new file mode 100644 (file)
index 0000000..4ad31cc
--- /dev/null
@@ -0,0 +1,4 @@
+PROG=  gcore
+MAN=
+
+.include <bsd.prog.mk>
diff --git a/commands/gcore/gcore.c b/commands/gcore/gcore.c
new file mode 100644 (file)
index 0000000..8fa98e6
--- /dev/null
@@ -0,0 +1,66 @@
+/* gcore - create core file of running process */
+
+#include <fcntl.h>
+#include <unistd.h>    
+#include <minix/config.h>
+#include <minix/type.h>
+#include <minix/ipc.h>
+#include <minix/const.h>
+#include <sys/ptrace.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <timers.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+int main(int argc, char *argv[])
+{
+  pid_t pid;
+  int r, status;
+
+  if(argc != 2) {
+       printf("usage: %s <pid>\n", argv[0]);
+       return 1;
+  }
+
+  pid = atoi(argv[1]);
+
+  if (ptrace(T_ATTACH, pid, 0, 0) != 0) {
+       perror("ptrace(T_ATTACH)");
+       return 1;
+  }
+
+  if (waitpid(pid, &status, 0) != pid) {
+       perror("waitpid");
+       return 1;
+  }
+
+  while (WIFSTOPPED(status) && WSTOPSIG(status) != SIGSTOP) {
+       /* whatever happens here is fine */
+       ptrace(T_RESUME, pid, 0, WSTOPSIG(status));
+
+       if (waitpid(pid, &status, 0) != pid) {
+               perror("waitpid");
+               return 1;
+       }
+  }
+
+  if (!WIFSTOPPED(status)) {
+       fprintf(stderr, "process died while attaching\n");
+       return 1;
+  }
+
+  if (ptrace(T_DUMPCORE, pid, 0, 0)) {
+       fprintf(stderr, "warning, dumpcore failed (%s)\n",
+       strerror(errno));
+  }
+
+  if (ptrace(T_DETACH, pid, 0, 0)) {
+       fprintf(stderr, "warning, detaching failed (%s)\n",
+       strerror(errno));
+  }
+
+  return r;
+}
index b82433f42170020e72be1fdb5b14e0dda6250bdf..01a9094da264e17732643425cc98c37f6d7c275c 100644 (file)
 
 /* Additional parameters for PM_DUMPCORE */
 #  define PM_TERM_SIG          m1_i2   /* process's termination signal */
+#  define PM_TRACED_PROC       m1_i3   /* required for T_DUMPCORE */
 
 /* Parameters for the EXEC_NEWMEM call */
 #define EXC_NM_PROC    m1_i1           /* process that needs new map */
index ddd17dc82749ae9471be9ae4c7564050f416585a..734b5ecd733f4bb2835819da0843260d90ab9482 100644 (file)
@@ -23,6 +23,7 @@
 #define T_SETOPT       13      /* set trace options */
 #define T_GETRANGE     14      /* get range of values */
 #define T_SETRANGE     15      /* set range of values */
+#define T_DUMPCORE      16      /* dumps the core for the process with the given pid */
 
 #define T_READB_INS    100     /* Read a byte from the text segment of an
                                 * untraced process (only for root)
index b829771a403096de52d00bf3246fceb110dd67e4..59c1a442aafeb47b84c98fb5235d28a3b12010e7 100644 (file)
@@ -23,6 +23,7 @@
 #define T_SETOPT       13      /* set trace options */
 #define T_GETRANGE     14      /* get range of values */
 #define T_SETRANGE     15      /* set range of values */
+#define T_DUMPCORE      16      /* dumps the core for the process with the given pid */
 
 #define T_READB_INS    100     /* Read a byte from the text segment of an
                                 * untraced process (only for root)
index c3d0c7bb292322b6e52e48bb5f3806f83a23e006..9b1124ad9d437b6ce6b3ee0c59025e9b18737397 100644 (file)
@@ -317,6 +317,7 @@ int dump_core;                      /* flag indicating whether to dump core */
   /* Tell VFS about the exiting process. */
   m.m_type = dump_core ? PM_DUMPCORE : PM_EXIT;
   m.PM_PROC = rmp->mp_endpoint;
+  m.PM_TRACED_PROC = rmp->mp_endpoint;
 
   if (dump_core) {
     m.PM_TERM_SIG = rmp->mp_sigstatus;
index 90da3812f30b5625842b6c20015e02151af1a943..12b41daf0163c65c36d0a38cc918f2ebca88cb51 100644 (file)
@@ -477,7 +477,15 @@ PRIVATE void handle_vfs_reply()
        if (m_in.PM_STATUS == OK)
                rmp->mp_sigstatus |= DUMPED;
 
-       exit_restart(rmp, TRUE /*dump_core*/);
+       if (m_in.PM_PROC == m_in.PM_TRACED_PROC)
+               /* The reply is to a core dump request
+                * for a killed process */
+               exit_restart(rmp, TRUE /*dump_core*/);
+       else
+               /* The reply is to a core dump request
+                * for a traced process (T_DUMPCORE) */
+               /* Wake up the original caller */
+               setreply(rmp-mproc, rmp->mp_procgrp);
 
        break;
 
index b6893a610056d4a7e0c07774628adac6f071c7fc..0786791deaba2d5d3bed1f403ece6855252382c4 100644 (file)
@@ -42,6 +42,7 @@ PUBLIC int do_trace()
   register struct mproc *child;
   struct ptrace_range pr;
   int i, r, seg, req;
+  message m;
 
   req = m_in.request;
 
@@ -90,6 +91,27 @@ PUBLIC int do_trace()
        mp->mp_reply.reply_trace = 0;
        return(OK);
 
+  case T_DUMPCORE:
+       if ((child = find_proc(m_in.pid)) == NULL) return(ESRCH);
+
+       /* Allow dumpcore only if traced! */
+       if (child->mp_tracer != who_p) return(EPERM);
+
+       /* Tell VFS to dump the core. */
+       m.m_type = PM_DUMPCORE;
+       m.PM_PROC = mp->mp_endpoint;
+       m.PM_TRACED_PROC = child->mp_endpoint;
+       /* Note that m.PM_PROC != m.PM_TRACED_PROC
+        * (we use this to differentiate between a VFS core dump reply for a
+        * an exiting process and the one for a traced process) */
+
+       m.PM_TERM_SIG = child->mp_sigstatus;
+       m.PM_PATH = child->mp_name;
+
+       tell_vfs(mp, &m);
+
+       return(SUSPEND); /* Suspend the process until we receive reply from VFS */
+
   case T_STOP:         /* stop the process */
        /* This call is not exposed to user programs, because its effect can be
         * achieved better by sending the traced process a signal with kill(2).
index 06b7536f566a52e47ce79f6134e352ec38fdac76..05c3b035e0c2932cbb5f9c40b1469ddce8afc50f 100644 (file)
@@ -558,6 +558,7 @@ PRIVATE void service_pm()
        /* Reply status to PM */
        m_out.m_type = PM_CORE_REPLY;
        m_out.PM_PROC = m_in.PM_PROC;
+       m_out.PM_TRACED_PROC = m_in.PM_TRACED_PROC;
        m_out.PM_STATUS = r;
        
        break;
index b41fc0d281be273001b08ae4e7332b5eefa9f4b4..1b406e9fa5a5a436da6bd9e6167f44590aef0af2 100644 (file)
@@ -581,8 +581,9 @@ int csig;
 char *exe_name;
 {
   int proc_s, r, old_who_e;
-       
-  okendpt(proc_e, &proc_s);
+  int traced_proc_e = m_in.PM_TRACED_PROC;
+
+  okendpt(traced_proc_e, &proc_s);
   fp = &fproc[proc_s];
 
   /* Open the core file */
@@ -603,10 +604,12 @@ char *exe_name;
   close_fd(fp, r);
 
   /* Terminate the process */
-  free_proc(&fproc[proc_s], FP_EXITING);
+  if (traced_proc_e == proc_e)
+       free_proc(&fproc[proc_s], FP_EXITING);
 
   /* Restore the important variables that have been overwritten */
   m_in.PM_PROC = proc_e;
+  m_in.PM_TRACED_PROC = traced_proc_e;
   who_e = old_who_e;
 
   return OK;