From 2e4ffe59b588159eb80e236f068278ba47735932 Mon Sep 17 00:00:00 2001 From: Wichert Akkerman Date: Sun, 3 Sep 2000 23:57:48 +0000 Subject: [PATCH] more FreeBSD updates --- CREDITS | 2 +- ChangeLog | 1 + defs.h | 3 ++- net.c | 9 +++------ process.c | 2 +- strace.c | 42 +++++++++++++++++++++++++++++++++--------- term.c | 16 ++++++++++++++-- 7 files changed, 55 insertions(+), 20 deletions(-) diff --git a/CREDITS b/CREDITS index ed03b500..2c8c22a6 100644 --- a/CREDITS +++ b/CREDITS @@ -39,4 +39,4 @@ porting to new systems: Florian Lohoff D.J. Barrow Topi Miettinen - Gaël Roualland + Gaël Roualland diff --git a/ChangeLog b/ChangeLog index 758e584c..bf4377ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,7 @@ * file.c: rename dirent64 struct to kernel_dirent64 so things compile again with newer libcs * test/clone.c: improve our testcase a bit + * Merge another patch from Gäel Roualland with FreeBSD updates 2000-09-01 Wichert Akkerman diff --git a/defs.h b/defs.h index 4dbed044..e6f90f10 100644 --- a/defs.h +++ b/defs.h @@ -210,9 +210,10 @@ extern int mp_ioctl (int f, int c, void *a, int s); #define PIOCWSTOP PIOCWAIT #define PR_WHY why #define PR_WHAT val -#define PR_FLAGS flags +#define PR_FLAGS state /* from /usr/src/sys/miscfs/procfs/procfs_vnops.c, status.state = 0 for running, 1 for stopped */ +#define PR_ASLEEP 1 #define PR_SYSENTRY S_SCE #define PR_SYSEXIT S_SCX #define PR_SIGNALLED S_SIG diff --git a/net.c b/net.c index da061c87..daea7825 100644 --- a/net.c +++ b/net.c @@ -943,7 +943,7 @@ struct tcb *tcp; else tprintf("[%u, %u]", fds[0], fds[1]); } -#elif defined(SPARC) || defined(SVR4) +#elif defined(SPARC) || defined(SVR4) || defined(FREEBSD) if (exiting(tcp)) tprintf("[%lu, %lu]", tcp->u_rval, getrval2(tcp)); #endif @@ -990,12 +990,9 @@ struct tcb *tcp; else tprintf(", [%u, %u]", fds[0], fds[1]); #endif /* LINUX */ -#ifdef SUNOS4 +#if defined(SUNOS4) || defined(SVR4) || defined(FREEBSD) tprintf(", [%lu, %lu]", tcp->u_rval, getrval2(tcp)); -#endif /* SUNOS4 */ -#ifdef SVR4 - tprintf(", [%lu, %lu]", tcp->u_rval, getrval2(tcp)); -#endif /* SVR4 */ +#endif /* SUNOS4 || SVR4 || FREEBSD */ } return 0; } diff --git a/process.c b/process.c index 47fc87d2..11b9910e 100644 --- a/process.c +++ b/process.c @@ -376,7 +376,7 @@ struct tcb *tcp; fprintf(stderr, "sys_fork: tcb table full\n"); return 0; } - if (proc_open(tcpchild, 1) < 0) + if (proc_open(tcpchild, 2) < 0) droptcb(tcpchild); } return 0; diff --git a/strace.c b/strace.c index 3e4b4a61..0e9242b1 100644 --- a/strace.c +++ b/strace.c @@ -684,11 +684,7 @@ int attaching; perror("strace: PIOCSTATUS"); return -1; } -#ifndef FREEBSD if (tcp->status.PR_FLAGS & PR_ASLEEP) -#else - if (tcp->status.state == 1) -#endif break; } } @@ -823,11 +819,31 @@ int attaching; } #else /* FREEBSD */ } else { - /* little hack to show the current syscall */ - IOCTL_STATUS(tcp); - tcp->flags &= ~TCB_INSYSCALL; - tcp->status.why = PR_SYSENTRY; - trace_syscall(tcp); + if (attaching < 2) { + /* We are attaching to an already running process. + * Try to figure out the state of the process in syscalls, + * to handle the first event well. + * This is done by having a look at the "wchan" property of the + * process, which tells where it is stopped (if it is). */ + FILE * status; + char wchan[20]; /* should be enough */ + + sprintf(proc, "/proc/%d/status", tcp->pid); + status = fopen(proc, "r"); + if (status && + (fscanf(status, "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d" + "%*d,%*d %*d,%*d %19s", wchan) == 1) && + strcmp(wchan, "nochan") && strcmp(wchan, "spread") && + strcmp(wchan, "stopevent")) { + /* The process is asleep in the middle of a syscall. + Fake the syscall entry event */ + tcp->flags &= ~(TCB_INSYSCALL|TCB_STARTUP); + tcp->status.PR_WHY = PR_SYSENTRY; + trace_syscall(tcp); + } + if (status) + fclose(status); + } /* otherwise it's a fork being followed */ } #endif /* FREEBSD */ #ifndef HAVE_POLLABLE_PROCFS @@ -1474,6 +1490,14 @@ trace() } } +#ifdef FREEBSD + if ((tcp->flags & TCB_STARTUP) && (tcp->status.PR_WHY == PR_SYSEXIT)) { + /* discard first event for a syscall we never entered */ + IOCTL (tcp->pfd, PIOCRUN, 0); + continue; + } +#endif + /* clear the just started flag */ tcp->flags &= ~TCB_STARTUP; diff --git a/term.c b/term.c index db15ef9b..0a741d54 100644 --- a/term.c +++ b/term.c @@ -178,7 +178,10 @@ long code, arg; #ifndef FREEBSD struct termio tio; #else - struct termios tio; + #define TCGETS TIOCGETA + #define TCSETS TIOCSETA + #define TCSETSW TIOCSETAW + #define TCSETSF TIOCSETAF #endif struct winsize ws; #ifdef TIOCGSIZE @@ -204,7 +207,16 @@ long code, arg; return 0; if (abbrev(tcp)) { tprintf(", {"); +#ifndef FREEBSD printxval(baud_options, tios.c_cflag & CBAUD, "B???"); +#else + printxval(baud_options, tios.c_ispeed, "B???"); + if (tios.c_ispeed != tios.c_ospeed) { + tprintf(" (in)"); + printxval(baud_options, tios.c_ospeed, "B???"); + tprintf(" (out)"); + } +#endif tprintf(" %sopost %sisig %sicanon %secho ...}", (tios.c_oflag & OPOST) ? "" : "-", (tios.c_lflag & ISIG) ? "" : "-", @@ -216,7 +228,7 @@ long code, arg; (long) tios.c_iflag, (long) tios.c_oflag); tprintf("c_cflags=%#lx, c_lflags=%#lx, ", (long) tios.c_cflag, (long) tios.c_lflag); -#ifndef SVR4 +#if !defined(SVR4) && !defined(FREEBSD) tprintf("c_line=%u, ", tios.c_line); #endif if (!(tios.c_lflag & ICANON)) -- 2.40.0