diff options
author | bdrewery <bdrewery@FreeBSD.org> | 2015-10-06 21:58:38 +0000 |
---|---|---|
committer | bdrewery <bdrewery@FreeBSD.org> | 2015-10-06 21:58:38 +0000 |
commit | 7c2a5d79afd81f0e773ba7ddc4fe40c4c3d62627 (patch) | |
tree | 52c11c1990eccc6a0f7281e868a447f7a337a01d /usr.bin/truss | |
parent | cb4dcd0eff4e6b716d70dbc789e83538ea109d30 (diff) | |
download | FreeBSD-src-7c2a5d79afd81f0e773ba7ddc4fe40c4c3d62627.zip FreeBSD-src-7c2a5d79afd81f0e773ba7ddc4fe40c4c3d62627.tar.gz |
truss: Add support for utrace(2).
This uses the kdump(1) utrace support code directly until a common library
is created.
This allows malloc(3) tracing with MALLOC_CONF=utrace:true and rtld tracing
with LD_UTRACE=1. Unknown utrace(2) data is just printed as hex.
PR: 43819 [inspired by]
Reviewed by: jhb
MFC after: 2 weeks
Relnotes: yes
Differential Revision: https://reviews.freebsd.org/D3819
Diffstat (limited to 'usr.bin/truss')
-rw-r--r-- | usr.bin/truss/Makefile | 3 | ||||
-rw-r--r-- | usr.bin/truss/syscall.h | 3 | ||||
-rw-r--r-- | usr.bin/truss/syscalls.c | 37 | ||||
-rw-r--r-- | usr.bin/truss/truss.1 | 5 |
4 files changed, 45 insertions, 3 deletions
diff --git a/usr.bin/truss/Makefile b/usr.bin/truss/Makefile index 1cd0a9c..8c78196 100644 --- a/usr.bin/truss/Makefile +++ b/usr.bin/truss/Makefile @@ -10,6 +10,9 @@ SRCS+= ${MACHINE_ARCH}-fbsd.c SRCS+= ${MACHINE_CPUARCH}-fbsd.c .endif +.PATH: ${.CURDIR:H}/kdump +SRCS+= utrace.c + CFLAGS+= -I${.CURDIR} -I. CLEANFILES= syscalls.master syscalls.h ioctl.c diff --git a/usr.bin/truss/syscall.h b/usr.bin/truss/syscall.h index 3e3a1b9..a870810 100644 --- a/usr.bin/truss/syscall.h +++ b/usr.bin/truss/syscall.h @@ -27,6 +27,7 @@ * Sigprocmask -- the first argument to sigprocmask(). Prints the name. * Kevent -- a pointer to an array of struct kevents. Prints all elements. * Pathconf -- the 2nd argument of pathconf(). + * Utrace -- utrace(2) buffer. * * In addition, the pointer types (String, Ptr) may have OUT masked in -- * this means that the data is set on *return* from the system call -- or @@ -43,7 +44,7 @@ enum Argtype { None = 1, Hex, Octal, Int, LongHex, Name, Ptr, Stat, Ioctl, Quad, Fcntlflag, Rusage, BinString, Shutdown, Resource, Rlimit, Timeval2, Pathconf, Rforkflags, ExitStatus, Waitoptions, Idtype, Procctl, LinuxSockArgs, Umtxop, Atfd, Atflags, Timespec2, Accessmode, Long, - Sysarch, ExecArgs, ExecEnv, PipeFds, QuadHex }; + Sysarch, ExecArgs, ExecEnv, PipeFds, QuadHex, Utrace }; #define ARG_MASK 0xff #define OUT 0x100 diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c index 540138d..d14fa86 100644 --- a/usr.bin/truss/syscalls.c +++ b/usr.bin/truss/syscalls.c @@ -72,6 +72,9 @@ __FBSDID("$FreeBSD$"); #include "extern.h" #include "syscall.h" +/* usr.bin/kdump/utrace.c */ +int kdump_print_utrace(FILE *, void *, size_t, int); + /* 64-bit alignment on 32-bit platforms. */ #if !defined(__LP64__) && defined(__powerpc__) #define QUAD_ALIGN 1 @@ -342,6 +345,8 @@ static struct syscall decoded_syscalls[] = { { Atflags, 3 } } }, { .name = "utimes", .ret_type = 1, .nargs = 2, .args = { { Name | IN, 0 }, { Timeval2 | IN, 1 } } }, + { .name = "utrace", .ret_type = 1, .nargs = 1, + .args = { { Utrace, 0 } } }, { .name = "wait4", .ret_type = 1, .nargs = 4, .args = { { Int, 0 }, { ExitStatus | OUT, 1 }, { Waitoptions, 2 }, { Rusage | OUT, 3 } } }, @@ -860,6 +865,24 @@ print_kevent(FILE *fp, struct kevent *ke, int input) fprintf(fp, ",%p,%p", (void *)ke->data, (void *)ke->udata); } +static void +print_utrace(FILE *fp, void *utrace_addr, size_t len) +{ + unsigned char *utrace_buffer; + + fprintf(fp, "{ "); + if (kdump_print_utrace(fp, utrace_addr, len, 0)) { + fprintf(fp, " }"); + return; + } + + utrace_buffer = utrace_addr; + fprintf(fp, "%zu:", len); + while (len--) + fprintf(fp, " %02x", *utrace_buffer++); + fprintf(fp, " }"); +} + /* * Converts a syscall argument into a string. Said string is * allocated via malloc(), so needs to be free()'d. sc is @@ -1601,6 +1624,20 @@ print_arg(struct syscall_args *sc, unsigned long *args, long *retval, fprintf(fp, "{ %ld, %ld }", retval[0], retval[1]); retval[0] = 0; break; + case Utrace: { + size_t len; + void *utrace_addr; + + len = args[sc->offset + 1]; + utrace_addr = calloc(1, len); + if (get_struct(pid, (void *)args[sc->offset], + (void *)utrace_addr, len) != -1) + print_utrace(fp, utrace_addr, len); + else + fprintf(fp, "0x%lx", args[sc->offset]); + free(utrace_addr); + break; + } default: errx(1, "Invalid argument type %d\n", sc->type & ARG_MASK); } diff --git a/usr.bin/truss/truss.1 b/usr.bin/truss/truss.1 index 6a01451..7c148df 100644 --- a/usr.bin/truss/truss.1 +++ b/usr.bin/truss/truss.1 @@ -1,6 +1,6 @@ .\" $FreeBSD$ .\" -.Dd May 12, 2009 +.Dd October 5, 2015 .Dt TRUSS 1 .Os .Sh NAME @@ -95,7 +95,8 @@ options are mutually exclusive.) .Sh SEE ALSO .Xr kdump 1 , .Xr ktrace 1 , -.Xr ptrace 2 +.Xr ptrace 2 , +.Xr utrace 2 .Sh HISTORY The .Nm |