Date: Fri, 19 Oct 2001 01:50:01 -0700 (PDT) From: Thomas Quinot <quinot@inf.enst.fr> To: freebsd-bugs@FreeBSD.org Subject: Re: bin/25587: truss -f patch updated for -CURRENT 20011017 Message-ID: <200110190850.f9J8o1g14194@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/25587; it has been noted by GNATS.
From: Thomas Quinot <quinot@inf.enst.fr>
To: "Matthew N. Dodd" <winter@jurai.net>
Cc: freebsd-gnats-submit@freebsd.org
Subject: Re: bin/25587: truss -f patch updated for -CURRENT 20011017
Date: Fri, 19 Oct 2001 10:45:04 +0200
Le 2001-10-19, Matthew N. Dodd écrivait :
> The patches to main.c don't apply cleanly.
Strange. OK, I got a new, fresh copy of main.c 1.16 and diffed against
that. Please let me know if this new diff applies correctly for you.
Thanks,
Thomas.
--- main.c.dist Fri Oct 19 10:42:29 2001
+++ main.c Fri Oct 19 10:42:35 2001
@@ -50,37 +50,36 @@
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/pioctl.h>
+#include <sys/time.h>
+
+#include "truss.h"
extern int setup_and_wait(char **);
-extern int start_tracing(int, int);
+extern int start_tracing(int, int, int);
#ifdef __alpha__
-extern void alpha_syscall_entry(int, int);
-extern void alpha_syscall_exit(int, int);
+extern void alpha_syscall_entry(struct trussinfo *, int);
+extern void alpha_syscall_exit(struct trussinfo *, int);
#endif
#ifdef __i386__
-extern void i386_syscall_entry(int, int);
-extern void i386_syscall_exit(int, int);
-extern void i386_linux_syscall_entry(int, int);
-extern void i386_linux_syscall_exit(int, int);
+extern void i386_syscall_entry(struct trussinfo *, int);
+extern void i386_syscall_exit(struct trussinfo *, int);
+extern void i386_linux_syscall_entry(struct trussinfo *, int);
+extern void i386_linux_syscall_exit(struct trussinfo *, int);
#endif
/*
- * These should really be parameterized -- I don't like having globals,
- * but this is the easiest way, right now, to deal with them.
+ * It's difficult to parameterize this because it must be
+ * accessible in a signal handler.
*/
-int pid = 0;
-int nosigs = 0;
-FILE *outfile;
int Procfd;
-char progtype[50]; /* OS and type of executable */
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 [-fdDS] [-o file] -p pid",
+ " truss [-fdDS] [-o file] command [args]");
exit(1);
}
@@ -90,8 +89,8 @@
*/
struct ex_types {
char *type;
- void (*enter_syscall)(int, int);
- void (*exit_syscall)(int, int);
+ void (*enter_syscall)(struct trussinfo *, int);
+ int (*exit_syscall)(struct trussinfo *, int);
} ex_types[] = {
#ifdef __alpha__
{ "FreeBSD ELF", alpha_syscall_entry, alpha_syscall_exit },
@@ -111,13 +110,13 @@
*/
static struct ex_types *
-set_etype() {
+set_etype(struct trussinfo *trussinfo) {
struct ex_types *funcs;
char etype[24];
char progtype[32];
int fd;
- sprintf(etype, "/proc/%d/etype", pid);
+ sprintf(etype, "/proc/%d/etype", trussinfo->pid);
if ((fd = open(etype, O_RDONLY)) == -1) {
strcpy(progtype, "FreeBSD a.out");
} else {
@@ -148,18 +147,34 @@
int in_exec = 0;
char *fname = NULL;
int sigexit = 0;
+ struct trussinfo *trussinfo;
+
+ /* Initialize the trussinfo struct */
+ if ((trussinfo = (struct trussinfo *)malloc(sizeof(struct trussinfo)))
+ == NULL)
+ errx(1, "malloc() failed");
+ bzero(trussinfo, sizeof(struct trussinfo));
+ trussinfo->outfile = stderr;
- outfile = stdout;
- while ((c = getopt(ac, av, "p:o:S")) != -1) {
+ while ((c = getopt(ac, av, "p:o:fdDS")) != -1) {
switch (c) {
- case 'p': /* specified pid */
- pid = atoi(optarg);
+ case 'p': /* specified pid */
+ trussinfo->pid = atoi(optarg);
+ break;
+ case 'f': /* Follow fork()'s */
+ trussinfo->flags |= FOLLOWFORKS;
+ break;
+ case 'd': /* Absolute timestamps */
+ trussinfo->flags |= ABSOLUTETIMESTAMPS;
break;
- case 'o': /* Specified output file */
+ case 'D': /* Relative timestamps */
+ trussinfo->flags |= RELATIVETIMESTAMPS;
+ break;
+ case 'o': /* Specified output file */
fname = optarg;
break;
- case 'S': /* Don't trace signals */
- nosigs = 1;
+ case 'S': /* Don't trace signals */
+ trussinfo->flags |= NOSIGS;
break;
default:
usage();
@@ -167,11 +182,11 @@
}
ac -= optind; av += optind;
- if ((pid == 0 && ac == 0) || (pid != 0 && ac != 0))
+ if ((trussinfo->pid == 0 && ac == 0) || (trussinfo->pid != 0 && ac != 0))
usage();
if (fname != NULL) { /* Use output file */
- if ((outfile = fopen(fname, "w")) == NULL)
+ if ((trussinfo->outfile = fopen(fname, "w")) == NULL)
errx(1, "cannot open %s", fname);
}
@@ -182,9 +197,9 @@
* then we restore the event mask on these same signals.
*/
- if (pid == 0) { /* Start a command ourselves */
+ if (trussinfo->pid == 0) { /* Start a command ourselves */
command = av;
- pid = setup_and_wait(command);
+ trussinfo->pid = setup_and_wait(command);
signal(SIGINT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
@@ -201,20 +216,25 @@
* be woken up, either in exit() or in execve().
*/
- Procfd = start_tracing(pid, S_EXEC | S_SCE | S_SCX | S_CORE | S_EXIT |
- (nosigs ? 0 : S_SIG));
+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 & FOLLOWFORKS) ? PF_FORK : 0));
if (Procfd == -1)
return 0;
pfs.why = 0;
- funcs = set_etype();
+ funcs = set_etype(trussinfo);
/*
* At this point, it's a simple loop, waiting for the process to
* stop, finding out why, printing out why, and then continuing it.
* All of the grunt work is done in the support routines.
*/
+ gettimeofday(&trussinfo->start_time, (struct timezone *)NULL);
+
do {
int val = 0;
@@ -223,46 +243,68 @@
else {
switch(i = pfs.why) {
case S_SCE:
- funcs->enter_syscall(pid, pfs.val);
- break;
+ funcs->enter_syscall(trussinfo, pfs.val);
+ gettimeofday(&trussinfo->before, (struct timezone *)NULL);
+ break;
case S_SCX:
- /*
- * This is so we don't get two messages for an exec -- one
- * for the S_EXEC, and one for the syscall exit. It also,
- * conveniently, ensures that the first message printed out
- * isn't the return-from-syscall used to create the process.
- */
-
- if (in_exec) {
- in_exec = 0;
- break;
- }
- funcs->exit_syscall(pid, pfs.val);
- break;
+ gettimeofday(&trussinfo->after, (struct timezone *)NULL);
+
+ /*
+ * This is so we don't get two messages for an exec -- one
+ * for the S_EXEC, and one for the syscall exit. It also,
+ * conveniently, ensures that the first message printed out
+ * isn't the return-from-syscall used to create the process.
+ */
+
+ if (in_exec) {
+ 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:
- fprintf(outfile, "SIGNAL %lu\n", pfs.val);
- sigexit = pfs.val;
- break;
+ fprintf(trussinfo->outfile, "SIGNAL %lu\n", pfs.val);
+ sigexit = pfs.val;
+ break;
case S_EXIT:
- fprintf (outfile, "process exit, rval = %lu\n", pfs.val);
- break;
+ fprintf (trussinfo->outfile, "process exit, rval = %lu\n", pfs.val);
+ break;
case S_EXEC:
- funcs = set_etype();
- in_exec = 1;
- break;
+ funcs = set_etype(trussinfo);
+ in_exec = 1;
+ break;
default:
- fprintf (outfile, "Process stopped because of: %d\n", i);
- break;
+ fprintf (trussinfo->outfile, "Process stopped because of: %d\n", i);
+ break;
}
}
if (ioctl(Procfd, PIOCCONT, val) == -1) {
- if (kill(pid, 0) == -1 && errno == ESRCH)
- break;
+ if (kill(trussinfo->pid, 0) == -1 && errno == ESRCH)
+ break;
else
- warn("PIOCCONT");
+ warn("PIOCCONT");
}
} while (pfs.why != S_EXIT);
- fflush(outfile);
+ fflush(trussinfo->outfile);
if (sigexit) {
if (sigexit == SIGQUIT)
exit(sigexit);
--
Thomas Quinot ** Département Informatique & Réseaux ** quinot@inf.enst.fr
ENST // 46 rue Barrault // 75634 PARIS CEDEX 13
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200110190850.f9J8o1g14194>
