diff options
author | jhb <jhb@FreeBSD.org> | 2013-09-12 18:08:25 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2013-09-12 18:08:25 +0000 |
commit | e4d9007c2c613694224d9f3249f3057212a1b3ac (patch) | |
tree | 2cf0f084d10cf818e843e6a04081c57c277ec537 /usr.bin/truss | |
parent | 5dbaab99c0ddca3e6afd70a1ecd29f360752f46d (diff) | |
download | FreeBSD-src-e4d9007c2c613694224d9f3249f3057212a1b3ac.zip FreeBSD-src-e4d9007c2c613694224d9f3249f3057212a1b3ac.tar.gz |
- Decode the idtype argument passed to wait6() in kdump and truss.
- Don't treat an options argument of 0 to wait4() as an error in
kdump.
- Decode the wait options passed to wait4() and wait6() in truss
and decode the returned rusage and exit status.
Approved by: re (kib)
MFC after: 1 week
Diffstat (limited to 'usr.bin/truss')
-rw-r--r-- | usr.bin/truss/syscall.h | 2 | ||||
-rw-r--r-- | usr.bin/truss/syscalls.c | 77 |
2 files changed, 67 insertions, 12 deletions
diff --git a/usr.bin/truss/syscall.h b/usr.bin/truss/syscall.h index 94776a0..ce7d2e9 100644 --- a/usr.bin/truss/syscall.h +++ b/usr.bin/truss/syscall.h @@ -40,7 +40,7 @@ enum Argtype { None = 1, Hex, Octal, Int, Name, Ptr, Stat, Ioctl, Quad, Fd_set, Sigaction, Fcntl, Mprot, Mmapflags, Whence, Readlinkres, Umtx, Sigset, Sigprocmask, Kevent, Sockdomain, Socktype, Open, Fcntlflag, Rusage, BinString, Shutdown, Resource, Rlimit, Timeval2, - Pathconf, Rforkflags }; + Pathconf, Rforkflags, ExitStatus, Waitoptions, Idtype }; #define ARG_MASK 0xff #define OUT 0x100 diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c index 99a377f..5369dec 100644 --- a/usr.bin/truss/syscalls.c +++ b/usr.bin/truss/syscalls.c @@ -39,12 +39,13 @@ static const char rcsid[] = * arguments. */ -#include <sys/mman.h> #include <sys/types.h> +#include <sys/mman.h> #include <sys/ptrace.h> #include <sys/socket.h> #include <sys/time.h> #include <sys/un.h> +#include <sys/wait.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/ioccom.h> @@ -263,6 +264,12 @@ static struct syscall syscalls[] = { .args = { { Name , 0 } , { Name, 1 } } }, { .name = "posix_openpt", .ret_type = 1, .nargs = 1, .args = { { Open, 0 } } }, + { .name = "wait4", .ret_type = 1, .nargs = 4, + .args = { { Int, 0 }, { ExitStatus | OUT, 1 }, { Waitoptions, 2 }, + { Rusage | OUT, 3 } } }, + { .name = "wait6", .ret_type = 1, .nargs = 6, + .args = { { Idtype, 0 }, { Int, 1 }, { ExitStatus | OUT, 2 }, + { Waitoptions, 3 }, { Rusage | OUT, 4 }, { Ptr, 5 } } }, { .name = 0 }, }; @@ -381,6 +388,17 @@ static struct xlat rfork_flags[] = { X(RFSIGSHARE) X(RFTSIGZMB) X(RFLINUXTHPN) XEND }; +static struct xlat wait_options[] = { + X(WNOHANG) X(WUNTRACED) X(WCONTINUED) X(WNOWAIT) X(WEXITED) + X(WTRAPPED) XEND +}; + +static struct xlat idtype_arg[] = { + X(P_PID) X(P_PPID) X(P_PGID) X(P_SID) X(P_CID) X(P_UID) X(P_GID) + X(P_ALL) X(P_LWPID) X(P_TASKID) X(P_PROJID) X(P_POOLID) X(P_JAILID) + X(P_CTID) X(P_CPUID) X(P_PSETID) XEND +}; + #undef X #undef XEND @@ -537,6 +555,16 @@ get_string(pid_t pid, void *offset, int max) } } +static char * +strsig2(int sig) +{ + char *tmp; + + tmp = strsig(sig); + if (tmp == NULL) + asprintf(&tmp, "%d", sig); + return (tmp); +} /* * print_arg @@ -822,19 +850,14 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, free(fds); break; } - case Signal: { - long sig; - - sig = args[sc->offset]; - tmp = strsig(sig); - if (tmp == NULL) - asprintf(&tmp, "%ld", sig); + case Signal: + tmp = strsig2(args[sc->offset]); break; - } case Sigset: { long sig; sigset_t ss; int i, used; + char *signame; sig = args[sc->offset]; if (get_struct(pid, (void *)args[sc->offset], (void *)&ss, @@ -845,8 +868,11 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, tmp = malloc(sys_nsig * 8); /* 7 bytes avg per signal name */ used = 0; for (i = 1; i < sys_nsig; i++) { - if (sigismember(&ss, i)) - used += sprintf(tmp + used, "%s|", strsig(i)); + if (sigismember(&ss, i)) { + signame = strsig(i); + used += sprintf(tmp + used, "%s|", signame); + free(signame); + } } if (used) tmp[used-1] = 0; @@ -1143,6 +1169,35 @@ print_arg(struct syscall_args *sc, unsigned long *args, long retval, asprintf(&tmp, "0x%lx", args[sc->offset]); break; } + case ExitStatus: { + char *signame; + int status; + signame = NULL; + if (get_struct(pid, (void *)args[sc->offset], &status, + sizeof(status)) != -1) { + if (WIFCONTINUED(status)) + tmp = strdup("{ CONTINUED }"); + else if (WIFEXITED(status)) + asprintf(&tmp, "{ EXITED,val=%d }", + WEXITSTATUS(status)); + else if (WIFSIGNALED(status)) + asprintf(&tmp, "{ SIGNALED,sig=%s%s }", + signame = strsig2(WTERMSIG(status)), + WCOREDUMP(status) ? ",cored" : ""); + else + asprintf(&tmp, "{ STOPPED,sig=%s }", + signame = strsig2(WTERMSIG(status))); + } else + asprintf(&tmp, "0x%lx", args[sc->offset]); + free(signame); + break; + } + case Waitoptions: + tmp = strdup(xlookup_bits(wait_options, args[sc->offset])); + break; + case Idtype: + tmp = strdup(xlookup(idtype_arg, args[sc->offset])); + break; default: errx(1, "Invalid argument type %d\n", sc->type & ARG_MASK); } |