summaryrefslogtreecommitdiffstats
path: root/usr.bin
diff options
context:
space:
mode:
authormdodd <mdodd@FreeBSD.org>2002-08-04 01:02:52 +0000
committermdodd <mdodd@FreeBSD.org>2002-08-04 01:02:52 +0000
commit65f8611398fde0becef8e3b6adea757da2411823 (patch)
tree68de8093cb515e71bf3ce5c2a2a03b522535281f /usr.bin
parent357fc6060d6acc804f9b5950000f1dfe7054417d (diff)
downloadFreeBSD-src-65f8611398fde0becef8e3b6adea757da2411823.zip
FreeBSD-src-65f8611398fde0becef8e3b6adea757da2411823.tar.gz
Allow tracking fork()ed children.
PR: bin/25587 (in part) MFC after: 3 weeks
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/truss/alpha-fbsd.c8
-rw-r--r--usr.bin/truss/amd64-fbsd32.c8
-rw-r--r--usr.bin/truss/amd64-linux32.c7
-rw-r--r--usr.bin/truss/extern.h2
-rw-r--r--usr.bin/truss/i386-fbsd.c8
-rw-r--r--usr.bin/truss/i386-linux.c7
-rw-r--r--usr.bin/truss/main.c30
-rw-r--r--usr.bin/truss/setup.c6
-rw-r--r--usr.bin/truss/syscalls.c5
-rw-r--r--usr.bin/truss/truss.17
-rw-r--r--usr.bin/truss/truss.h2
11 files changed, 80 insertions, 10 deletions
diff --git a/usr.bin/truss/alpha-fbsd.c b/usr.bin/truss/alpha-fbsd.c
index 4a88ff1..a7b5baf 100644
--- a/usr.bin/truss/alpha-fbsd.c
+++ b/usr.bin/truss/alpha-fbsd.c
@@ -155,6 +155,14 @@ alpha_syscall_entry(struct trussinfo *trussinfo, int nargs) {
fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall);
}
+ if (fsc.name && (trussinfo->flags & FOLLOWFORKS)
+ && ((!strcmp(fsc.name, "fork")
+ || !strcmp(fsc.name, "rfork")
+ || !strcmp(fsc.name, "vfork"))))
+ {
+ trussinfo->in_fork = 1;
+ }
+
if (nargs == 0)
return;
diff --git a/usr.bin/truss/amd64-fbsd32.c b/usr.bin/truss/amd64-fbsd32.c
index 702db80..6364927 100644
--- a/usr.bin/truss/amd64-fbsd32.c
+++ b/usr.bin/truss/amd64-fbsd32.c
@@ -160,6 +160,14 @@ i386_syscall_entry(struct trussinfo *trussinfo, int nargs) {
fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall);
}
+ if (fsc.name && (trussinfo->flags & FOLLOWFORKS)
+ && ((!strcmp(fsc.name, "fork")
+ || !strcmp(fsc.name, "rfork")
+ || !strcmp(fsc.name, "vfork"))))
+ {
+ trussinfo->in_fork = 1;
+ }
+
if (nargs == 0)
return;
diff --git a/usr.bin/truss/amd64-linux32.c b/usr.bin/truss/amd64-linux32.c
index e6a560a..f307c80 100644
--- a/usr.bin/truss/amd64-linux32.c
+++ b/usr.bin/truss/amd64-linux32.c
@@ -120,6 +120,13 @@ i386_linux_syscall_entry(struct trussinfo *trussinfo, int nargs) {
fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d\n", syscall);
}
+ if (lsc.name && (trussinfo->flags & FOLLOWFORKS)
+ && ((!strcmp(lsc.name, "linux_fork")
+ || !strcmp(lsc.name, "linux_vfork"))))
+ {
+ trussinfo->in_fork = 1;
+ }
+
if (nargs == 0)
return;
diff --git a/usr.bin/truss/extern.h b/usr.bin/truss/extern.h
index ea7c435..a708dda 100644
--- a/usr.bin/truss/extern.h
+++ b/usr.bin/truss/extern.h
@@ -32,7 +32,7 @@
*/
extern int setup_and_wait(char **);
-extern int start_tracing(int, int);
+extern int start_tracing(int, int, int);
extern void restore_proc(int);
extern const char *ioctlname(register_t val);
#ifdef __alpha__
diff --git a/usr.bin/truss/i386-fbsd.c b/usr.bin/truss/i386-fbsd.c
index 702db80..6364927 100644
--- a/usr.bin/truss/i386-fbsd.c
+++ b/usr.bin/truss/i386-fbsd.c
@@ -160,6 +160,14 @@ i386_syscall_entry(struct trussinfo *trussinfo, int nargs) {
fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall);
}
+ if (fsc.name && (trussinfo->flags & FOLLOWFORKS)
+ && ((!strcmp(fsc.name, "fork")
+ || !strcmp(fsc.name, "rfork")
+ || !strcmp(fsc.name, "vfork"))))
+ {
+ trussinfo->in_fork = 1;
+ }
+
if (nargs == 0)
return;
diff --git a/usr.bin/truss/i386-linux.c b/usr.bin/truss/i386-linux.c
index e6a560a..f307c80 100644
--- a/usr.bin/truss/i386-linux.c
+++ b/usr.bin/truss/i386-linux.c
@@ -120,6 +120,13 @@ i386_linux_syscall_entry(struct trussinfo *trussinfo, int nargs) {
fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d\n", syscall);
}
+ if (lsc.name && (trussinfo->flags & FOLLOWFORKS)
+ && ((!strcmp(lsc.name, "linux_fork")
+ || !strcmp(lsc.name, "linux_vfork"))))
+ {
+ trussinfo->in_fork = 1;
+ }
+
if (nargs == 0)
return;
diff --git a/usr.bin/truss/main.c b/usr.bin/truss/main.c
index 503329f..d1a236a 100644
--- a/usr.bin/truss/main.c
+++ b/usr.bin/truss/main.c
@@ -67,8 +67,8 @@ static __inline void
usage(void)
{
fprintf(stderr, "%s\n%s\n",
- "usage: truss [-S] [-o file] -p pid",
- " truss [-S] [-o file] command [args]");
+ "usage: truss [-fS] [-o file] -p pid",
+ " truss [-fS] [-o file] command [args]");
exit(1);
}
@@ -145,11 +145,14 @@ main(int ac, char **av) {
bzero(trussinfo, sizeof(struct trussinfo));
trussinfo->outfile = stderr;
- while ((c = getopt(ac, av, "p:o:S")) != -1) {
+ while ((c = getopt(ac, av, "p:o:fS")) != -1) {
switch (c) {
case 'p': /* specified pid */
trussinfo->pid = atoi(optarg);
break;
+ case 'f': /* Follow fork()'s */
+ trussinfo->flags |= FOLLOWFORKS;
+ break;
case 'o': /* Specified output file */
fname = optarg;
break;
@@ -195,9 +198,11 @@ main(int ac, char **av) {
* be woken up, either in exit() or in execve().
*/
+START_TRACE:
Procfd = start_tracing(
trussinfo->pid, S_EXEC | S_SCE | S_SCX | S_CORE | S_EXIT |
- ((trussinfo->flags & NOSIGS) ? 0 : S_SIG));
+ ((trussinfo->flags & NOSIGS) ? 0 : S_SIG),
+ ((trussinfo->flags & FOLLOWFORKS) ? PF_FORK : 0));
if (Procfd == -1)
return 0;
@@ -232,6 +237,23 @@ main(int ac, char **av) {
in_exec = 0;
break;
}
+
+ if (trussinfo->in_fork && (trussinfo->flags & FOLLOWFORKS)) {
+ int childpid;
+
+ trussinfo->in_fork = 0;
+ childpid = funcs->exit_syscall(trussinfo, pfs.val);
+
+ /*
+ * Fork a new copy of ourself to trace the child of the
+ * original traced process.
+ */
+ if (fork() == 0) {
+ trussinfo->pid = childpid;
+ goto START_TRACE;
+ }
+ break;
+ }
funcs->exit_syscall(trussinfo, pfs.val);
break;
case S_SIG:
diff --git a/usr.bin/truss/setup.c b/usr.bin/truss/setup.c
index baeb570..e3d52a4 100644
--- a/usr.bin/truss/setup.c
+++ b/usr.bin/truss/setup.c
@@ -130,7 +130,7 @@ setup_and_wait(char *command[]) {
*/
int
-start_tracing(int pid, int flags) {
+start_tracing(int pid, int eventflags, int flags) {
int fd;
char buf[32];
struct procfs_status tmp;
@@ -153,7 +153,7 @@ start_tracing(int pid, int flags) {
}
evflags = tmp.events;
- if (ioctl(fd, PIOCBIS, flags) == -1)
+ if (ioctl(fd, PIOCBIS, eventflags) == -1)
err(9, "cannot set procfs event bit mask");
/*
@@ -162,7 +162,7 @@ start_tracing(int pid, int flags) {
* needs to be woken up via procctl.
*/
- if (ioctl(fd, PIOCSFL, 0) == -1)
+ if (ioctl(fd, PIOCSFL, flags) == -1)
warn("cannot clear PF_LINGER");
return fd;
diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c
index 432197f..8056aa1 100644
--- a/usr.bin/truss/syscalls.c
+++ b/usr.bin/truss/syscalls.c
@@ -357,7 +357,12 @@ void
print_syscall(struct trussinfo *trussinfo, const char *name, int nargs, char **s_args) {
int i;
int len = 0;
+
+ if (trussinfo->flags & FOLLOWFORKS)
+ len += fprintf(trussinfo->outfile, "%5d: ", trussinfo->pid);
+
len += fprintf(trussinfo->outfile, "%s(", name);
+
for (i = 0; i < nargs; i++) {
if (s_args[i])
len += fprintf(trussinfo->outfile, "%s", s_args[i]);
diff --git a/usr.bin/truss/truss.1 b/usr.bin/truss/truss.1
index f2a99cc..58f9ac5 100644
--- a/usr.bin/truss/truss.1
+++ b/usr.bin/truss/truss.1
@@ -8,11 +8,11 @@
.Nd trace system calls
.Sh SYNOPSIS
.Nm
-.Op Fl S
+.Op Fl fS
.Op Fl o Ar file
.Fl p Ar pid
.Nm
-.Op Fl S
+.Op Fl fS
.Op Fl o Ar file
command
.Op args
@@ -26,6 +26,9 @@ It does this by stopping and restarting the process being monitored via
.Pp
The options are as follows:
.Bl -tag -width indent
+.It Fl f
+Trace decendants of the original traced process created by fork(),
+vfork, etc.
.It Fl S
Do not display information about signals received by the process.
(Normally,
diff --git a/usr.bin/truss/truss.h b/usr.bin/truss/truss.h
index 24396ad..f77202a 100644
--- a/usr.bin/truss/truss.h
+++ b/usr.bin/truss/truss.h
@@ -25,11 +25,13 @@
* $FreeBSD$
*/
+#define FOLLOWFORKS 0x00000001
#define NOSIGS 0x00000008
struct trussinfo
{
int pid;
int flags;
+ int in_fork;
FILE *outfile;
};
OpenPOWER on IntegriCloud