Retire ptrace(T_DUMPCORE), dumpcore(1), gcore(1)
The T_DUMPCORE implementation was not only broken - it would currently produce a coredump of the tracer process rather than the traced process - but also deeply flawed, and fixing it would require serious alteration of PM's internal state machine. It should be possible to implement the same functionality in userland, and that is now the suggested way forward. For now, also remove the (identical) utilities using T_DUMPCORE: dumpcore(1) and gcore(1). Change-Id: I1d51be19c739362b8a5833de949b76382a1edbcc
This commit is contained in:
parent
f707937192
commit
4f6b382c41
14 changed files with 11 additions and 218 deletions
|
@ -7,10 +7,10 @@ SUBDIR= add_route arp ash at backup btrace \
|
|||
chmod chown ci cleantmp cmp co \
|
||||
compress cp crc cron crontab \
|
||||
dd decomp16 DESCRIBE devmand devsize dhcpd \
|
||||
dhrystone diff diskctl dumpcore \
|
||||
dhrystone diff diskctl \
|
||||
eject factor fbdctl \
|
||||
find fix format fortune fsck.mfs \
|
||||
gcore gcov-pull getty grep host \
|
||||
gcov-pull getty grep host \
|
||||
hostaddr ifconfig ifdef \
|
||||
intr ipcrm ipcs irdpd isoread last \
|
||||
less loadkeys loadramdisk logger look lp \
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
PROG= dumpcore
|
||||
CPPFLAGS+= -I${NETBSDSRCDIR}
|
||||
MAN=
|
||||
|
||||
.include <bsd.prog.mk>
|
|
@ -1,71 +0,0 @@
|
|||
/* dumpcore - 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>
|
||||
|
||||
#include <machine/archtypes.h>
|
||||
#include "kernel/proc.h"
|
||||
|
||||
#define CLICK_WORDS (CLICK_SIZE / sizeof(unsigned long))
|
||||
|
||||
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) != 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;
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
PROG= gcore
|
||||
MAN=
|
||||
|
||||
.include <bsd.prog.mk>
|
|
@ -1,58 +0,0 @@
|
|||
/* gcore - create core file of running process */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/wait.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
pid_t pid;
|
||||
int 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 0;
|
||||
}
|
|
@ -299,7 +299,7 @@
|
|||
./usr/bin/dosread minix-sys
|
||||
./usr/bin/doswrite minix-sys
|
||||
./usr/bin/du minix-sys
|
||||
./usr/bin/dumpcore minix-sys
|
||||
./usr/bin/dumpcore minix-sys obsolete
|
||||
./usr/bin/egrep minix-sys
|
||||
./usr/bin/eject minix-sys
|
||||
./usr/bin/elfedit minix-sys binutils
|
||||
|
@ -331,7 +331,7 @@
|
|||
./usr/bin/ftp minix-sys
|
||||
./usr/bin/g++ minix-sys gcccmds
|
||||
./usr/bin/gcc minix-sys gcccmds
|
||||
./usr/bin/gcore minix-sys
|
||||
./usr/bin/gcore minix-sys obsolete
|
||||
./usr/bin/gcov minix-sys gcccmds
|
||||
./usr/bin/gcov-pull minix-sys
|
||||
./usr/bin/gcpp minix-sys gcccmds
|
||||
|
@ -1901,7 +1901,7 @@
|
|||
./usr/man/man1/dosread.1 minix-sys
|
||||
./usr/man/man1/doswrite.1 minix-sys
|
||||
./usr/man/man1/du.1 minix-sys
|
||||
./usr/man/man1/dumpcore.1 minix-sys
|
||||
./usr/man/man1/dumpcore.1 minix-sys obsolete
|
||||
./usr/man/man1/echo.1 minix-sys
|
||||
./usr/man/man1/ed.1 minix-sys
|
||||
./usr/man/man1/egrep.1 minix-sys
|
||||
|
|
|
@ -817,7 +817,6 @@
|
|||
|
||||
/* Additional parameters for PM_DUMPCORE */
|
||||
# define PM_TERM_SIG m7_i2 /* process's termination signal */
|
||||
# define PM_TRACED_PROC m7_i3 /* required for T_DUMPCORE */
|
||||
|
||||
/* Parameters for the EXEC_NEWMEM call */
|
||||
#define EXC_NM_PROC m1_i1 /* process that needs new map */
|
||||
|
|
|
@ -3,7 +3,7 @@ MAN= ash.1 at.1 \
|
|||
chmod.1 cmp.1 compress.1 \
|
||||
cp.1 crc.1 crontab.1 dd.1 \
|
||||
dhrystone.1 dosdir.1 dosread.1 doswrite.1 \
|
||||
dumpcore.1 eject.1 \
|
||||
eject.1 \
|
||||
factor.1 \
|
||||
flexdoc.1 format.1 fortune.1 \
|
||||
fsck.mfs.1 host.1 hostaddr.1 ifdef.1 \
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
.TH DUMPCORE 1
|
||||
.SH NAME
|
||||
dumpcore \- generate core file of running process
|
||||
.SH SYNOPSIS
|
||||
dumpcore \fIpid\fR
|
||||
.br
|
||||
.de FL
|
||||
.TP
|
||||
\\fB\\$1\\fR
|
||||
\\$2
|
||||
..
|
||||
.de EX
|
||||
.TP 20
|
||||
\\fB\\$1\\fR
|
||||
# \\$2
|
||||
..
|
||||
.SH DESCRIPTION
|
||||
The \fBdumpcore\fR utility generates a core file for a running process, based
|
||||
on that process's process ID (\fIpid\fP). The resulting core file will be
|
||||
stored under the name "core" in the current working directory. Any previous
|
||||
file with that name will be overwritten.
|
||||
.PP
|
||||
The resulting core file can be used with for example
|
||||
.BR mdb (1).
|
||||
.SH BUGS
|
||||
The process of generating the core file is currently very rudimentary, and
|
||||
the generated core file does not contain for example memory mapped areas.
|
||||
.SH "SEE ALSO"
|
||||
.BR mdb (1).
|
|
@ -320,7 +320,6 @@ 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;
|
||||
|
|
|
@ -447,15 +447,7 @@ static void handle_vfs_reply()
|
|||
if (m_in.PM_STATUS == OK)
|
||||
rmp->mp_sigstatus |= DUMPED;
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
@ -91,27 +91,6 @@ 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).
|
||||
|
|
|
@ -811,19 +811,12 @@ static void service_pm_postponed(void)
|
|||
|
||||
case PM_DUMPCORE:
|
||||
{
|
||||
endpoint_t proc_e, traced_proc_e;
|
||||
endpoint_t proc_e;
|
||||
int term_signal;
|
||||
vir_bytes core_path;
|
||||
|
||||
proc_e = job_m_in.PM_PROC;
|
||||
traced_proc_e = job_m_in.PM_TRACED_PROC;
|
||||
if(job_m_in.PM_PROC != job_m_in.PM_TRACED_PROC) {
|
||||
/* dumpcore request */
|
||||
term_signal = 0;
|
||||
} else {
|
||||
/* dumpcore on exit */
|
||||
term_signal = job_m_in.PM_TERM_SIG;
|
||||
}
|
||||
core_path = (vir_bytes) job_m_in.PM_PATH;
|
||||
|
||||
r = pm_dumpcore(proc_e, term_signal, core_path);
|
||||
|
@ -831,7 +824,6 @@ static void service_pm_postponed(void)
|
|||
/* Reply status to PM */
|
||||
m_out.m_type = PM_CORE_REPLY;
|
||||
m_out.PM_PROC = proc_e;
|
||||
m_out.PM_TRACED_PROC = traced_proc_e;
|
||||
m_out.PM_STATUS = r;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#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)
|
||||
|
|
Loading…
Reference in a new issue