gcore command to coredump a process
This commit is contained in:
		
							parent
							
								
									eaa29370f4
								
							
						
					
					
						commit
						c30f014a89
					
				@ -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 \
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								commands/gcore/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								commands/gcore/Makefile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,4 @@
 | 
			
		||||
PROG=  gcore
 | 
			
		||||
MAN=
 | 
			
		||||
 | 
			
		||||
.include <bsd.prog.mk>
 | 
			
		||||
							
								
								
									
										66
									
								
								commands/gcore/gcore.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								commands/gcore/gcore.c
									
									
									
									
									
										Normal file
									
								
							@ -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;
 | 
			
		||||
}
 | 
			
		||||
@ -794,6 +794,7 @@
 | 
			
		||||
 | 
			
		||||
/* 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 */
 | 
			
		||||
 | 
			
		||||
@ -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)
 | 
			
		||||
 | 
			
		||||
@ -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)
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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).
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user