diff options
author | Dan Kimmel <dan.kimmel@delphix.com> | 2013-03-14 21:56:45 -0800 |
---|---|---|
committer | Christopher Siden <chris.siden@delphix.com> | 2013-03-14 22:56:45 -0700 |
commit | 7994dfdd2a48fab1a1e1dc23109801c2f4cac5b3 (patch) | |
tree | a0e8c519714c6a9e78d2bee6ac4a933ae1443c7f | |
parent | fd9d0a82261102319cc3b862d8f2609c68e0fd23 (diff) | |
download | illumos-joyent-7994dfdd2a48fab1a1e1dc23109801c2f4cac5b3.tar.gz |
3567 dtrace print() doesn't play well with ::dtrace
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Gordon Ross <gwr@nexenta.com>
Approved by: Garrett D'Amore <garrett@damore.org>
-rw-r--r-- | usr/src/cmd/mdb/common/modules/dtrace/dtrace.c | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/usr/src/cmd/mdb/common/modules/dtrace/dtrace.c b/usr/src/cmd/mdb/common/modules/dtrace/dtrace.c index 265322e3f5..f484828b75 100644 --- a/usr/src/cmd/mdb/common/modules/dtrace/dtrace.c +++ b/usr/src/cmd/mdb/common/modules/dtrace/dtrace.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. */ /* @@ -43,6 +44,8 @@ #include <ctype.h> #include <errno.h> #include <math.h> +#include <stdio.h> +#include <unistd.h> /*ARGSUSED*/ int @@ -871,8 +874,41 @@ typedef struct dtrace_dcmddata { int dtdd_quiet; int dtdd_flowindent; int dtdd_heading; + FILE *dtdd_output; } dtrace_dcmddata_t; +/* + * Helper to grab all the content from a file, spit it into a string, and erase + * and reset the file. + */ +static void +print_and_truncate_file(FILE *fp) +{ + long len; + char *out; + + /* flush, find length of file, seek to beginning, initialize buffer */ + if (fflush(fp) || (len = ftell(fp)) < 0 || + fseek(fp, 0, SEEK_SET) < 0) { + mdb_warn("couldn't prepare DTrace output file: %d\n", errno); + return; + } + + out = mdb_alloc(len + 1, UM_SLEEP); + out[len] = '\0'; + + /* read file into buffer, truncate file, and seek to beginning */ + if ((fread(out, len + 1, sizeof (char), fp) == 0 && ferror(fp)) || + ftruncate(fileno(fp), 0) < 0 || fseek(fp, 0, SEEK_SET) < 0) { + mdb_warn("couldn't read DTrace output file: %d\n", errno); + mdb_free(out, len + 1); + return; + } + + mdb_printf("%s", out); + mdb_free(out, len + 1); +} + /*ARGSUSED*/ static int dtrace_dcmdrec(const dtrace_probedata_t *data, @@ -880,6 +916,8 @@ dtrace_dcmdrec(const dtrace_probedata_t *data, { dtrace_dcmddata_t *dd = arg; + print_and_truncate_file(dd->dtdd_output); + if (rec == NULL) { /* * We have processed the final record; output the newline if @@ -1083,7 +1121,12 @@ dtrace(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) goto err; } - if (dtrace_consume(dtp, NULL, + if ((dd.dtdd_output = tmpfile()) == NULL) { + mdb_warn("couldn't open DTrace output file: %d\n", errno); + goto err; + } + + if (dtrace_consume(dtp, dd.dtdd_output, dtrace_dcmdprobe, dtrace_dcmdrec, &dd) == -1) { mdb_warn("couldn't consume DTrace buffers: %s\n", dtrace_errmsg(dtp, dtrace_errno(dtp))); @@ -1098,6 +1141,7 @@ dtrace(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) rval = DCMD_OK; err: dtrace_close(dtp); + fclose(dd.dtdd_output); return (rval); } |