Allow tracking fork()ed children.
PR: bin/25587 (in part) MFC after: 3 weeks
This commit is contained in:
parent
ec0bed25ba
commit
c03bfcc871
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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__
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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]);
|
||||
|
@ -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,
|
||||
|
@ -25,11 +25,13 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#define FOLLOWFORKS 0x00000001
|
||||
#define NOSIGS 0x00000008
|
||||
|
||||
struct trussinfo
|
||||
{
|
||||
int pid;
|
||||
int flags;
|
||||
int in_fork;
|
||||
FILE *outfile;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user