diff options
226 files changed, 9814 insertions, 644 deletions
diff --git a/cddl/contrib/dtracetoolkit/dtruss b/cddl/contrib/dtracetoolkit/dtruss new file mode 100755 index 000000000000..f4b5e45a30df --- /dev/null +++ b/cddl/contrib/dtracetoolkit/dtruss @@ -0,0 +1,467 @@ +#!/usr/bin/sh +# +# dtruss - print process system call time details. +# Written using DTrace (Solaris 10 3/05). +# +# $Id: dtruss 9 2007-08-07 10:21:07Z brendan $ +# +# USAGE: dtruss [-acdeflhoLs] [-t syscall] { -p PID | -n name | command } +# +# -p PID # examine this PID +# -n name # examine this process name +# -t syscall # examine this syscall only +# -a # print all details +# -c # print system call counts +# -d # print relative timestamps (us) +# -e # print elapsed times (us) +# -f # follow children as they are forked +# -l # force printing of pid/lwpid per line +# -o # print on cpu times (us) +# -s # print stack backtraces +# -L # don't print pid/lwpid per line +# -b bufsize # dynamic variable buf size (default is "4m") +# eg, +# dtruss df -h # run and examine the "df -h" command +# dtruss -p 1871 # examine PID 1871 +# dtruss -n tar # examine all processes called "tar" +# dtruss -f test.sh # run test.sh and follow children +# +# See the man page dtruss(1M) for further details. +# +# SEE ALSO: procsystime # DTraceToolkit +# dapptrace # DTraceToolkit +# truss +# +# COPYRIGHT: Copyright (c) 2005, 2006, 2007 Brendan Gregg. +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at Docs/cddl1.txt +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# CDDL HEADER END +# +# TODO: Track signals, more output formatting. +# +# 29-Apr-2005 Brendan Gregg Created this. +# 09-May-2005 " " Fixed evaltime (thanks Adam L.) +# 16-May-2005 " " Added -t syscall tracing. +# 17-Jun-2005 " " Added -s stack backtraces. +# 17-Jun-2005 " " Last update. +# 29-Jun-2007 " " Used progenyof() (thanks Aaron Gutman). +# 06-Aug-2007 " " Various updates. +# + + +############################## +# --- Process Arguments --- +# + +### Default variables +opt_pid=0; opt_name=0; pid=0; pname="."; opt_elapsed=0; opt_cpu=0 +opt_counts=0; opt_relative=0; opt_printid=0; opt_follow=0; opt_command=0 +command=""; opt_buf=0; buf="4m"; opt_trace=0; trace="."; opt_stack=0 + +### Process options +while getopts ab:cdefhln:op:st:L name +do + case $name in + b) opt_buf=1; buf=$OPTARG ;; + p) opt_pid=1; pid=$OPTARG ;; + n) opt_name=1; pname=$OPTARG ;; + t) opt_trace=1; trace=$OPTARG ;; + a) opt_counts=1; opt_relative=1; opt_elapsed=1; opt_follow=1 + opt_printid=1; opt_cpu=1 ;; + c) opt_counts=1 ;; + d) opt_relative=1 ;; + e) opt_elapsed=1 ;; + f) opt_follow=1 ;; + l) opt_printid=1 ;; + o) opt_cpu=1 ;; + L) opt_printid=-1 ;; + s) opt_stack=-1 ;; + h|?) cat <<-END >&2 + USAGE: dtruss [-acdefholLs] [-t syscall] { -p PID | -n name | command } + + -p PID # examine this PID + -n name # examine this process name + -t syscall # examine this syscall only + -a # print all details + -c # print syscall counts + -d # print relative times (us) + -e # print elapsed times (us) + -f # follow children (-p or cmd only) + -l # force printing pid/lwpid + -o # print on cpu times + -s # print stack backtraces + -L # don't print pid/lwpid + -b bufsize # dynamic variable buf size + eg, + dtruss df -h # run and examine "df -h" + dtruss -p 1871 # examine PID 1871 + dtruss -n tar # examine all processes called "tar" + dtruss -f test.sh # run test.sh and follow children + END + exit 1 + esac +done +shift `expr $OPTIND - 1` + +### Option logic +if [ $opt_pid -eq 0 -a $opt_name -eq 0 ]; then + opt_command=1 + if [ "$*" = "" ]; then + $0 -h + exit + fi + command="$*" # yes, I meant $*! +fi +if [ $opt_follow -eq 1 -o $opt_name -eq 1 ]; then + if [ $opt_printid -ne -1 ]; then + opt_printid=1 + else + opt_printid=0 + fi +fi +if [ $opt_follow -eq 1 -a $opt_name -eq 1 ]; then + echo "ERROR: -f option cannot be used with -n (use -p or cmd instead)." + exit 1 +fi + +### Option translation +if [ "$trace" = "exec" ]; then trace="exece"; fi +if [ "$trace" = "time" ]; then trace="gtime"; fi +if [ "$trace" = "exit" ]; then trace="rexit"; fi + + +################################# +# --- Main Program, DTrace --- +# + +### Define D Script +dtrace=' +#pragma D option quiet +#pragma D option switchrate=10 + +/* + * Command line arguments + */ +inline int OPT_command = '$opt_command'; +inline int OPT_follow = '$opt_follow'; +inline int OPT_printid = '$opt_printid'; +inline int OPT_relative = '$opt_relative'; +inline int OPT_elapsed = '$opt_elapsed'; +inline int OPT_cpu = '$opt_cpu'; +inline int OPT_counts = '$opt_counts'; +inline int OPT_pid = '$opt_pid'; +inline int OPT_name = '$opt_name'; +inline int OPT_trace = '$opt_trace'; +inline int OPT_stack = '$opt_stack'; +inline string NAME = "'$pname'"; +inline string TRACE = "'$trace'"; + +dtrace:::BEGIN +{ + /* print header */ + OPT_printid ? printf("%-9s ", "PID/LWP") : 1; + OPT_relative ? printf("%8s ", "RELATIVE") : 1; + OPT_elapsed ? printf("%7s ", "ELAPSD") : 1; + OPT_cpu ? printf("%6s ", "CPU") : 1; + printf("SYSCALL(args) \t\t = return\n"); +} + +/* + * Save syscall entry info + */ +syscall:::entry +/((OPT_command || OPT_pid) && pid == $target) || + (OPT_name && execname == NAME) || + (OPT_follow && progenyof($target))/ +{ + /* set start details */ + self->start = timestamp; + self->vstart = vtimestamp; + self->arg0 = arg0; + self->arg1 = arg1; + self->arg2 = arg2; + + /* count occurances */ + OPT_counts == 1 ? @Counts[probefunc] = count() : 1; +} + +/* + * Follow children + */ +syscall::fork*:return +/(OPT_follow && progenyof($target)) && (!OPT_trace || (TRACE == probefunc))/ +{ + /* print output */ + self->code = errno == 0 ? "" : "Err#"; + OPT_printid ? printf("%6d/%d: ", pid, tid) : 1; + OPT_relative ? printf("%8d: ", vtimestamp/1000) : 1; + OPT_elapsed ? printf("%7d: ", 0) : 1; + OPT_cpu ? printf("%6d ", 0) : 1; + printf("%s(0x%X, 0x%X, 0x%X)\t\t = %d %s%d\n", probefunc, + self->arg0, self->arg1, self->arg2, (int)arg0, self->code, + (int)errno); +} + +/* + * Check for syscall tracing + */ +syscall:::entry +/OPT_trace && probefunc != TRACE/ +{ + /* drop info */ + self->start = 0; + self->vstart = 0; + self->arg0 = 0; + self->arg1 = 0; + self->arg2 = 0; +} + +/* + * Print return data + */ + +/* + * The following code is written in an intentionally repetative way. + * The first versions had no code redundancies, but performed badly during + * benchmarking. The priority here is speed, not cleverness. I know there + * are many obvious shortcuts to this code, I have tried them. This style has + * shown in benchmarks to be the fastest (fewest probes fired, fewest actions). + */ + +/* print 3 args, return as hex */ +syscall::lwp_sigmask:return +/self->start/ +{ + /* calculate elapsed time */ + this->elapsed = timestamp - self->start; + self->start = 0; + this->cpu = vtimestamp - self->vstart; + self->vstart = 0; + self->code = errno == 0 ? "" : "Err#"; + + /* print optional fields */ + OPT_printid ? printf("%6d/%d: ", pid, tid) : 1; + OPT_relative ? printf("%8d ", vtimestamp/1000) : 1; + OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1; + OPT_cpu ? printf("%6d ", this->cpu/1000) : 1; + + /* print main data */ + printf("%s(0x%X, 0x%X, 0x%X)\t\t = 0x%X %s%d\n", probefunc, + (int)self->arg0, self->arg1, self->arg2, (int)arg0, + self->code, (int)errno); + OPT_stack ? ustack() : 1; + OPT_stack ? trace("\n") : 1; + self->arg0 = 0; + self->arg1 = 0; + self->arg2 = 0; +} + +/* print 3 args, arg0 as a string */ +syscall::stat*:return, +syscall::lstat*:return, +syscall::open*:return, +syscall::resolvepath:return +/self->start/ +{ + /* calculate elapsed time */ + this->elapsed = timestamp - self->start; + self->start = 0; + this->cpu = vtimestamp - self->vstart; + self->vstart = 0; + self->code = errno == 0 ? "" : "Err#"; + + /* print optional fields */ + OPT_printid ? printf("%6d/%d: ", pid, tid) : 1; + OPT_relative ? printf("%8d ", vtimestamp/1000) : 1; + OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1; + OPT_cpu ? printf("%6d ", this->cpu/1000) : 1; + + /* print main data */ + printf("%s(\"%S\", 0x%X, 0x%X)\t\t = %d %s%d\n", probefunc, + copyinstr(self->arg0), self->arg1, self->arg2, (int)arg0, + self->code, (int)errno); + OPT_stack ? ustack() : 1; + OPT_stack ? trace("\n") : 1; + self->arg0 = 0; + self->arg1 = 0; + self->arg2 = 0; +} + +/* print 3 args, arg1 as a string */ +syscall::write:return, +syscall::pwrite:return, +syscall::*read*:return +/self->start/ +{ + /* calculate elapsed time */ + this->elapsed = timestamp - self->start; + self->start = 0; + this->cpu = vtimestamp - self->vstart; + self->vstart = 0; + self->code = errno == 0 ? "" : "Err#"; + + /* print optional fields */ + OPT_printid ? printf("%6d/%d: ", pid, tid) : 1; + OPT_relative ? printf("%8d ", vtimestamp/1000) : 1; + OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1; + OPT_cpu ? printf("%6d ", this->cpu/1000) : 1; + + /* print main data */ + printf("%s(0x%X, \"%S\", 0x%X)\t\t = %d %s%d\n", probefunc, self->arg0, + stringof(copyin(self->arg1, self->arg2)), self->arg2, (int)arg0, + self->code, (int)errno); + OPT_stack ? ustack() : 1; + OPT_stack ? trace("\n") : 1; + self->arg0 = 0; + self->arg1 = 0; + self->arg2 = 0; +} + +/* print 0 arg output */ +syscall::gtime:return, +syscall::*fork*:return +/self->start/ +{ + /* calculate elapsed time */ + this->elapsed = timestamp - self->start; + self->start = 0; + this->cpu = vtimestamp - self->vstart; + self->vstart = 0; + self->code = errno == 0 ? "" : "Err#"; + + /* print optional fields */ + OPT_printid ? printf("%6d/%d: ", pid, tid) : 1; + OPT_relative ? printf("%8d ", vtimestamp/1000) : 1; + OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1; + OPT_cpu ? printf("%6d ", this->cpu/1000) : 1; + + /* print main data */ + printf("%s()\t\t = %d %s%d\n", probefunc, + (int)arg0, self->code, (int)errno); + OPT_stack ? ustack() : 1; + OPT_stack ? trace("\n") : 1; + self->arg0 = 0; + self->arg1 = 0; + self->arg2 = 0; +} + +/* print 1 arg output */ +syscall::brk:return, +syscall::times:return, +syscall::stime:return, +syscall::close:return +/self->start/ +{ + /* calculate elapsed time */ + this->elapsed = timestamp - self->start; + self->start = 0; + this->cpu = vtimestamp - self->vstart; + self->vstart = 0; + self->code = errno == 0 ? "" : "Err#"; + + /* print optional fields */ + OPT_printid ? printf("%6d/%d: ", pid, tid) : 1; + OPT_relative ? printf("%8d ", vtimestamp/1000) : 1; + OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1; + OPT_cpu ? printf("%6d ", this->cpu/1000) : 1; + + /* print main data */ + printf("%s(0x%X)\t\t = %d %s%d\n", probefunc, self->arg0, + (int)arg0, self->code, (int)errno); + OPT_stack ? ustack() : 1; + OPT_stack ? trace("\n") : 1; + self->arg0 = 0; + self->arg1 = 0; + self->arg2 = 0; +} + +/* print 2 arg output */ +syscall::utime:return, +syscall::munmap:return +/self->start/ +{ + /* calculate elapsed time */ + this->elapsed = timestamp - self->start; + self->start = 0; + this->cpu = vtimestamp - self->vstart; + self->vstart = 0; + self->code = errno == 0 ? "" : "Err#"; + + /* print optional fields */ + OPT_printid ? printf("%6d/%d: ", pid, tid) : 1; + OPT_relative ? printf("%8d ", vtimestamp/1000) : 1; + OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1; + OPT_cpu ? printf("%6d ", this->cpu/1000) : 1; + + /* print main data */ + printf("%s(0x%X, 0x%X)\t\t = %d %s%d\n", probefunc, self->arg0, + self->arg1, (int)arg0, self->code, (int)errno); + OPT_stack ? ustack() : 1; + OPT_stack ? trace("\n") : 1; + self->arg0 = 0; + self->arg1 = 0; + self->arg2 = 0; +} + +/* print 3 arg output - default */ +syscall:::return +/self->start/ +{ + /* calculate elapsed time */ + this->elapsed = timestamp - self->start; + self->start = 0; + this->cpu = vtimestamp - self->vstart; + self->vstart = 0; + self->code = errno == 0 ? "" : "Err#"; + + /* print optional fields */ + OPT_printid ? printf("%6d/%d: ", pid, tid) : 1; + OPT_relative ? printf("%8d ", vtimestamp/1000) : 1; + OPT_elapsed ? printf("%7d ", this->elapsed/1000) : 1; + OPT_cpu ? printf("%6d ", this->cpu/1000) : 1; + + /* print main data */ + printf("%s(0x%X, 0x%X, 0x%X)\t\t = %d %s%d\n", probefunc, self->arg0, + self->arg1, self->arg2, (int)arg0, self->code, (int)errno); + OPT_stack ? ustack() : 1; + OPT_stack ? trace("\n") : 1; + self->arg0 = 0; + self->arg1 = 0; + self->arg2 = 0; +} + +/* program exited */ +proc:::exit +/(OPT_command || OPT_pid) && pid == $target/ +{ + exit(0); +} + +/* print counts */ +dtrace:::END +{ + OPT_counts == 1 ? printf("\n%-32s %16s\n", "CALL", "COUNT") : 1; + OPT_counts == 1 ? printa("%-32s %@16d\n", @Counts) : 1; +} +' + +### Run DTrace +if [ $opt_command -eq 1 ]; then + /usr/sbin/dtrace -x dynvarsize=$buf -x evaltime=exec -n "$dtrace" \ + -c "$command" >&2 +elif [ $opt_pid -eq 1 ]; then + /usr/sbin/dtrace -x dynvarsize=$buf -n "$dtrace" -p "$pid" >&2 +else + /usr/sbin/dtrace -x dynvarsize=$buf -n "$dtrace" >&2 +fi diff --git a/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c index 2580e6323a83..63721abc7132 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c +++ b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c @@ -773,19 +773,27 @@ compile_str(dtrace_cmd_t *dcp) static void prochandler(struct ps_prochandle *P, const char *msg, void *arg) { -fatal("DOODAD in function %s, file %s, line %d\n",__FUNCTION__,__FILE__,__LINE__); -#ifdef DOODAD +#if defined(sun) const psinfo_t *prp = Ppsinfo(P); int pid = Pstatus(P)->pr_pid; char name[SIG2STR_MAX]; +#else + int wstatus = proc_getwstat(P); + int pid = proc_getpid(P); +#endif if (msg != NULL) { notice("pid %d: %s\n", pid, msg); return; } +#if defined(sun) switch (Pstate(P)) { +#else + switch (proc_state(P)) { +#endif case PS_UNDEAD: +#if defined(sun) /* * Ideally we would like to always report pr_wstat here, but it * isn't possible given current /proc semantics. If we grabbed @@ -798,9 +806,20 @@ fatal("DOODAD in function %s, file %s, line %d\n",__FUNCTION__,__FILE__,__LINE__ notice("pid %d terminated by %s\n", pid, proc_signame(WTERMSIG(prp->pr_wstat), name, sizeof (name))); +#else + if (WIFSIGNALED(wstatus)) { + notice("pid %d terminated by %d\n", pid, + WTERMSIG(wstatus)); +#endif +#if defined(sun) } else if (prp != NULL && WEXITSTATUS(prp->pr_wstat) != 0) { notice("pid %d exited with status %d\n", pid, WEXITSTATUS(prp->pr_wstat)); +#else + } else if (WEXITSTATUS(wstatus) != 0) { + notice("pid %d exited with status %d\n", + pid, WEXITSTATUS(wstatus)); +#endif } else { notice("pid %d has exited\n", pid); } @@ -812,7 +831,6 @@ fatal("DOODAD in function %s, file %s, line %d\n",__FUNCTION__,__FILE__,__LINE__ g_pslive--; break; } -#endif } /*ARGSUSED*/ diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/baddof/baddof.c b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/baddof/baddof.c index 679ec53d86f1..1c14c6592c88 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/baddof/baddof.c +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/baddof/baddof.c @@ -20,12 +20,10 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/stat.h> #include <stdio.h> #include <stdlib.h> @@ -162,7 +160,7 @@ main(int argc, char **argv) FILE *fp; unsigned char *dof, *copy; - if (argc < 1) + if (argc < 2) fatal("expected D script as argument\n"); if ((fp = fopen(filename, "r")) == NULL) diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/chkargs/chkargs.c b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/chkargs/chkargs.c index 36042e3f7274..a7e0222fd0ea 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/chkargs/chkargs.c +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/chkargs/chkargs.c @@ -20,12 +20,10 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <strings.h> #include <unistd.h> #include <dtrace.h> @@ -35,6 +33,7 @@ static int g_errs; static int g_fd; static int g_verbose; static int g_errexit; +static char *g_progname; static int probe(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp, void *data) @@ -91,9 +90,11 @@ main(int argc, char *argv[]) int err, c; char *p; + g_progname = argv[0]; + if ((dtp = dtrace_open(DTRACE_VERSION, 0, &err)) == NULL) { (void) fprintf(stderr, "%s: failed to open dtrace: %s\n", - argv[0], dtrace_errmsg(dtp, err)); + g_progname, dtrace_errmsg(dtp, err)); return (1); } @@ -111,7 +112,7 @@ main(int argc, char *argv[]) if (dtrace_setopt(dtp, optarg, p) != 0) { (void) fprintf(stderr, "%s: failed to set " - "option -x %s: %s\n", argv[0], optarg, + "option -x %s: %s\n", g_progname, optarg, dtrace_errmsg(dtp, dtrace_errno(dtp))); return (2); } @@ -119,7 +120,7 @@ main(int argc, char *argv[]) default: (void) fprintf(stderr, "Usage: %s [-ev] " - "[-x opt[=arg]] [probedesc]\n", argv[0]); + "[-x opt[=arg]] [probedesc]\n", g_progname); return (2); } } @@ -128,9 +129,9 @@ main(int argc, char *argv[]) argc -= optind; if (argc > 0) { - if (dtrace_str2desc(dtp, DTRACE_PROBESPEC_NAME, argv[1], &pd)) { + if (dtrace_str2desc(dtp, DTRACE_PROBESPEC_NAME, argv[0], &pd)) { (void) fprintf(stderr, "%s: invalid probe description " - "%s: %s\n", argv[0], argv[1], + "%s: %s\n", g_progname, argv[0], dtrace_errmsg(dtp, dtrace_errno(dtp))); return (2); } diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/scripts/dstyle.pl b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/scripts/dstyle.pl index cb47c7cbfd1c..3c3e180a0e75 100644..100755 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/scripts/dstyle.pl +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/scripts/dstyle.pl @@ -21,12 +21,11 @@ # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -#pragma ident "%Z%%M% %I% %E% SMI" -require 5.6.1; +require 5.8.4; $PNAME = $0; $PNAME =~ s:.*/::; diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/scripts/dtest.pl b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/scripts/dtest.pl index e8d9032fcd6c..7b47580ddf62 100644..100755 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/scripts/dtest.pl +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/scripts/dtest.pl @@ -24,9 +24,8 @@ # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" -require 5.6.1; +require 5.8.4; use File::Find; use File::Basename; @@ -40,10 +39,11 @@ $OPTSTR = 'abd:fghi:jlnqsx:'; $USAGE = "Usage: $PNAME [-abfghjlnqs] [-d dir] [-i isa] " . "[-x opt[=arg]] [file | dir ...]\n"; ($MACH = `uname -p`) =~ s/\W*\n//; +($PLATFORM = `uname -i`) =~ s/\W*\n//; @dtrace_argv = (); -$ksh_path = '/bin/sh'; +$ksh_path = '/usr/local/bin/ksh'; @files = (); %exceptions = (); @@ -215,17 +215,17 @@ sub is_exception { } # -# Iterate over the set of test files specified on the command-line or by -# a find on "$defdir/common" and "$defdir/$MACH" and execute each one. -# If the test file is executable, we fork and exec it. If the test is a -# .ksh file, we run it with $ksh_path. Otherwise we run dtrace -s on it. -# If the file is named tst.* we assume it should return exit status 0. -# If the file is named err.* we assume it should return exit status 1. -# If the file is named err.D_[A-Z0-9]+[.*].d we use dtrace -xerrtags and -# examine stderr to ensure that a matching error tag was produced. -# If the file is named drp.[A-Z0-9]+[.*].d we use dtrace -xdroptags and -# examine stderr to ensure that a matching drop tag was produced. -# If any *.out or *.err files are found we perform output comparisons. +# Iterate over the set of test files specified on the command-line or by a find +# on "$defdir/common", "$defdir/$MACH" and "$defdir/$PLATFORM" and execute each +# one. If the test file is executable, we fork and exec it. If the test is a +# .ksh file, we run it with $ksh_path. Otherwise we run dtrace -s on it. If +# the file is named tst.* we assume it should return exit status 0. If the +# file is named err.* we assume it should return exit status 1. If the file is +# named err.D_[A-Z0-9]+[.*].d we use dtrace -xerrtags and examine stderr to +# ensure that a matching error tag was produced. If the file is named +# drp.[A-Z0-9]+[.*].d we use dtrace -xdroptags and examine stderr to ensure +# that a matching drop tag was produced. If any *.out or *.err files are found +# we perform output comparisons. # # run_tests takes two arguments: The first is the pathname of the dtrace # command to invoke when running the tests. The second is the pathname @@ -548,6 +548,7 @@ $bindir = -d $dt_bin ? $dt_bin : '.'; find(\&wanted, "$defdir/common") if (scalar(@ARGV) == 0); find(\&wanted, "$defdir/$MACH") if (scalar(@ARGV) == 0); +find(\&wanted, "$defdir/$PLATFORM") if (scalar(@ARGV) == 0); die $USAGE if (scalar(@files) == 0); $dtrace_path = '/usr/sbin/dtrace'; diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.stddevtoofew.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.stddevtoofew.d new file mode 100644 index 000000000000..262040f1b820 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.stddevtoofew.d @@ -0,0 +1,41 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * ASSERTION: + * stddev() should not accept a non-scalar value + * + * SECTION: Aggregations/Aggregations + * + */ + +#pragma D option quiet + +BEGIN +{ + @a[pid] = stddev(probefunc); +} + diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.stddevnoarg.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.stddevnoarg.d new file mode 100644 index 000000000000..2952cf50c6d2 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.stddevnoarg.d @@ -0,0 +1,41 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * ASSERTION: + * stddev() should not accept a call with no arguments + * + * SECTION: Aggregations/Aggregations + * + */ + +#pragma D option quiet + +BEGIN +{ + @a[1] = stddev(); +} + diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.stddevtoomany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.stddevtoomany.d new file mode 100644 index 000000000000..c42e9628ce48 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.stddevtoomany.d @@ -0,0 +1,41 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * ASSERTION: + * stddev() should not have more than one argument + * + * SECTION: Aggregations/Aggregations + * + */ + +#pragma D option quiet + +BEGIN +{ + @a[1] = stddev(1, 2); +} + diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearstddev.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearstddev.d new file mode 100644 index 000000000000..af3ecd56a7fd --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearstddev.d @@ -0,0 +1,57 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * ASSERTION: + * Positive stddev() test + * + * SECTION: Aggregations/Aggregations + * + * NOTES: + * Verifies that printing a clear()'d aggregation with an stddev() + * aggregation function doesn't cause problems. + * + */ + +#pragma D option quiet + +tick-10ms +/i++ < 5/ +{ + @a = stddev(timestamp); +} + +tick-10ms +/i == 5/ +{ + exit(2); +} + +END +{ + clear(@a); + exit(0); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearstddev.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearstddev.d.out new file mode 100644 index 000000000000..8d23188fd1f0 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearstddev.d.out @@ -0,0 +1,2 @@ + + 0 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs1.d index 80cffd4c9694..c65fb529e062 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs1.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs1.d @@ -20,15 +20,13 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * ASSERTION: - * Multiple aggregates can be used within the same D script. + * Multiple aggregates can be used within the same D script. * * SECTION: Aggregations/Aggregations * @@ -52,9 +50,11 @@ tick-10ms @c[pid] = avg(new_time); @d[pid] = sum(new_time); @e[pid] = quantize(new_time); - @f[timestamp] = max(new_time); - @g[timestamp] = quantize(new_time); - @h[timestamp] = lquantize(new_time, 0, 10000, 1000); + @f[pid] = stddev(new_time); + @g[timestamp] = max(new_time); + @h[timestamp] = quantize(new_time); + @i[timestamp] = lquantize(new_time, 0, 10000, 1000); + time_1 = time_2; i++; } diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs2.d index 21c05b8e844b..b34d73fa8b84 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs2.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs2.d @@ -20,18 +20,16 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * ASSERTION: - * Test multiple aggregations and the default output order + * Test multiple aggregations and the default output order * * SECTION: Aggregations/Aggregations; - * Aggregations/Output + * Aggregations/Output * */ @@ -51,6 +49,7 @@ tick-10ms @d = max(i); @e = quantize(i); @f = lquantize(i, 0, 1000, 100); + @g = stddev(i); i += 100; } diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs2.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs2.d.out index 2e84e08ead16..579f78dd9bed 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs2.d.out +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs2.d.out @@ -34,3 +34,4 @@ 900 |@@@@ 1 >= 1000 | 0 + 287 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs3.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs3.d index 0685c0dac059..21d2fa9e2d69 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs3.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs3.d @@ -20,19 +20,17 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * ASSERTION: - * Test multiple aggregations and overriding default order with - * printa() statements. + * Test multiple aggregations and overriding default order with + * printa() statements. * * SECTION: Aggregations/Aggregations; - * Aggregations/Output + * Aggregations/Output * * NOTES: This is a simple verifiable test. * @@ -55,6 +53,7 @@ tick-10ms @e = max(i); @f = quantize(i); @g = lquantize(i, 0, 1000, 100); + @h = stddev(i); i += 100; } @@ -62,6 +61,7 @@ tick-10ms tick-10ms /i == 1000/ { + printa("%@d\n", @h); printa("%@d\n", @g); printa("%@d\n", @f); printa("%@d\n", @e); diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs3.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs3.d.out index b0c49a33d3e6..ab976601b2af 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs3.d.out +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.multiaggs3.d.out @@ -1,3 +1,4 @@ +287 value ------------- Distribution ------------- count < 0 | 0 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.stddev.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.stddev.d index 11e99d390553..041b82070f84 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.stddev.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.stddev.d @@ -20,20 +20,19 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - - /* * ASSERTION: - * Positive stddev() test + * Positive stddev() test * * SECTION: Aggregations/Aggregations * * NOTES: This is a simple verifiable positive test of the stddev() function. + * printa() for one aggregation, default printing behavior for the other + * so that we exercise both code paths. */ #pragma D option quiet @@ -60,5 +59,6 @@ BEGIN @b = stddev(-5000000700); @b = stddev(-5000000800); @b = stddev(-5000000900); + printa("%@d\n", @a); exit(0); } diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.stddev.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.stddev.d.out index cec6074081e1..0c02852e452f 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.stddev.d.out +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.stddev.d.out @@ -1,3 +1,3 @@ +287 287 - 287 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.subr.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.subr.d index 5ca1f1ef9389..d508596a97ff 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.subr.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.subr.d @@ -26,7 +26,6 @@ #pragma ident "%Z%%M% %I% %E% SMI" -#include <sys/dtrace.h> #define INTFUNC(x) \ BEGIN \ diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.orthogonality.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.orthogonality.d index f474a572098e..3a7d6a2c6413 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.orthogonality.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/assocs/tst.orthogonality.d @@ -39,13 +39,13 @@ BEGIN } BEGIN -/b[curthread->t_did] == 0/ +/b[curthread->td_flags] == 0/ { exit(0); } BEGIN { - printf("value should be 0; value is %x!", b[curthread->t_did]); + printf("value should be 0; value is %x!", b[curthread->td_flags]); exit(1); } diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.D_PDESC_ZERO.lowfrequency.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.D_PDESC_ZERO.lowfrequency.d new file mode 100644 index 000000000000..1015a251cfeb --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.D_PDESC_ZERO.lowfrequency.d @@ -0,0 +1,45 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * Test to check that attempting to enable a valid event with a frequency + * lower than the default platform limit will fail. + * + * This test will fail if: + * 1) The system under test does not define the 'PAPI_tot_ins' event. + * 2) The 'dcpc-min-overflow' variable in dcpc.conf has been modified. + */ + +#pragma D option quiet + +BEGIN +{ + exit(0); +} + +cpc:::PAPI_tot_ins-all-100 +{ +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.D_PDESC_ZERO.malformedoverflow.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.D_PDESC_ZERO.malformedoverflow.d new file mode 100644 index 000000000000..f9b780942fab --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.D_PDESC_ZERO.malformedoverflow.d @@ -0,0 +1,40 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * Tests that specifying an overflow value containing extraneous characters + * (only digits are allowed) will fail. + */ + +BEGIN +{ + exit(0); +} + +cpc:::PAPI_tot_ins-all-10000bonehead +{ + @[probename] = count(); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.D_PDESC_ZERO.nonexistentevent.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.D_PDESC_ZERO.nonexistentevent.d new file mode 100644 index 000000000000..73f9575fbe6b --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.D_PDESC_ZERO.nonexistentevent.d @@ -0,0 +1,40 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * Tests that attempting to enable a probe containing a non existent event + * will fail. + */ + +BEGIN +{ + exit(0); +} + +cpc:::PAPI_cpc_bad-all-10000 +{ + @[probename] = count(); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cpcvscpustatpart1.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cpcvscpustatpart1.ksh new file mode 100644 index 000000000000..767d493a76b7 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cpcvscpustatpart1.ksh @@ -0,0 +1,78 @@ +#!/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + + +# +# This tests that cpustat(1) should fail to start if the cpc provider +# is already calling the shots. +# +# This script will fail if: +# 1) The system under test does not define the 'PAPI_tot_ins' +# generic event. + +script() +{ + $dtrace -o $dtraceout -s /dev/stdin <<EOF + #pragma D option bufsize=128k + + cpc:::PAPI_tot_ins-all-10000 + { + @[probename] = count(); + } +EOF +} + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +dtraceout=/tmp/dtrace.out.$$ +script 2>/dev/null & +timeout=15 + +# +# Sleep while the above script fires into life. To guard against dtrace dying +# and us sleeping forever we allow 15 secs for this to happen. This should be +# enough for even the slowest systems. +# +while [ ! -f $dtraceout ]; do + sleep 1 + timeout=$(($timeout-1)) + if [ $timeout -eq 0 ]; then + echo "dtrace failed to start. Exiting." + exit 1 + fi +done + +cpustat -c PAPI_tot_ins 1 5 +status=$? + +rm $dtraceout + +exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cpcvscpustatpart2.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cpcvscpustatpart2.ksh new file mode 100644 index 000000000000..584469c3fe9c --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cpcvscpustatpart2.ksh @@ -0,0 +1,70 @@ +#!/bin/ksh -p +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + + +# +# This tests that enablings from the cpc provider will fail if cpustat(1) is +# already master of the universe. +# +# This script will fail if: +# 1) The system under test does not define the 'PAPI_tot_ins' +# generic event. + +script() +{ + $dtrace -s /dev/stdin <<EOF + #pragma D option bufsize=128k + + BEGIN + { + exit(0); + } + + cpc:::PAPI_tot_ins-all-10000 + { + @[probename] = count(); + } +EOF +} + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +dtraceout=/tmp/dtrace.out.$$ + +cpustat -c PAPI_tot_ins 1 20 & +pid=$! +sleep 5 +script 2>/dev/null + +status=$? + +kill $pid +exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cputrackfailtostart.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cputrackfailtostart.ksh new file mode 100644 index 000000000000..f62b83d5714b --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cputrackfailtostart.ksh @@ -0,0 +1,77 @@ +#!/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. + +# +# This script ensures that cputrack(1M) will fail to start when the cpc +# provider has active enablings. +# +# The script will fail if: +# 1) The system under test does not define the 'PAPI_tot_ins' event. +# + +script() +{ + $dtrace -o $dtraceout -s /dev/stdin <<EOF + #pragma D option bufsize=128k + + cpc:::PAPI_tot_ins-all-10000 + { + @[probename] = count(); + } +EOF +} + + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +dtraceout=/tmp/dtrace.out.$$ +script 2>/dev/null & +timeout=15 + +# +# Sleep while the above script fires into life. To guard against dtrace dying +# and us sleeping forever we allow 15 secs for this to happen. This should be +# enough for even the slowest systems. +# +while [ ! -f $dtraceout ]; do + sleep 1 + timeout=$(($timeout-1)) + if [ $timeout -eq 0 ]; then + echo "dtrace failed to start. Exiting." + exit 1 + fi +done + +cputrack -c PAPI_tot_ins sleep 10 +status=$? + +rm $dtraceout + +exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cputrackterminates.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cputrackterminates.ksh new file mode 100644 index 000000000000..58d1e798f10e --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cputrackterminates.ksh @@ -0,0 +1,70 @@ +#!/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. + +# +# This script ensures that cputrack(1) will terminate when the cpc provider +# kicks into life. +# +# The script will fail if: +# 1) The system under test does not define the 'PAPI_tot_ins' event. +# + +script() +{ + $dtrace -s /dev/stdin <<EOF + #pragma D option bufsize=128k + + cpc:::PAPI_tot_ins-all-10000 + { + @[probename] = count(); + } + + tick-1s + /n++ > 10/ + { + exit(0); + } +EOF +} + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 + +cputrack -c PAPI_tot_ins sleep 20 & +cputrack_pid=$! +sleep 5 +script 2>/dev/null & + +wait $cputrack_pid +status=$? + +rm $dtraceout + +exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.toomanyenablings.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.toomanyenablings.d new file mode 100644 index 000000000000..a50bd71ae6ae --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.toomanyenablings.d @@ -0,0 +1,55 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * Test to check that attempting to enable too many probes will fail. + * + * This test will fail if: + * 1) We ever execute on a platform which is capable of programming 10 + * 'PAPI_tot_ins' events simultaneously (which no current platforms are + * capable of doing). + * 2) The system under test does not define the 'PAPI_tot_ins' event. + */ + +#pragma D option quiet + +BEGIN +{ + exit(0); +} + +cpc:::PAPI_tot_ins-all-10000, +cpc:::PAPI_tot_ins-all-10001, +cpc:::PAPI_tot_ins-all-10002, +cpc:::PAPI_tot_ins-all-10003, +cpc:::PAPI_tot_ins-all-10004, +cpc:::PAPI_tot_ins-all-10005, +cpc:::PAPI_tot_ins-all-10006, +cpc:::PAPI_tot_ins-all-10007, +cpc:::PAPI_tot_ins-all-10008, +cpc:::PAPI_tot_ins-all-10009 +{ +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/tst.allcpus.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/tst.allcpus.ksh new file mode 100644 index 000000000000..7f026c9ebca7 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/tst.allcpus.ksh @@ -0,0 +1,107 @@ +#!/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# This script verifies that we can fire a probe on each CPU that is in +# an online state. +# +# The script will fail if: +# 1) The system under test does not define the 'PAPI_tot_ins' event. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +numproc=`psrinfo | tail -1 | cut -f1` +cpu=0 +dtraceout=/var/tmp/dtrace.out.$$ +scriptout=/var/tmp/script.out.$$ + +spin() +{ + while [ 1 ]; do + : + done +} + +script() +{ + $dtrace -o $dtraceout -s /dev/stdin <<EOF + #pragma D option bufsize=128k + #pragma D option quiet + + cpc:::PAPI_tot_ins-user-10000 + /cpus[cpu] != 1/ + { + cpus[cpu] = 1; + @a[cpu] = count(); + } + + tick-1s + /n++ > 10/ + { + printa(@a); + exit(0); + } +EOF +} + +echo "" > $scriptout +while [ $cpu -le $numproc ] +do + if [ "`psrinfo -s $cpu 2> /dev/null`" -eq 1 ]; then + printf "%9d %16d\n" $cpu 1 >> $scriptout + spin & + allpids[$cpu]=$! + pbind -b $cpu $! + fi + cpu=$(($cpu+1)) +done +echo "" >> $scriptout + +script + +diff $dtraceout $scriptout >/dev/null 2>&1 +status=$? + +# kill off the spinner processes +cpu=0 +while [ $cpu -le $numproc ] +do + if [ "`psrinfo -s $cpu 2> /dev/null`" -eq 1 ]; then + kill ${allpids[$cpu]} + fi + cpu=$(($cpu+1)) +done + +rm $dtraceout +rm $scriptout + +exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/tst.genericevent.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/tst.genericevent.d new file mode 100644 index 000000000000..7ebf844e9cbe --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/tst.genericevent.d @@ -0,0 +1,48 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * Test that we can successfully enable a probe using a generic event. + * Currently, all platforms implement 'PAPI_tot_ins' so we'll use that. + * Note that this test will fail if the system under test does not + * implement that event. + * + * This test will fail if: + * 1) The system under test does not define the 'PAPI_tot_ins' event. + */ + +#pragma D option quiet +#pragma D option bufsize=128k + +cpc:::PAPI_tot_ins-all-10000 +{ + @[probename] = count(); +} + +tick-1s +/n++ > 10/ +{ + exit(0); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/tst.platformevent.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/tst.platformevent.ksh new file mode 100644 index 000000000000..96d1ab8c6a71 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/tst.platformevent.ksh @@ -0,0 +1,81 @@ +#!/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# This script ensures that we can enable a probe which specifies a platform +# specific event. +# + +if [ $# != 1 ]; then + print -u2 "expected one argument: <dtrace-path>" + exit 2 +fi + +dtrace=$1 + +get_event() +{ + perl /dev/stdin /dev/stdout << EOF + open CPUSTAT, '/usr/sbin/cpustat -h |' + or die "Couldn't run cpustat: \$!\n"; + while (<CPUSTAT>) { + if (/(\s+)event\[*[0-9]-*[0-9]*\]*:/ && !/PAPI/) { + @a = split(/ /, \$_); + \$event = \$a[\$#a-1]; + } + } + + close CPUSTAT; + print "\$event\n"; +EOF +} + +script() +{ + $dtrace -s /dev/stdin << EOD + #pragma D option quiet + #pragma D option bufsize=128k + + cpc:::$1-all-10000 + { + @[probename] = count(); + } + + tick-1s + /n++ > 5/ + { + exit(0); + } +EOD +} + +event=$(get_event) +script $event + +status=$? + +exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.AddSearchPath.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.AddSearchPath.d.ksh index 2f49f733e3ef..b36f1e4c181d 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.AddSearchPath.d.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.AddSearchPath.d.ksh @@ -78,5 +78,5 @@ if [ "$status" -ne 0 ]; then exit $status fi -/usr/bin/rm -f $tempfile +/bin/rm -f $tempfile exit 0 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithModule.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithModule.d.ksh index 923be51c6992..8ab32fdb40ee 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithModule.d.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.DestructWithModule.d.ksh @@ -44,7 +44,7 @@ fi dtrace=$1 -$dtrace -qwm unix'{chill(15); printf("Done chilling"); exit(0);}' +$dtrace -qwm kernel'{chill(15); printf("Done chilling"); exit(0);}' status=$? if [ "$status" -ne 0 ]; then diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ELFGenerationOut.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ELFGenerationOut.d.ksh index b68fc1387497..a4f4670c02ce 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ELFGenerationOut.d.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ELFGenerationOut.d.ksh @@ -69,5 +69,5 @@ if [ ! -a "d.out" ]; then exit 1 fi -/usr/bin/rm -f "d.out" +/bin/rm -f "d.out" exit 0 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ELFGenerationWithO.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ELFGenerationWithO.d.ksh index ec38b50285fa..503dd50e0891 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ELFGenerationWithO.d.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.ELFGenerationWithO.d.ksh @@ -70,5 +70,5 @@ if [ ! -a "outputFile" ]; then exit 1 fi -/usr/bin/rm -f "outputFile" +/bin/rm -f "outputFile" exit 0 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.PreprocessorStatement.d.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.PreprocessorStatement.d.ksh index 182466f4f8b1..e4d093e4fc22 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.PreprocessorStatement.d.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/dtraceUtil/tst.PreprocessorStatement.d.ksh @@ -43,7 +43,6 @@ script() { $dtrace -CH -s /dev/stdin <<EOF -#include <stdio.h> BEGIN { diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoofew.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoofew.d index e878713abb27..cf4dd5e0e550 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoofew.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoofew.d @@ -34,7 +34,7 @@ * */ -lockstat:genunix:mutex_enter:adaptive-acquire +lockstat:kernel:mtx_lock:adaptive-acquire { mutex_owned(); exit(1); diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoomany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoomany.d index d3b9ed486eb0..6cc4be03fa30 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoomany.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.motoomany.d @@ -34,7 +34,7 @@ * */ -lockstat:genunix:mutex_enter:adaptive-acquire +lockstat:kernel:mtx_lock:adaptive-acquire { mutex_owned((kmutex_t *)arg0, 99); exit(1); diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoofew.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoofew.d index 98bc5c9313dd..61d967a5b470 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoofew.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoofew.d @@ -36,7 +36,7 @@ */ -lockstat:genunix:mutex_enter:adaptive-acquire +lockstat:kernel:mtx_lock:adaptive-acquire { mutex_type_adaptive(); exit(1); diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoomany.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoomany.d index e4f259a7e78c..f2c3178e31c6 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoomany.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/err.D_PROTO_LEN.mtatoomany.d @@ -35,7 +35,7 @@ */ -lockstat:genunix:mutex_enter:adaptive-acquire +lockstat:kernel:mtx_lock:adaptive-acquire { mutex_type_adaptive((kmutex_t *)arg0, 99); exit(1); diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.index.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.index.d index 547730a14ea1..1ec96978ab18 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.index.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.index.d @@ -80,7 +80,7 @@ BEGIN i++; end = j = k = 0; - printf("#!/usr/perl5/bin/perl\n\nBEGIN {\n"); + printf("#!/usr/bin/perl\n\nBEGIN {\n"); } tick-1ms diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv4remote.pl b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv4remote.pl new file mode 100755 index 000000000000..128263eaec22 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv4remote.pl @@ -0,0 +1,104 @@ +#!/usr/bin/perl -w +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#pragma ident "%Z%%M% %I% %E% SMI" + +# +# get.ipv4remote.pl [tcpport] +# +# Find an IPv4 reachable remote host using both ifconfig(1M) and ping(1M). +# If a tcpport is specified, return a host that is also listening on this +# TCP port. Print the local address and the remote address, or an +# error message if no suitable remote host was found. Exit status is 0 if +# a host was found. +# + +use strict; +use IO::Socket; + +my $MAXHOSTS = 32; # max hosts to port scan +my $TIMEOUT = 3; # connection timeout +my $tcpport = @ARGV == 1 ? $ARGV[0] : 0; + +# +# Determine local IP address +# +my $local = ""; +my $remote = ""; +my %Broadcast; +my $up; +open IFCONFIG, '/sbin/ifconfig -a |' or die "Couldn't run ifconfig: $!\n"; +while (<IFCONFIG>) { + next if /^lo/; + + # "UP" is always printed first (see print_flags() in ifconfig.c): + $up = 1 if /^[a-z].*<UP,/; + $up = 0 if /^[a-z].*<,/; + + # assume output is "inet X ... broadcast Z": + if (/inet (\S+) .* broadcast (\S+)/) { + my ($addr, $bcast) = ($1, $2); + $Broadcast{$addr} = $bcast; + $local = $addr if $up and $local eq ""; + $up = 0; + } +} +close IFCONFIG; +die "Could not determine local IP address" if $local eq ""; + +# +# Find the first remote host that responds to an icmp echo, +# which isn't a local address. +# +open PING, "/sbin/ping -ns $Broadcast{$local} 56 $MAXHOSTS |" or + die "Couldn't run ping: $!\n"; +while (<PING>) { + if (/bytes from (.*): / and not defined $Broadcast{$1}) { + my $addr = $1; + + if ($tcpport != 0) { + # + # Test TCP + # + my $socket = IO::Socket::INET->new( + Proto => "tcp", + PeerAddr => $addr, + PeerPort => $tcpport, + Timeout => $TIMEOUT, + ); + next unless $socket; + close $socket; + } + + $remote = $addr; + last; + } +} +close PING; +die "Can't find a remote host for testing: No suitable response from " . + "$Broadcast{$local}\n" if $remote eq ""; + +print "$local $remote\n"; diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv6remote.pl b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv6remote.pl new file mode 100755 index 000000000000..837ca3c799d2 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv6remote.pl @@ -0,0 +1,88 @@ +#!/usr/bin/perl -w +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#pragma ident "%Z%%M% %I% %E% SMI" + +# +# get.ipv6remote.pl +# +# Find an IPv6 reachable remote host using both ifconfig(1M) and ping(1M). +# Print the local address and the remote address, or print nothing if either +# no IPv6 interfaces or remote hosts were found. (Remote IPv6 testing is +# considered optional, and so not finding another IPv6 host is not an error +# state we need to log.) Exit status is 0 if a host was found. +# + +use strict; +use IO::Socket; + +my $MAXHOSTS = 32; # max hosts to scan +my $TIMEOUT = 3; # connection timeout +my $MULTICAST = "FF02::1"; # IPv6 multicast address + +# +# Determine local IP address +# +my $local = ""; +my $remote = ""; +my %Local; +my $up; +open IFCONFIG, '/sbin/ifconfig -a inet6 |' + or die "Couldn't run ifconfig: $!\n"; +while (<IFCONFIG>) { + next if /^lo/; + + # "UP" is always printed first (see print_flags() in ifconfig.c): + $up = 1 if /^[a-z].*<UP,/; + $up = 0 if /^[a-z].*<,/; + + # assume output is "inet6 ...": + if (m:inet6 (\S+)/:) { + my $addr = $1; + $Local{$addr} = 1; + $local = $addr if $up and $local eq ""; + $up = 0; + } +} +close IFCONFIG; +exit 1 if $local eq ""; + +# +# Find the first remote host that responds to an icmp echo, +# which isn't a local address. +# +open PING, "/sbin/ping -ns -A inet6 $MULTICAST 56 $MAXHOSTS |" or + die "Couldn't run ping: $!\n"; +while (<PING>) { + if (/bytes from (.*): / and not defined $Local{$1}) { + $remote = $1; + last; + } +} +close PING; +exit 2 if $remote eq ""; + +print "$local $remote\n"; diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localicmp.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localicmp.ksh new file mode 100755 index 000000000000..0f2b64a2d902 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localicmp.ksh @@ -0,0 +1,70 @@ +#!/usr/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#pragma ident "%Z%%M% %I% %E% SMI" + +# +# Test ip:::{send,receive} of IPv4 ICMP to a local address. +# +# This may fail due to: +# +# 1. A change to the ip stack breaking expected probe behavior, +# which is the reason we are testing. +# 2. The lo0 interface missing or not up. +# 3. Unrelated ICMP on lo0 traced by accident. +# + +if (( $# != 1 )); then + print -u2 "expected one argument: <dtrace-path>" + exit 2 +fi + +dtrace=$1 +local=127.0.0.1 + +$dtrace -c "/sbin/ping $local 3" -qs /dev/stdin <<EOF | sort -n +ip:::send +/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" && + args[4]->ipv4_protocol == IPPROTO_ICMP/ +{ + printf("1 ip:::send ("); + printf("args[2]: %d %d, ", args[2]->ip_ver, args[2]->ip_plength); + printf("args[4]: %d %d %d %d %d)\n", + args[4]->ipv4_ver, args[4]->ipv4_length, args[4]->ipv4_flags, + args[4]->ipv4_offset, args[4]->ipv4_ttl); +} + +ip:::receive +/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" && + args[4]->ipv4_protocol == IPPROTO_ICMP/ +{ + printf("2 ip:::receive ("); + printf("args[2]: %d %d, ", args[2]->ip_ver, args[2]->ip_plength); + printf("args[4]: %d %d %d %d %d)\n", + args[4]->ipv4_ver, args[4]->ipv4_length, args[4]->ipv4_flags, + args[4]->ipv4_offset, args[4]->ipv4_ttl); +} +EOF diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localicmp.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localicmp.ksh.out new file mode 100644 index 000000000000..41d6e0c8ad41 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localicmp.ksh.out @@ -0,0 +1,6 @@ + +1 ip:::send (args[2]: 4 64, args[4]: 4 84 0 0 255) +1 ip:::send (args[2]: 4 64, args[4]: 4 84 0 0 255) +2 ip:::receive (args[2]: 4 64, args[4]: 4 84 0 0 255) +2 ip:::receive (args[2]: 4 64, args[4]: 4 84 0 0 255) +127.0.0.1 is alive diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh new file mode 100755 index 000000000000..c18dc7625d8e --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh @@ -0,0 +1,125 @@ +#!/usr/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. +# + +# +# Test {ip,tcp}:::{send,receive} of IPv4 TCP to local host. +# +# This may fail due to: +# +# 1. A change to the ip stack breaking expected probe behavior, +# which is the reason we are testing. +# 2. The lo0 interface missing or not up. +# 3. The local ssh service is not online. +# 4. An unlikely race causes the unlocked global send/receive +# variables to be corrupted. +# +# This test performs a TCP connection and checks that at least the +# following packet counts were traced: +# +# 3 x ip:::send (2 during the TCP handshake, then a FIN) +# 3 x tcp:::send (2 during the TCP handshake, then a FIN) +# 2 x ip:::receive (1 during the TCP handshake, then the FIN ACK) +# 2 x tcp:::receive (1 during the TCP handshake, then the FIN ACK) + +# The actual count tested is 5 each way, since we are tracing both +# source and destination events. +# +# For this test to work, we are assuming that the TCP handshake and +# TCP close will enter the IP code path and not use tcp fusion. +# + +if (( $# != 1 )); then + print -u2 "expected one argument: <dtrace-path>" + exit 2 +fi + +dtrace=$1 +local=127.0.0.1 +tcpport=22 +DIR=/var/tmp/dtest.$$ + +mkdir $DIR +cd $DIR + +cat > test.pl <<-EOPERL + use IO::Socket; + my \$s = IO::Socket::INET->new( + Proto => "tcp", + PeerAddr => "$local", + PeerPort => $tcpport, + Timeout => 3); + die "Could not connect to host $local port $tcpport" unless \$s; + close \$s; +EOPERL + +$dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin <<EODTRACE +BEGIN +{ + ipsend = tcpsend = ipreceive = tcpreceive = 0; +} + +ip:::send +/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" && + args[4]->ipv4_protocol == IPPROTO_TCP/ +{ + ipsend++; +} + +tcp:::send +/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local"/ +{ + tcpsend++; +} + +ip:::receive +/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" && + args[4]->ipv4_protocol == IPPROTO_TCP/ +{ + ipreceive++; +} + +tcp:::receive +/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local"/ +{ + tcpreceive++; +} + +END +{ + printf("Minimum TCP events seen\n\n"); + printf("ip:::send - %s\n", ipsend >= 5 ? "yes" : "no"); + printf("ip:::receive - %s\n", ipreceive >= 5 ? "yes" : "no"); + printf("tcp:::send - %s\n", tcpsend >= 5 ? "yes" : "no"); + printf("tcp:::receive - %s\n", tcpreceive >= 5 ? "yes" : "no"); +} +EODTRACE + +status=$? + +cd / +/bin/rm -rf $DIR + +exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh.out new file mode 100644 index 000000000000..2a85b98b6b7d --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh.out @@ -0,0 +1,7 @@ +Minimum TCP events seen + +ip:::send - yes +ip:::receive - yes +tcp:::send - yes +tcp:::receive - yes + diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh new file mode 100755 index 000000000000..6d08e24a9fbd --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh @@ -0,0 +1,93 @@ +#!/usr/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. +# + +# +# Test ip:::{send,receive} of IPv4 UDP to a local address. +# +# This may fail due to: +# +# 1. A change to the ip stack breaking expected probe behavior, +# which is the reason we are testing. +# 2. No physical network interface is plumbed and up. +# 3. No other hosts on this subnet are reachable and listening on rpcbind. +# 4. An unlikely race causes the unlocked global send/receive +# variables to be corrupted. +# +# This test sends a UDP message using ping and checks that at least the +# following counts were traced: +# +# 1 x ip:::send (UDP sent to ping's base UDP port) +# 1 x udp:::send (UDP sent to ping's base UDP port) +# 1 x ip:::receive (UDP received) +# +# No udp:::receive event is expected as the response ping -U elicits is +# an ICMP PORT_UNREACHABLE response rather than a UDP packet, and locally +# the echo request UDP packet only reaches IP, so the udp:::receive probe +# is not triggered by it. +# + +if (( $# != 1 )); then + print -u2 "expected one argument: <dtrace-path>" + exit 2 +fi + +dtrace=$1 +local=127.0.0.1 + +$dtrace -c "/sbin/ping -U $local" -qs /dev/stdin <<EOF | grep -v 'is alive' +BEGIN +{ + ipsend = udpsend = ipreceive = 0; +} + +ip:::send +/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" && + args[4]->ipv4_protocol == IPPROTO_UDP/ +{ + ipsend++; +} + +udp:::send +/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local"/ +{ + udpsend++; +} + +ip:::receive +/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" && + args[4]->ipv4_protocol == IPPROTO_UDP/ +{ + ipreceive++; +} + +END +{ + printf("Minimum UDP events seen\n\n"); + printf("ip:::send - %s\n", ipsend >= 1 ? "yes" : "no"); + printf("ip:::receive - %s\n", ipreceive >= 1 ? "yes" : "no"); + printf("udp:::send - %s\n", udpsend >= 1 ? "yes" : "no"); +} +EOF diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh.out new file mode 100644 index 000000000000..bca55327ef57 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh.out @@ -0,0 +1,6 @@ +Minimum UDP events seen + +ip:::send - yes +ip:::receive - yes +udp:::send - yes + diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteicmp.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteicmp.ksh new file mode 100755 index 000000000000..87553ea71107 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteicmp.ksh @@ -0,0 +1,81 @@ +#!/usr/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#pragma ident "%Z%%M% %I% %E% SMI" + +# +# Test ip:::{send,receive} of IPv4 ICMP to a remote host. +# +# This may fail due to: +# +# 1. A change to the ip stack breaking expected probe behavior, +# which is the reason we are testing. +# 2. No physical network interface is plumbed and up. +# 3. No other hosts on this subnet are reachable. +# 4. An unrelated ICMP between these hosts was traced by accident. +# + +if (( $# != 1 )); then + print -u2 "expected one argument: <dtrace-path>" + exit 2 +fi + +dtrace=$1 +getaddr=./get.ipv4remote.pl + +if [[ ! -x $getaddr ]]; then + print -u2 "could not find or execute sub program: $getaddr" + exit 3 +fi +$getaddr | read source dest +if (( $? != 0 )); then + exit 4 +fi + +$dtrace -c "/sbin/ping $dest 3" -qs /dev/stdin <<EOF | \ + grep -v 'is alive' | sort -n +ip:::send +/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" && + args[4]->ipv4_protocol == IPPROTO_ICMP/ +{ + printf("1 ip:::send ("); + printf("args[2]: %d %d, ", args[2]->ip_ver, args[2]->ip_plength); + printf("args[4]: %d %d %d %d %d)\n", + args[4]->ipv4_ver, args[4]->ipv4_length, args[4]->ipv4_flags, + args[4]->ipv4_offset, args[4]->ipv4_ttl); +} + +ip:::receive +/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" && + args[4]->ipv4_protocol == IPPROTO_ICMP/ +{ + printf("2 ip:::receive ("); + printf("args[2]: %d %d, ", args[2]->ip_ver, args[2]->ip_plength); + printf("args[4]: %d %d %d %d %d)\n", + args[4]->ipv4_ver, args[4]->ipv4_length, args[4]->ipv4_flags, + args[4]->ipv4_offset, args[4]->ipv4_ttl); +} +EOF diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteicmp.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteicmp.ksh.out new file mode 100644 index 000000000000..b5915f8db477 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteicmp.ksh.out @@ -0,0 +1,3 @@ + +1 ip:::send (args[2]: 4 64, args[4]: 4 84 0 0 255) +2 ip:::receive (args[2]: 4 64, args[4]: 4 84 4 0 255) diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh new file mode 100755 index 000000000000..e513ace0be64 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh @@ -0,0 +1,128 @@ +#!/usr/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. +# + +# +# Test {tcp,ip}:::{send,receive} of IPv4 TCP to a remote host. +# +# This may fail due to: +# +# 1. A change to the ip stack breaking expected probe behavior, +# which is the reason we are testing. +# 2. No physical network interface is plumbed and up. +# 3. No other hosts on this subnet are reachable and listening on ssh. +# 4. An unlikely race causes the unlocked global send/receive +# variables to be corrupted. +# +# This test performs a TCP connection and checks that at least the +# following packet counts were traced: +# +# 3 x ip:::send (2 during the TCP handshake, then a FIN) +# 3 x tcp:::send (2 during the TCP handshake, then a FIN) +# 2 x ip:::receive (1 during the TCP handshake, then the FIN ACK) +# 2 x tcp:::receive (1 during the TCP handshake, then the FIN ACK) +# + +if (( $# != 1 )); then + print -u2 "expected one argument: <dtrace-path>" + exit 2 +fi + +dtrace=$1 +getaddr=./get.ipv4remote.pl +tcpport=22 +DIR=/var/tmp/dtest.$$ + +if [[ ! -x $getaddr ]]; then + print -u2 "could not find or execute sub program: $getaddr" + exit 3 +fi +$getaddr $tcpport | read source dest +if (( $? != 0 )); then + exit 4 +fi + +mkdir $DIR +cd $DIR + +cat > test.pl <<-EOPERL + use IO::Socket; + my \$s = IO::Socket::INET->new( + Proto => "tcp", + PeerAddr => "$dest", + PeerPort => $tcpport, + Timeout => 3); + die "Could not connect to host $dest port $tcpport" unless \$s; + close \$s; +EOPERL + +$dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin <<EODTRACE +BEGIN +{ + ipsend = tcpsend = ipreceive = tcpreceive = 0; +} + +ip:::send +/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" && + args[4]->ipv4_protocol == IPPROTO_TCP/ +{ + ipsend++; +} + +tcp:::send +/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest"/ +{ + tcpsend++; +} + +ip:::receive +/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" && + args[4]->ipv4_protocol == IPPROTO_TCP/ +{ + ipreceive++; +} + +tcp:::receive +/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source"/ +{ + tcpreceive++; +} + +END +{ + printf("Minimum TCP events seen\n\n"); + printf("ip:::send - %s\n", ipsend >= 3 ? "yes" : "no"); + printf("ip:::receive - %s\n", ipreceive >= 2 ? "yes" : "no"); + printf("tcp:::send - %s\n", tcpsend >= 3 ? "yes" : "no"); + printf("tcp:::receive - %s\n", tcpreceive >= 2 ? "yes" : "no"); +} +EODTRACE + +status=$? + +cd / +/bin/rm -rf $DIR + +exit $? diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh.out new file mode 100644 index 000000000000..2a85b98b6b7d --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh.out @@ -0,0 +1,7 @@ +Minimum TCP events seen + +ip:::send - yes +ip:::receive - yes +tcp:::send - yes +tcp:::receive - yes + diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh new file mode 100755 index 000000000000..cc7a32c556b1 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh @@ -0,0 +1,88 @@ +#!/usr/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. +# + +# +# Test {udp,ip}:::{send,receive} of IPv4 UDP to a remote host. +# +# This may fail due to: +# +# 1. A change to the ip stack breaking expected probe behavior, +# which is the reason we are testing. +# 2. No physical network interface is plumbed and up. +# 3. No other hosts on this subnet are reachable and listening on rpcbind. +# 4. An unlikely race causes the unlocked global send/receive +# variables to be corrupted. +# +# This test sends a UDP message using ping and checks that at least the +# following counts were traced: +# +# 1 x ip:::send (UDP sent to ping's base UDP port) +# 1 x udp:::send (UDP sent to ping's base UDP port) +# + +if (( $# != 1 )); then + print -u2 "expected one argument: <dtrace-path>" + exit 2 +fi + +dtrace=$1 +getaddr=./get.ipv4remote.pl + +if [[ ! -x $getaddr ]]; then + print -u2 "could not find or execute sub program: $getaddr" + exit 3 +fi +$getaddr | read source dest +if (( $? != 0 )); then + exit 4 +fi + +$dtrace -c "/sbin/ping -U $dest" -qs /dev/stdin <<EOF | grep -v 'is alive' +BEGIN +{ + ipsend = udpsend = 0; +} + +ip:::send +/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" && + args[4]->ipv4_protocol == IPPROTO_UDP/ +{ + ipsend++; +} + +udp:::send +/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest"/ +{ + udpsend++; +} + +END +{ + printf("Minimum UDP events seen\n\n"); + printf("ip:::send - %s\n", ipsend >= 1 ? "yes" : "no"); + printf("udp:::send - %s\n", udpsend >= 1 ? "yes" : "no"); +} +EOF diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh.out new file mode 100644 index 000000000000..bdbbe1fd6562 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh.out @@ -0,0 +1,5 @@ +Minimum UDP events seen + +ip:::send - yes +udp:::send - yes + diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6localicmp.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6localicmp.ksh new file mode 100755 index 000000000000..f63d1ed766bc --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6localicmp.ksh @@ -0,0 +1,82 @@ +#!/usr/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#pragma ident "%Z%%M% %I% %E% SMI" + +# +# Test ip:::{send,receive} of IPv6 ICMP to a local address. This creates a +# temporary lo0/inet6 interface if one doesn't already exist. +# +# This may fail due to: +# +# 1. A change to the ip stack breaking expected probe behavior, +# which is the reason we are testing. +# 2. Unrelated ICMPv6 on lo0 traced by accident. +# + +if (( $# != 1 )); then + print -u2 "expected one argument: <dtrace-path>" + exit 2 +fi + +dtrace=$1 +local=::1 + +if ! ifconfig lo0 inet6 > /dev/null 2>&1; then + if ! ifconfig lo0 inet6 plumb up; then + print -u2 "could not plumb lo0 inet6 for testing" + exit 3 + fi + removeinet6=1 +else + removeinet6=0 +fi + +$dtrace -c "/sbin/ping -A inet6 $local 3" -qs /dev/stdin <<EOF | sort -n +ip:::send +/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" && + args[5]->ipv6_nexthdr == IPPROTO_ICMPV6/ +{ + printf("1 ip:::send ("); + printf("args[2]: %d %d, ", args[2]->ip_ver, args[2]->ip_plength); + printf("args[5]: %d %d %d)\n", + args[5]->ipv6_ver, args[5]->ipv6_tclass, args[5]->ipv6_plen); +} + +ip:::receive +/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" && + args[5]->ipv6_nexthdr == IPPROTO_ICMPV6/ +{ + printf("2 ip:::receive ("); + printf("args[2]: %d %d, ", args[2]->ip_ver, args[2]->ip_plength); + printf("args[5]: %d %d %d)\n", + args[5]->ipv6_ver, args[5]->ipv6_tclass, args[5]->ipv6_plen); +} +EOF + +if (( removeinet6 )); then + ifconfig lo0 inet6 unplumb +fi diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6localicmp.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6localicmp.ksh.out new file mode 100644 index 000000000000..529d251fa06e --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6localicmp.ksh.out @@ -0,0 +1,6 @@ + +::1 is alive +1 ip:::send (args[2]: 6 64, args[5]: 6 0 64) +1 ip:::send (args[2]: 6 64, args[5]: 6 0 64) +2 ip:::receive (args[2]: 6 64, args[5]: 6 0 64) +2 ip:::receive (args[2]: 6 64, args[5]: 6 0 64) diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6remoteicmp.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6remoteicmp.ksh new file mode 100755 index 000000000000..c859e6bfe44f --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6remoteicmp.ksh @@ -0,0 +1,88 @@ +#!/usr/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#pragma ident "%Z%%M% %I% %E% SMI" + +# +# Test ip:::{send,receive} of IPv6 ICMP to a remote host. This test is +# skipped if there are no physical interfaces configured with IPv6, or no +# other IPv6 hosts are reachable. +# +# This may fail due to: +# +# 1. A change to the ip stack breaking expected probe behavior, +# which is the reason we are testing. +# 2. An unrelated ICMPv6 between these hosts was traced by accident. +# + +if (( $# != 1 )); then + print -u2 "expected one argument: <dtrace-path>" + exit 2 +fi + +dtrace=$1 +getaddr=./get.ipv6remote.pl + +if [[ ! -x $getaddr ]]; then + print -u2 "could not find or execute sub program: $getaddr" + exit 3 +fi +$getaddr | read source dest +if (( $? != 0 )); then + print -nu2 "Could not find a local IPv6 interface and a remote IPv6 " + print -u2 "host. Aborting test.\n" + print -nu2 "For this test to continue, a \"ping -ns -A inet6 FF02::1\" " + print -u2 "must respond with a\nremote IPv6 host." + exit 3 +fi + +# +# Shake loose any ICMPv6 Neighbor advertisement messages before tracing. +# +/sbin/ping $dest 3 > /dev/null 2>&1 + +$dtrace -c "/sbin/ping $dest 3" -qs /dev/stdin <<EOF | \ + grep -v 'is alive' | sort -n +ip:::send +/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" && + args[5]->ipv6_nexthdr == IPPROTO_ICMPV6/ +{ + printf("1 ip:::send ("); + printf("args[2]: %d %d, ", args[2]->ip_ver, args[2]->ip_plength); + printf("args[5]: %d %d %d)\n", + args[5]->ipv6_ver, args[5]->ipv6_tclass, args[5]->ipv6_plen); +} + +ip:::receive +/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" && + args[5]->ipv6_nexthdr == IPPROTO_ICMPV6/ +{ + printf("2 ip:::receive ("); + printf("args[2]: %d %d, ", args[2]->ip_ver, args[2]->ip_plength); + printf("args[5]: %d %d %d)\n", + args[5]->ipv6_ver, args[5]->ipv6_tclass, args[5]->ipv6_plen); +} +EOF diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6remoteicmp.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6remoteicmp.ksh.out new file mode 100644 index 000000000000..1ddcd07b367e --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6remoteicmp.ksh.out @@ -0,0 +1,3 @@ + +1 ip:::send (args[2]: 6 64, args[5]: 6 0 64) +2 ip:::receive (args[2]: 6 64, args[5]: 6 0 64) diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh new file mode 100644 index 000000000000..5e0c7474065f --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh @@ -0,0 +1,182 @@ +#!/usr/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +# + +# +# Test tcp:::state-change and tcp:::{send,receive} by connecting to +# the local ssh service and sending a test message. This should result +# in a "Protocol mismatch" response and a close of the connection. +# A number of state transition events along with tcp fusion send and +# receive events for the message should result. +# +# This may fail due to: +# +# 1. A change to the ip stack breaking expected probe behavior, +# which is the reason we are testing. +# 2. The lo0 interface missing or not up. +# 3. The local ssh service is not online. +# 4. An unlikely race causes the unlocked global send/receive +# variables to be corrupted. +# +# This test performs a TCP connection to the ssh service (port 22) and +# checks that at least the following packet counts were traced: +# +# 3 x ip:::send (2 during the TCP handshake, then a FIN) +# 4 x tcp:::send (2 during the TCP handshake, 1 message then a FIN) +# 2 x ip:::receive (1 during the TCP handshake, then the FIN ACK) +# 3 x tcp:::receive (1 during the TCP handshake, 1 message then the FIN ACK) +# +# The actual ip count tested is 5 each way, since we are tracing both +# source and destination events. The actual tcp count tested is 7 +# each way, since the TCP fusion send/receive events will not reach IP. +# +# For this test to work, we are assuming that the TCP handshake and +# TCP close will enter the IP code path and not use tcp fusion. +# + +if (( $# != 1 )); then + print -u2 "expected one argument: <dtrace-path>" + exit 2 +fi + +dtrace=$1 +local=127.0.0.1 +tcpport=22 +DIR=/var/tmp/dtest.$$ + +mkdir $DIR +cd $DIR + +cat > test.pl <<-EOPERL + use IO::Socket; + my \$s = IO::Socket::INET->new( + Proto => "tcp", + PeerAddr => "$local", + PeerPort => $tcpport, + Timeout => 3); + die "Could not connect to host $local port $tcpport" unless \$s; + print \$s "testing state machine transitions"; + close \$s; +EOPERL + +$dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin <<EODTRACE +BEGIN +{ + ipsend = tcpsend = ipreceive = tcpreceive = 0; + connreq = connest = connaccept = 0; +} + +ip:::send +/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" && + args[4]->ipv4_protocol == IPPROTO_TCP/ +{ + ipsend++; +} + +tcp:::send +/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" && + (args[4]->tcp_sport == $tcpport || args[4]->tcp_dport == $tcpport)/ +{ + tcpsend++; +} + +ip:::receive +/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" && + args[4]->ipv4_protocol == IPPROTO_TCP/ +{ + ipreceive++; +} + +tcp:::receive +/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" && + (args[4]->tcp_sport == $tcpport || args[4]->tcp_dport == $tcpport)/ +{ + tcpreceive++; +} + +tcp:::state-change +{ + state_event[args[3]->tcps_state]++; +} + +tcp:::connect-request +/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" && + args[4]->tcp_dport == $tcpport/ +{ + connreq++; +} + +tcp:::connect-established +/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" && + args[4]->tcp_sport == $tcpport/ +{ + connest++; +} + +tcp:::accept-established +/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" && + args[4]->tcp_dport == $tcpport/ +{ + connaccept++; +} + +END +{ + printf("Minimum TCP events seen\n\n"); + printf("ip:::send - %s\n", ipsend >= 5 ? "yes" : "no"); + printf("ip:::receive - %s\n", ipreceive >= 5 ? "yes" : "no"); + printf("tcp:::send - %s\n", tcpsend >= 7 ? "yes" : "no"); + printf("tcp:::receive - %s\n", tcpreceive >= 7 ? "yes" : "no"); + printf("tcp:::state-change to syn-sent - %s\n", + state_event[TCP_STATE_SYN_SENT] >=1 ? "yes" : "no"); + printf("tcp:::state-change to syn-received - %s\n", + state_event[TCP_STATE_SYN_RECEIVED] >=1 ? "yes" : "no"); + printf("tcp:::state-change to established - %s\n", + state_event[TCP_STATE_ESTABLISHED] >= 2 ? "yes" : "no"); + printf("tcp:::state-change to fin-wait-1 - %s\n", + state_event[TCP_STATE_FIN_WAIT_1] >= 1 ? "yes" : "no"); + printf("tcp:::state-change to close-wait - %s\n", + state_event[TCP_STATE_CLOSE_WAIT] >= 1 ? "yes" : "no"); + printf("tcp:::state-change to fin-wait-2 - %s\n", + state_event[TCP_STATE_FIN_WAIT_2] >= 1 ? "yes" : "no"); + printf("tcp:::state-change to last-ack - %s\n", + state_event[TCP_STATE_LAST_ACK] >= 1 ? "yes" : "no"); + printf("tcp:::state-change to time-wait - %s\n", + state_event[TCP_STATE_TIME_WAIT] >= 1 ? "yes" : "no"); + printf("tcp:::connect-request - %s\n", + connreq >=1 ? "yes" : "no"); + printf("tcp:::connect-established - %s\n", + connest >=1 ? "yes" : "no"); + printf("tcp:::accept-established - %s\n", + connaccept >=1 ? "yes" : "no"); +} +EODTRACE + +status=$? + +cd / +/bin/rm -rf $DIR + +exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh.out new file mode 100644 index 000000000000..ea1c27e5020c --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh.out @@ -0,0 +1,18 @@ +Minimum TCP events seen + +ip:::send - yes +ip:::receive - yes +tcp:::send - yes +tcp:::receive - yes +tcp:::state-change to syn-sent - yes +tcp:::state-change to syn-received - yes +tcp:::state-change to established - yes +tcp:::state-change to fin-wait-1 - yes +tcp:::state-change to close-wait - yes +tcp:::state-change to fin-wait-2 - yes +tcp:::state-change to last-ack - yes +tcp:::state-change to time-wait - yes +tcp:::connect-request - yes +tcp:::connect-established - yes +tcp:::accept-established - yes + diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh new file mode 100644 index 000000000000..4bf4362b61d2 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh @@ -0,0 +1,172 @@ +#!/usr/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +# + +# +# Test tcp:::state-change and tcp:::{send,receive} by connecting to +# the remote ssh service and sending a test message. This should result +# in a "Protocol mismatch" response and a close of the connection. +# A number of state transition events along with tcp send and receive +# events for the message should result. +# +# This may fail due to: +# +# 1. A change to the ip stack breaking expected probe behavior, +# which is the reason we are testing. +# 2. The lo0 interface missing or not up. +# 3. The remote ssh service is not online. +# 4. An unlikely race causes the unlocked global send/receive +# variables to be corrupted. +# +# This test performs a TCP connection to the ssh service (port 22) and +# checks that at least the following packet counts were traced: +# +# 4 x ip:::send (2 during the TCP handshake, the message, then a FIN) +# 4 x tcp:::send (2 during the TCP handshake, the messages, then a FIN) +# 3 x ip:::receive (1 during the TCP handshake, the response, then the FIN ACK) +# 3 x tcp:::receive (1 during the TCP handshake, the response, then the FIN ACK) +# +# For this test to work, we are assuming that the TCP handshake and +# TCP close will enter the IP code path and not use tcp fusion. +# + +if (( $# != 1 )); then + print -u2 "expected one argument: <dtrace-path>" + exit 2 +fi + +dtrace=$1 +getaddr=./get.ipv4remote.pl +tcpport=22 +DIR=/var/tmp/dtest.$$ + +if [[ ! -x $getaddr ]]; then + print -u2 "could not find or execute sub program: $getaddr" + exit 3 +fi +$getaddr $tcpport | read source dest +if (( $? != 0 )); then + exit 4 +fi + +mkdir $DIR +cd $DIR + +cat > test.pl <<-EOPERL + use IO::Socket; + my \$s = IO::Socket::INET->new( + Proto => "tcp", + PeerAddr => "$dest", + PeerPort => $tcpport, + Timeout => 3); + die "Could not connect to host $dest port $tcpport" unless \$s; + print \$s "testing state machine transitions"; + close \$s; +EOPERL + +$dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin <<EODTRACE +BEGIN +{ + ipsend = tcpsend = ipreceive = tcpreceive = 0; + connreq = connest = 0; +} + +ip:::send +/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" && + args[4]->ipv4_protocol == IPPROTO_TCP/ +{ + ipsend++; +} + +tcp:::send +/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" && + args[4]->tcp_dport == $tcpport/ +{ + tcpsend++; +} + +ip:::receive +/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" && + args[4]->ipv4_protocol == IPPROTO_TCP/ +{ + ipreceive++; +} + +tcp:::receive +/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" && + args[4]->tcp_sport == $tcpport/ +{ + tcpreceive++; +} + +tcp:::state-change +{ + state_event[args[3]->tcps_state]++; +} + +tcp:::connect-request +/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" && + args[4]->tcp_dport == $tcpport/ +{ + connreq++; +} + +tcp:::connect-established +/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" && + args[4]->tcp_sport == $tcpport/ +{ + connest++; +} + +END +{ + printf("Minimum TCP events seen\n\n"); + printf("ip:::send - %s\n", ipsend >= 4 ? "yes" : "no"); + printf("ip:::receive - %s\n", ipreceive >= 3 ? "yes" : "no"); + printf("tcp:::send - %s\n", tcpsend >= 4 ? "yes" : "no"); + printf("tcp:::receive - %s\n", tcpreceive >= 3 ? "yes" : "no"); + printf("tcp:::state-change to syn-sent - %s\n", + state_event[TCP_STATE_SYN_SENT] >=1 ? "yes" : "no"); + printf("tcp:::state-change to established - %s\n", + state_event[TCP_STATE_ESTABLISHED] >= 1 ? "yes" : "no"); + printf("tcp:::state-change to fin-wait-1 - %s\n", + state_event[TCP_STATE_FIN_WAIT_1] >= 1 ? "yes" : "no"); + printf("tcp:::state-change to fin-wait-2 - %s\n", + state_event[TCP_STATE_FIN_WAIT_2] >= 1 ? "yes" : "no"); + printf("tcp:::state-change to time-wait - %s\n", + state_event[TCP_STATE_TIME_WAIT] >= 1 ? "yes" : "no"); + printf("tcp:::connect-request - %s\n", + connreq >=1 ? "yes" : "no"); + printf("tcp:::connect-established - %s\n", + connest >=1 ? "yes" : "no"); +} +EODTRACE + +status=$? + +cd / +/bin/rm -rf $DIR + +exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh.out new file mode 100644 index 000000000000..27388fba65dc --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh.out @@ -0,0 +1,15 @@ +Minimum TCP events seen + +ip:::send - yes +ip:::receive - yes +tcp:::send - yes +tcp:::receive - yes +tcp:::state-change to syn-sent - yes +tcp:::state-change to established - yes +tcp:::state-change to fin-wait-1 - yes +tcp:::state-change to close-wait - yes +tcp:::state-change to fin-wait-2 - yes +tcp:::state-change to time-wait - yes +tcp:::connect-request - yes +tcp:::connect-established - yes + diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestFunctionLookup.java b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestFunctionLookup.java index 3488903c19ea..2bc43ea6f1ce 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestFunctionLookup.java +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestFunctionLookup.java @@ -20,10 +20,8 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. - * - * ident "%Z%%M% %I% %E% SMI" */ import org.opensolaris.os.dtrace.*; @@ -70,7 +68,7 @@ public class TestFunctionLookup { long addr = (Long)address; f = consumer.lookupKernelFunction(addr); } - if (f.equals("genunix`setrun")) { + if (f.equals("genunix`cv_wakeup")) { System.out.println(f); done = true; } diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestGetAggregate.java b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestGetAggregate.java new file mode 100644 index 000000000000..e02df8582417 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestGetAggregate.java @@ -0,0 +1,252 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +import org.opensolaris.os.dtrace.*; +import java.util.*; + +/** + * Assert getAggregate() can explicitly specify the anonymous aggregation. + */ +public class TestGetAggregate { + static final String programString = + "profile:::tick-50ms" + + "{" + + " @ = count();" + + " @a = count();" + + "}"; + + static final String ANONYMOUS_AGGREGATION = ""; + static final int TICK = 50; + static final int EXPECTED_TICKS = 3; + static final int INTERVALS = 4; + + static void + testIncluded(Consumer consumer, String ... aggregationNames) + throws DTraceException, InterruptedException + { + Aggregate aggregate; + Set <String> included = new HashSet <String> (); + int n = 1; + + for (String name : aggregationNames) { + included.add(name); + } + + // Wait up to a full second to obtain aggregate data. Without a + // time limit, we'll loop forever if no aggregation was + // successfully included. + do { + Thread.sleep(TICK); + aggregate = consumer.getAggregate(included, null); + } while (aggregate.asMap().isEmpty() && n++ < (1000 / TICK)); + + for (String name : included) { + if (aggregate.getAggregation(name) == null) { + throw new IllegalStateException("@" + name + + " was explicitly included but did not appear " + + "in the aggregate"); + } + } + for (Aggregation a : aggregate.getAggregations()) { + if (!included.contains(a.getName())) { + throw new IllegalStateException("@" + a.getName() + + " was not explicitly included but appeared " + + "in the aggregate anyway"); + } + } + + if (!consumer.isRunning()) { + throw new IllegalStateException("consumer exited"); + } + } + + static void + testCleared(Consumer consumer, String ... aggregationNames) + throws DTraceException, InterruptedException + { + Aggregate aggregate; + AggregationRecord rec; + long value; + Long firstValue; + int n = 1; + Map <String, Long> firstValues = new HashMap <String, Long> (); + Set <String> cleared = new HashSet <String> (); + + for (String name : aggregationNames) { + cleared.add(name); + } + + do { + Thread.sleep(TICK); + aggregate = consumer.getAggregate(null, cleared); + } while (aggregate.asMap().isEmpty() && n++ < (1000 / TICK)); + n = 1; + + do { + Thread.sleep(TICK * EXPECTED_TICKS); + aggregate = consumer.getAggregate(null, cleared); + + for (Aggregation a : aggregate.getAggregations()) { + if (!firstValues.containsKey(a.getName())) { + rec = a.getRecord(Tuple.EMPTY); + value = rec.getValue().getValue().longValue(); + firstValues.put(a.getName(), value); + } + } + } while (consumer.isRunning() && n++ < INTERVALS); + + for (Aggregation a : aggregate.getAggregations()) { + rec = a.getRecord(Tuple.EMPTY); + value = rec.getValue().getValue().longValue(); + firstValue = firstValues.get(a.getName()); + + if (cleared.contains(a.getName())) { + // last value should be about the same as first value + if (value > (firstValue * 2)) { + throw new IllegalStateException( + "@" + a.getName() + " should have " + + "been cleared but instead grew from " + + firstValue + " to " + value); + } + } else { + // last value should be about (INTERVALS * firstValue) + if (value < (firstValue * 2)) { + throw new IllegalStateException( + "@" + a.getName() + " should have " + + "accumulated a running total but " + + "instead went from " + + firstValue + " to " + value); + } + } + } + + if (!consumer.isRunning()) { + throw new IllegalStateException("consumer exited"); + } + } + + static Integer includedStatus; + static Integer clearedStatus; + + static void + startIncludedTest() + { + final Consumer consumer = new LocalConsumer(); + consumer.addConsumerListener(new ConsumerAdapter() { + public void consumerStarted(ConsumerEvent e) { + new Thread(new Runnable() { + public void run() { + try { + testIncluded(consumer, ANONYMOUS_AGGREGATION); + includedStatus = 0; + } catch (Exception e) { + includedStatus = 1; + e.printStackTrace(); + } finally { + consumer.abort(); + } + } + }).start(); + } + }); + + try { + consumer.open(); + consumer.setOption(Option.aggrate, Option.millis(TICK)); + consumer.compile(programString); + consumer.enable(); + consumer.go(); + } catch (Exception e) { + includedStatus = 1; + e.printStackTrace(); + } + } + + static void + startClearedTest() + { + final Consumer consumer = new LocalConsumer(); + consumer.addConsumerListener(new ConsumerAdapter() { + public void consumerStarted(ConsumerEvent e) { + new Thread(new Runnable() { + public void run() { + try { + testCleared(consumer, ANONYMOUS_AGGREGATION); + clearedStatus = 0; + } catch (Exception e) { + clearedStatus = 1; + e.printStackTrace(); + } finally { + consumer.abort(); + } + } + }).start(); + } + }); + + try { + consumer.open(); + consumer.setOption(Option.aggrate, Option.millis(TICK)); + consumer.compile(programString); + consumer.enable(); + consumer.go(); + } catch (Exception e) { + clearedStatus = 1; + e.printStackTrace(); + } + } + + public static void + main(String[] args) + { + startIncludedTest(); + + do { + try { + Thread.sleep(TICK); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } while (includedStatus == null); + + startClearedTest(); + + do { + try { + Thread.sleep(TICK); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } while (clearedStatus == null); + + if (includedStatus != 0 || clearedStatus != 0) { + System.out.println("Failure"); + System.exit(1); + } + + System.out.println("Success"); + } +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.FunctionLookup.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.FunctionLookup.ksh.out index 400064d8eaba..d42e9b59b6e1 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.FunctionLookup.ksh.out +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.FunctionLookup.ksh.out @@ -1,3 +1,3 @@ -genunix`setrun +genunix`cv_wakeup 3 tst.FunctionLookup.exe`f1 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.GetAggregate.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.GetAggregate.ksh new file mode 100644 index 000000000000..2fdd5a9eac44 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.GetAggregate.ksh @@ -0,0 +1,36 @@ +#!/bin/ksh -p +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +############################################################################ +# ASSERTION: +# getAggregate() can explicitly specify the anonymous aggregation +# +# SECTION: Java API +# +############################################################################ + +java -cp test.jar TestGetAggregate diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.include.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.include.ksh index ec328021b3a3..30a2ce4175b3 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.include.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.include.ksh @@ -31,7 +31,7 @@ if [ $# != 1 ]; then fi dtrace=$1 -CC=/usr/sfw/bin/gcc +CC=/usr/bin/gcc CFLAGS= doit() diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.macroglob.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.macroglob.ksh new file mode 100644 index 000000000000..a5114f4917e5 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.macroglob.ksh @@ -0,0 +1,41 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 + +$dtrace -ln 'syscall::*$1:entry' read | awk '{print $(NF-1),$NF}' | sort +$dtrace -ln 'syscall::$1*:entry' read | awk '{print $(NF-1),$NF}' | sort +$dtrace -ln 'syscall::re$1*:entry' ad | awk '{print $(NF-1),$NF}' | sort +$dtrace -ln 'syscall::$1l*:entry' read | awk '{print $(NF-1),$NF}' | sort +$dtrace -ln 'syscall::p$1[0-9][0-9]:entry' read | awk '{print $(NF-1),$NF}' | \ + sort + +exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.macroglob.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.macroglob.ksh.out new file mode 100644 index 000000000000..8a9ac6d96c5a --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.macroglob.ksh.out @@ -0,0 +1,15 @@ +FUNCTION NAME +pread entry +read entry +FUNCTION NAME +read entry +readlink entry +readv entry +FUNCTION NAME +read entry +readlink entry +readv entry +FUNCTION NAME +readlink entry +FUNCTION NAME +pread64 entry diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.schrock.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.schrock.ksh index 494f6f8e6605..197bd8dd5f32 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.schrock.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.schrock.ksh @@ -39,7 +39,7 @@ dtrace=$1 # LD_NOEXEC_64 variable prevents nm from re-execing itself. # LD_NOEXEC_64=tomeeisrad $dtrace -F -s /dev/stdin -c \ - '/usr/ccs/bin/nm /bin/ls' stat <<EOF + '/usr/bin/nm /bin/ls' stat <<EOF pid\$target::\$1:entry { diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PDESC_ZERO.badlib.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PDESC_ZERO.badlib.exe new file mode 100644 index 000000000000..595db1de33da --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PDESC_ZERO.badlib.exe @@ -0,0 +1,29 @@ +#!/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" + +sleep 1000000 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_CREATEFAIL.many.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_CREATEFAIL.many.exe new file mode 100644 index 000000000000..25b4ff143dad --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_CREATEFAIL.many.exe @@ -0,0 +1,29 @@ +#!/bin/bash +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" + +sleep 1000000 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_FUNC.badfunc.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_FUNC.badfunc.exe new file mode 100644 index 000000000000..595db1de33da --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_FUNC.badfunc.exe @@ -0,0 +1,29 @@ +#!/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" + +sleep 1000000 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_LIB.libdash.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_LIB.libdash.exe new file mode 100644 index 000000000000..595db1de33da --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_LIB.libdash.exe @@ -0,0 +1,29 @@ +#!/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" + +sleep 1000000 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.alldash.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.alldash.exe new file mode 100644 index 000000000000..595db1de33da --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.alldash.exe @@ -0,0 +1,29 @@ +#!/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" + +sleep 1000000 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.badname.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.badname.exe new file mode 100644 index 000000000000..595db1de33da --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.badname.exe @@ -0,0 +1,29 @@ +#!/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" + +sleep 1000000 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.globdash.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.globdash.exe new file mode 100644 index 000000000000..595db1de33da --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.globdash.exe @@ -0,0 +1,29 @@ +#!/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" + +sleep 1000000 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_OFF.toobig.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_OFF.toobig.exe new file mode 100644 index 000000000000..595db1de33da --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_OFF.toobig.exe @@ -0,0 +1,29 @@ +#!/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" + +sleep 1000000 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.coverage.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.coverage.exe new file mode 100644 index 000000000000..07e84583e74c --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.coverage.exe @@ -0,0 +1,29 @@ +#!/usr/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" + +while true; do env > /dev/null; done diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.emptystack.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.emptystack.exe new file mode 100644 index 000000000000..a8bc8cb351e9 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.emptystack.exe @@ -0,0 +1,29 @@ +#!/usr/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" + +exec find / > /dev/null 2>&1 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.fork.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.fork.c index d5e90dbc90cf..8c2772396a1b 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.fork.c +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.fork.c @@ -56,7 +56,7 @@ main(int argc, char **argv) while (waiting(&a) == 0) continue; - (void) forkall(); + (void) fork(); (void) go(); return (0); diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.gcc.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.gcc.c index b97fa9d1afdb..69df4723dc9f 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.gcc.c +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.gcc.c @@ -28,13 +28,14 @@ #include <spawn.h> #include <signal.h> +#include <stdio.h> void go(void) { pid_t pid; - (void) posix_spawn(&pid, "/usr/bin/ls", NULL, NULL, NULL, NULL); + (void) posix_spawn(&pid, "/bin/ls", NULL, NULL, NULL, NULL); (void) waitpid(pid, NULL, 0); } diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.killonerror.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.killonerror.ksh new file mode 100644 index 000000000000..587878c3fc2a --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.killonerror.ksh @@ -0,0 +1,41 @@ +#!/bin/ksh -p +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 + +# +# Make sure we kill a process if the dtrace(1M) command fails. +# + +rc=`$dtrace -c date -n jarod 2>/dev/null | /usr/bin/wc -l` + +exit $rc diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.probemod.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.probemod.ksh index 2565b503d154..326fd1ab9f83 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.probemod.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.probemod.ksh @@ -21,11 +21,9 @@ # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" -# if [ $# != 1 ]; then echo expected one argument: '<'dtrace-path'>' @@ -40,7 +38,7 @@ dtrace=$1 # (and therefore 'libc' and 'libc.so') as it's definitely there. # -for lib in libc libc.so libc.so.1; do +for lib in libc libc.so libc.so.1 'lib[c]*'; do sleep 60 & pid=$! dtrace -n "pid$pid:$lib::entry" -n 'tick-2s{exit(0);}' diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex1.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex1.ksh index 892ff3e24df1..7b0824eedd7c 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex1.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex1.ksh @@ -88,6 +88,6 @@ script status=$? cd /tmp -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex2.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex2.ksh index 8d83bddd2319..8951cb381f8c 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex2.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex2.ksh @@ -126,6 +126,6 @@ script status=$? cd /tmp -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex3.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex3.ksh index c9ac6b1dd6a8..49e362b33b20 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex3.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex3.ksh @@ -97,6 +97,6 @@ script status=$? cd /tmp -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex4.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex4.ksh index 278ec128131c..865b9bbee5fd 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex4.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.provregex4.ksh @@ -149,6 +149,6 @@ script status=$? cd /tmp -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/plockstat/tst.available.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/plockstat/tst.available.exe new file mode 100644 index 000000000000..221e8b1d7434 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/plockstat/tst.available.exe @@ -0,0 +1,29 @@ +#!/usr/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" + +sleep 100000000 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/plockstat/tst.libmap.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/plockstat/tst.libmap.exe new file mode 100644 index 000000000000..221e8b1d7434 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/plockstat/tst.libmap.exe @@ -0,0 +1,29 @@ +#!/usr/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" + +sleep 100000000 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.basics.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.basics.d index e7de2d389abf..f5353870808d 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.basics.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.basics.d @@ -20,15 +20,13 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * ASSERTION: - * Test the basic formatting of all the supported kinds of aggregations. + * Test the basic formatting of all the supported kinds of aggregations. * * SECTION: Output Formatting/printa() * @@ -45,6 +43,7 @@ BEGIN @e = min(1); @f = sum(1); @g = quantize(1); + @h = stddev(1); printa("@a = %@u\n", @a); printa("@b = %@u\n", @b); @@ -53,6 +52,7 @@ BEGIN printa("@e = %@u\n", @e); printa("@f = %@u\n", @f); printa("@g = %@d\n", @g); + printa("@h = %@d\n", @h); exit(0); } diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.basics.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.basics.d.out index a3d46a982a95..ddad2134d1af 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.basics.d.out +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.basics.d.out @@ -15,4 +15,5 @@ 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1 2 | 0 +@h = 0 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.largeusersym.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.largeusersym.ksh new file mode 100644 index 000000000000..7d8bd39af74b --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.largeusersym.ksh @@ -0,0 +1,83 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +DIR=/var/tmp/dtest.$$ + +mkdir $DIR +cd $DIR + +cat > test.c <<EOF +void +thequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydog(void) +{ + while (1) + ; +} + +int +main(int argc, char *argv[]) +{ + thequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydogthequickbrownfoxjumpsoverthelazydog(); +} +EOF + +cc -o test test.c +if [ $? -ne 0 ]; then + print -u2 "failed to compile test.c" + exit 1 +fi + +script() +{ + $dtrace -c ./test -qs /dev/stdin <<EOF + profile:::profile-1001hz + /pid == \$target/ + { + @[arg1] = count(); + } + + tick-1s + /n++ > 10/ + { + printa("%A %@d\n", @); + exit(0); + } +EOF +} + +script +status=$? + +cd / +/bin/rm -rf $DIR + +exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.walltimestamp.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.walltimestamp.ksh index bb0d5a0f6a6a..69bf46b5383c 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.walltimestamp.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.walltimestamp.ksh @@ -33,7 +33,7 @@ fi dtrace=$1 # The output files assumes the timezone is US/Pacific -TZ=US/Pacific +export TZ=America/Los_Angeles $dtrace -s /dev/stdin <<EOF #pragma D option quiet diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printT.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printT.ksh index 516253809567..6d3695711c95 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printT.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printT.ksh @@ -33,7 +33,7 @@ fi dtrace=$1 # The output files assumes the timezone is US/Pacific -TZ=US/Pacific +export TZ=America/Los_Angeles $dtrace -s /dev/stdin <<EOF #pragma D option quiet diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printY.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printY.ksh index 2dc3a4c334bb..b8ea2fff2aff 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printY.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.printY.ksh @@ -33,7 +33,7 @@ fi dtrace=$1 # The output files assumes the timezone is US/Pacific -TZ=US/Pacific +export TZ=America/Los_Angeles $dtrace -s /dev/stdin <<EOF #pragma D option quiet diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.str.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.str.d index 483473344a54..a74041393ebf 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.str.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.str.d @@ -20,12 +20,10 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * ASSERTION: * Test printf() with a simple string argument. @@ -38,6 +36,6 @@ BEGIN { - printf("rootfs = %s", `rootfs.bo_fstype); + printf("sysname = %s", `utsname.sysname); exit(0); } diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.str.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.str.d.out index b425586425ea..ba3198176ecc 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.str.d.out +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.str.d.out @@ -1 +1 @@ -rootfs = ufs +sysname = SunOS diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.sym.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.sym.d index 55f89f992586..32bc682e829b 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.sym.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.sym.d @@ -38,6 +38,6 @@ BEGIN { - printf("symbol = %a", &`kmem_flags); + printf("symbol = %a", &`kmem_alloc); exit(0); } diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.sym.d.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.sym.d.out index 14f1e825bf85..5ed9d8ec53b6 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.sym.d.out +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printf/tst.sym.d.out @@ -1 +1 @@ -symbol = genunix`kmem_flags +symbol = kernel`kmem_alloc diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.exec.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.exec.ksh index 92330fb01c3e..a4ad57212cef 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.exec.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.exec.ksh @@ -41,7 +41,7 @@ script() self->exec = 1; } - proc:::exec_success + proc:::exec-success /self->exec/ { exit(0); diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.execfail.ENOENT.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.execfail.ENOENT.ksh index 5dbce13e0c5f..995eb056255d 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.execfail.ENOENT.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.execfail.ENOENT.ksh @@ -42,7 +42,7 @@ script() self->exec = 1; } - proc:::exec_failure + proc:::exec-failure /self->exec && args[0] == ENOENT/ { exit(0); diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.execfail.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.execfail.ksh index 3b2dbb39a737..7fb3faaedc10 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.execfail.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.execfail.ksh @@ -45,7 +45,7 @@ script() self->exec = 1; } - proc:::exec_failure + proc:::exec-failure /self->exec/ { exit(0); diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.sigwait.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.sigwait.d index fd6baffdc276..bb8281902e22 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.sigwait.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/proc/tst.sigwait.d @@ -28,13 +28,13 @@ #pragma D option destructive -proc:::signal_send +proc:::signal-send /args[1]->p_pid == $1 && args[2] == SIGUSR1/ { sent = 1; } -proc:::signal_clear +proc:::signal-clear /pid == $1 && args[0] == SIGUSR1 && sent/ { exit(0); diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.D_MACRO_UNUSED.overflow.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.D_MACRO_UNUSED.overflow.ksh index 0f4e1455223d..cc1e6dd9f745 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.D_MACRO_UNUSED.overflow.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.D_MACRO_UNUSED.overflow.ksh @@ -70,11 +70,11 @@ fi grep "D_MACRO_UNUSED" /var/tmp/err.$$.txt >/dev/null 2>&1 if [ $? -ne 0 ]; then print -u2 "Expected error D_MACRO_UNUSED not returned" - /usr/bin/rm -f /var/tmp/err.$$.txt + /bin/rm -f /var/tmp/err.$$.txt exit 1 fi -/usr/bin/rm -f $dfilename -/usr/bin/rm -f /var/tmp/err.$$.txt +/bin/rm -f $dfilename +/bin/rm -f /var/tmp/err.$$.txt exit 0 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.arguments.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.arguments.ksh index deb644a50137..6ec078abf29d 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.arguments.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.arguments.ksh @@ -42,7 +42,7 @@ fi dtrace=$1 -bname=`/bin/basename $0` +bname=`/usr/bin/basename $0` dfilename=/var/tmp/$bname.$$ @@ -85,6 +85,6 @@ if [[ ${outarray[0]} != 1 || ${outarray[1]} != 2 || ${outarray[2]} != 3 || \ exit 1 fi -/usr/bin/rm -f $dfilename +/bin/rm -f $dfilename exit 0 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.egid.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.egid.ksh index 9e1955f2980e..afee24f83b71 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.egid.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.egid.ksh @@ -43,7 +43,7 @@ if [ $# != 1 ]; then fi dtrace=$1 -bname=`/bin/basename $0` +bname=`/usr/bin/basename $0` dfilename=/var/tmp/$bname.$$.d ## Create .d file @@ -70,14 +70,14 @@ EOF #chmod 555 the .d file chmod 555 $dfilename >/dev/null 2>&1 -if [ &? -ne 0 ]; then +if [ $? -ne 0 ]; then print -u2 "chmod $dfilename failed" exit 1 fi #Get the groupid of the calling process using ps -groupid=`ps -o pid,gid | grep "$$ " | awk '{print $2}' 2>/dev/null` +groupid=`ps -o pid,pgid | grep "$$ " | awk '{print $2}' 2>/dev/null` if [ $? -ne 0 ]; then print -u2 "unable to get uid of the current process with pid = $$" exit 1 @@ -93,5 +93,5 @@ fi #Cleanup leftovers -/usr/bin/rm -f $dfilename +/bin/rm -f $dfilename exit 0 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.euid.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.euid.ksh index 7112b257817e..1b6b9b3e0d39 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.euid.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.euid.ksh @@ -82,5 +82,5 @@ if [ $? -ne 0 ]; then exit 1 fi -#/usr/bin/rm -f $dfilename +#/bin/rm -f $dfilename exit 0 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.gid.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.gid.ksh index 83955db14797..332b8e70d27d 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.gid.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.gid.ksh @@ -82,5 +82,5 @@ if [ $? -ne 0 ]; then exit 1 fi -#/usr/bin/rm -f $dfilename +#/bin/rm -f $dfilename exit 0 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.ppid.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.ppid.ksh index 4a74ee428193..bbd9a5364797 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.ppid.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.ppid.ksh @@ -82,5 +82,5 @@ if [ $? -ne 0 ]; then exit 1 fi -#/usr/bin/rm -f $dfilename +#/bin/rm -f $dfilename exit 0 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.projid.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.projid.ksh index da60ea1d61de..62bc817af5f6 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.projid.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.projid.ksh @@ -82,5 +82,5 @@ if [ $? -ne 0 ]; then exit 1 fi -#/usr/bin/rm -f $dfilename +#/bin/rm -f $dfilename exit 0 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.sid.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.sid.ksh index d1e122c1333f..477ebc0290a5 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.sid.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.sid.ksh @@ -82,5 +82,5 @@ if [ $? -ne 0 ]; then exit 1 fi -#/usr/bin/rm -f $dfilename +#/bin/rm -f $dfilename exit 0 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.stringmacro.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.stringmacro.ksh index 6903cb1cd994..724bd5fda7f0 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.stringmacro.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.stringmacro.ksh @@ -74,5 +74,5 @@ if [ "$output" != "this is test" ]; then exit 1 fi -/usr/bin/rm -f $dfilename +/bin/rm -f $dfilename exit 0 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.taskid.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.taskid.ksh index 54392d23d737..88b450d381ff 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.taskid.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.taskid.ksh @@ -82,5 +82,5 @@ if [ $? -ne 0 ]; then exit 1 fi -#/usr/bin/rm -f $dfilename +#/bin/rm -f $dfilename exit 0 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.uid.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.uid.ksh index 2630f2f945fb..fabf0eda7433 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.uid.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/scripting/tst.uid.ksh @@ -82,5 +82,5 @@ if [ $? -ne 0 ]; then exit 1 fi -#/usr/bin/rm -f $dfilename +#/bin/rm -f $dfilename exit 0 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.c new file mode 100644 index 000000000000..e2e9505fb598 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.c @@ -0,0 +1,51 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <unistd.h> +#ifndef __FreeBSD__ +#include <sys/uadmin.h> +#endif + +int +main(int argc, char **argv) +{ +#ifdef __FreeBSD__ + return (1); +#else + while (1) { + if (uadmin(A_SDTTEST, 0, 0) < 0) { + perror("uadmin"); + return (1); + } + + sleep(1); + } + + return (0); +#endif +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.d new file mode 100644 index 000000000000..0523de0951ed --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.d @@ -0,0 +1,67 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * ASSERTION: Verify that argN (1..7) variables are properly remapped. + */ + +BEGIN +{ + /* Timeout after 5 seconds */ + timeout = timestamp + 5000000000; + ignore = $1; +} + +ERROR +{ + printf("sdt:::test failed.\n"); + exit(1); +} + +sdt:::test +/arg0 != 1 || arg1 != 2 || arg2 != 3 || arg3 != 4 || arg4 != 5 || arg5 != 6 || + arg6 != 7/ +{ + printf("sdt arg mismatch\n\n"); + printf("args are : %d, %d, %d, %d, %d, %d, %d\n", arg0, arg1, arg2, + arg3, arg4, arg5, arg6); + printf("should be : 1, 2, 3, 4, 5, 6, 7\n"); + exit(1); +} + +sdt:::test +{ + exit(0); +} + +profile:::tick-1 +/timestamp > timeout/ +{ + trace("test timed out"); + exit(1); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithStddev.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithStddev.d new file mode 100644 index 000000000000..22953c2a55f4 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithStddev.d @@ -0,0 +1,65 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * ASSERTION: + * Aggregating actions may never be speculative. + * + * SECTION: Speculative Tracing/Using a Speculation + * + */ +#pragma D option quiet + +BEGIN +{ + i = 0; +} + +profile:::tick-1sec +/i < 1/ +{ + var = speculation(); + speculate(var); + printf("Speculation ID: %d", var); + @sdev["speculate"] = stddev(i); + i++; +} + +profile:::tick-1sec +/1 == i/ +{ + exit(0); +} + +ERROR +{ + exit(0); +} + +END +{ + exit(0); +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sysevent/tst.post_chan.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sysevent/tst.post_chan.c index 8394716af173..4a452a7ad2de 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sysevent/tst.post_chan.c +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sysevent/tst.post_chan.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <libsysevent.h> #include <stdio.h> @@ -42,7 +40,7 @@ main(int argc, char **argv) for (;;) { if (sysevent_evc_publish(ch, "class_dtest", "subclass_dtest", "vendor_dtest", "publisher_dtest", NULL, EVCH_SLEEP) != 0) { - sysevent_evc_unbind(ch); + (void) sysevent_evc_unbind(ch); (void) fprintf(stderr, "failed to publisth sysevent\n"); return (1); } diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/Makefile b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/Makefile new file mode 100644 index 000000000000..77fe870aa91f --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/Makefile @@ -0,0 +1,13 @@ +all: main + +main: main.o prov.o + $(CC) -o main main.o prov.o + +main.o: main.c prov.h + $(CC) -c main.c + +prov.h: prov.d + /usr/sbin/dtrace -h -s prov.d + +prov.o: prov.d main.o + /usr/sbin/dtrace -G -32 -s prov.d main.o diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/main.c b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/main.c new file mode 100644 index 000000000000..9dc0a0e63beb --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/main.c @@ -0,0 +1,11 @@ +#include <stdlib.h> +#include <sys/sdt.h> +#include "prov.h" + +int +main(int argc, char **argv, char **envp) +{ + envp[0] = (char*)0xff; + TESTER_ENTRY(); + return 0; +} diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/prov.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/prov.d new file mode 100644 index 000000000000..53e5ef3988d1 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/prov.d @@ -0,0 +1,3 @@ +provider tester { + probe entry(); +}; diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/prov.h b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/prov.h new file mode 100644 index 000000000000..e29654edb672 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/prov.h @@ -0,0 +1,46 @@ +/* + * Generated by dtrace(1M). + */ + +#ifndef _PROV_H +#define _PROV_H + +#include <unistd.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#if _DTRACE_VERSION + +#define TESTER_ENTRY() \ + __dtrace_tester___entry() +#ifndef __sparc +#define TESTER_ENTRY_ENABLED() \ + __dtraceenabled_tester___entry() +#else +#define TESTER_ENTRY_ENABLED() \ + __dtraceenabled_tester___entry(0) +#endif + + +extern void __dtrace_tester___entry(void); +#ifndef __sparc +extern int __dtraceenabled_tester___entry(void); +#else +extern int __dtraceenabled_tester___entry(long); +#endif + +#else + +#define TESTER_ENTRY() +#define TESTER_ENTRY_ENABLED() (0) + +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* _PROV_H */ diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.badguess.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.badguess.ksh index 291fe83fac25..91b6cf06f10d 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.badguess.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.badguess.ksh @@ -79,6 +79,6 @@ if [ $? -eq 0 ]; then fi cd / -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR exit 0 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.corruptenv.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.corruptenv.ksh new file mode 100644 index 000000000000..68dbb03456cc --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.corruptenv.ksh @@ -0,0 +1,107 @@ +#!/usr/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# This test verifies that a program that corrupts its own environment +# without inducing a crash does not crash solely due to drti.o's use of +# getenv(3C). +# + +PATH=/usr/bin:/usr/sbin:$PATH + +if (( $# != 1 )); then + print -u2 'expected one argument: <dtrace-path>' + exit 2 +fi + +# +# jdtrace does not implement the -h option that is required to generate +# C header files. +# +if [[ "$1" == */jdtrace ]]; then + exit 0 +fi + +dtrace="$1" +startdir="$PWD" +dir=$(mktemp -td drtiXXXXXX) +if (( $? != 0 )); then + print -u2 'Could not create safe temporary directory' + exit 2 +fi + +cd "$dir" + +cat > Makefile <<EOF +all: main + +main: main.o prov.o + \$(CC) -o main main.o prov.o + +main.o: main.c prov.h + \$(CC) -c main.c + +prov.h: prov.d + $dtrace -h -s prov.d + +prov.o: prov.d main.o + $dtrace -G -32 -s prov.d main.o +EOF + +cat > prov.d <<EOF +provider tester { + probe entry(); +}; +EOF + +cat > main.c <<EOF +#include <stdlib.h> +#include <sys/sdt.h> +#include "prov.h" + +int +main(int argc, char **argv, char **envp) +{ + envp[0] = (char*)0xff; + TESTER_ENTRY(); + return 0; +} +EOF + +make > /dev/null +status=$? +if (( $status != 0 )) ; then + print -u2 "failed to build" +else + ./main + status=$? +fi + +cd "$startdir" +rm -rf "$dir" + +exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose1.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose1.ksh index 0a6666628fd4..1c155febb5ae 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose1.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose1.ksh @@ -125,7 +125,7 @@ main(int argc, char **argv) } EOF -/usr/ccs/bin/make > /dev/null +/usr/bin/make > /dev/null if [ $? -ne 0 ]; then print -u2 "failed to build" exit 1 @@ -154,6 +154,6 @@ script 2>&1 status=$? cd / -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose2.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose2.ksh index c83d8bfa8618..107707ede32e 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose2.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose2.ksh @@ -136,7 +136,7 @@ main(int argc, char **argv) } EOF -/usr/ccs/bin/make > /dev/null +/usr/bin/make > /dev/null if [ $? -ne 0 ]; then print -u2 "failed to build" exit 1 @@ -155,6 +155,6 @@ script status=$? cd / -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose3.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose3.ksh index 72f24ce5e30d..a750b59e14e6 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose3.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.dlclose3.ksh @@ -131,7 +131,7 @@ main(int argc, char **argv) } EOF -/usr/ccs/bin/make > /dev/null +/usr/bin/make > /dev/null if [ $? -ne 0 ]; then print -u2 "failed to build" exit 1 @@ -165,6 +165,6 @@ script status=$? cd / -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.eliminate.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.eliminate.ksh index 687e435e3fcb..96b05d5cde2d 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.eliminate.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.eliminate.ksh @@ -101,6 +101,6 @@ if [ $? -eq 0 ]; then fi cd / -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR exit 0 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled.ksh index ba62be75a4ca..d0ac1864877e 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled.ksh @@ -91,6 +91,6 @@ script status=$? cd / -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled2.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled2.ksh new file mode 100644 index 000000000000..d40036d8c576 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled2.ksh @@ -0,0 +1,113 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" + +# +# This test is primarily intended to verify a fix for SPARC, but there's no +# harm in running it on other platforms. Here, we verify that is-enabled +# probes don't interfere with return values from previously invoked functions. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +DIR=/var/tmp/dtest.$$ + +mkdir $DIR +cd $DIR + +cat > prov.d <<EOF +provider test_prov { + probe go(); +}; +EOF + +$dtrace -h -s prov.d +if [ $? -ne 0 ]; then + print -u2 "failed to generate header file" + exit 1 +fi + +cat > test.c <<EOF +#include <stdio.h> +#include "prov.h" + +int +foo(void) +{ + return (24); +} + +int +main(int argc, char **argv) +{ + int a = foo(); + if (TEST_PROV_GO_ENABLED()) { + TEST_PROV_GO(); + } + (void) printf("%d %d %d\n", a, a, a); + + return (0); +} +EOF + +cc -c -xO2 test.c +if [ $? -ne 0 ]; then + print -u2 "failed to compile test.c" + exit 1 +fi +$dtrace -G -32 -s prov.d test.o +if [ $? -ne 0 ]; then + print -u2 "failed to create DOF" + exit 1 +fi +cc -o test test.o prov.o +if [ $? -ne 0 ]; then + print -u2 "failed to link final executable" + exit 1 +fi + +script() +{ + ./test + + $dtrace -c ./test -qs /dev/stdin <<EOF + test_prov\$target::: + { + } +EOF +} + +script +status=$? + +cd / +/bin/rm -rf $DIR + +exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled2.ksh.out b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled2.ksh.out new file mode 100644 index 000000000000..563d68fd312b --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled2.ksh.out @@ -0,0 +1,3 @@ +24 24 24 +24 24 24 + diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.entryreturn.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.entryreturn.ksh index 9d2646cdf1fb..51afe961a843 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.entryreturn.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.entryreturn.ksh @@ -113,6 +113,6 @@ script | cut -c5- status=$? cd / -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.fork.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.fork.ksh index 9c12e6dea29e..3ee9e9f228d5 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.fork.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.fork.ksh @@ -100,6 +100,6 @@ script status=$? cd / -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.guess32.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.guess32.ksh index 68a8d016073c..8affb3583f8d 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.guess32.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.guess32.ksh @@ -91,6 +91,6 @@ script status=$? cd / -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.guess64.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.guess64.ksh index 39de8e0d81b0..0c2801872e3f 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.guess64.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.guess64.ksh @@ -95,6 +95,6 @@ else fi cd / -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.header.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.header.ksh index 08a1912bae84..37ad97c3b0f1 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.header.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.header.ksh @@ -82,4 +82,4 @@ if [ $? -ne 0 ]; then fi cd / -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.include.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.include.ksh index 5683f47d4277..6f809fdc7c89 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.include.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.include.ksh @@ -56,6 +56,6 @@ fi status=$? cd / -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.linkpriv.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.linkpriv.ksh index ec07e057af88..a1ef9d89c30b 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.linkpriv.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.linkpriv.ksh @@ -79,4 +79,4 @@ if [ $? -ne 0 ]; then fi cd / -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.linkunpriv.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.linkunpriv.ksh index 01b2126c9442..ffc5107b1bfa 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.linkunpriv.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.linkunpriv.ksh @@ -81,4 +81,4 @@ if [ $? -ne 0 ]; then fi cd / -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.multiple.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.multiple.ksh index 0c8b072cb0d3..3f545a7bd48e 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.multiple.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.multiple.ksh @@ -94,6 +94,6 @@ script status=$? cd / -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.nodtrace.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.nodtrace.ksh index a911bcdfdfbb..f766f6d1d1a5 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.nodtrace.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.nodtrace.ksh @@ -85,6 +85,6 @@ fi status=$? cd / -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.onlyenabled.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.onlyenabled.ksh index 989d6d32aff9..9def3c002b9a 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.onlyenabled.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.onlyenabled.ksh @@ -79,4 +79,4 @@ if [ $? -ne 0 ]; then fi cd / -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.reeval.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.reeval.ksh index 7fad40156a09..4ea33f76d83c 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.reeval.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.reeval.ksh @@ -93,6 +93,6 @@ script status=$? cd / -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static.ksh index 1ebcdb95fdf2..0cddf0db810e 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static.ksh @@ -93,6 +93,6 @@ script status=$? cd / -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static2.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static2.ksh index 7cf9004c612c..8385b27cdfe4 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static2.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.static2.ksh @@ -103,6 +103,6 @@ script status=$? cd / -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.user.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.user.ksh index d5d9fdc4d3fd..89ceb4a94858 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.user.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.user.ksh @@ -91,6 +91,6 @@ script status=$? cd / -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.ucaller.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.ucaller.ksh index 8427ea0cb4e0..c09825ec21bc 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.ucaller.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/vars/tst.ucaller.ksh @@ -38,7 +38,7 @@ fi dtrace=$1 -$dtrace -qs /dev/stdin -c "/usr/bin/echo" <<EOF +$dtrace -qs /dev/stdin -c "/bin/echo" <<EOF pid\$target:ld.so.1:calloc:entry { self->calloc = 1; diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/funcs/tst.badcopyin.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/funcs/tst.badcopyin.d index d5b8c24aa5dc..f14c8afc8cad 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/funcs/tst.badcopyin.d +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i386/funcs/tst.badcopyin.d @@ -20,12 +20,10 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * ASSERTION: * On IA/32, there is a single 32-bit address space that is partitioned @@ -43,11 +41,12 @@ BEGIN { - lbolt = copyin((uintptr_t)&`lbolt, sizeof (int)); + dtrace_zero = copyin((uintptr_t)&`dtrace_zero, sizeof (int)); exit(1); } ERROR { - exit(arg4 == DTRACEFLT_BADADDR && arg5 == (uint64_t)&`lbolt ? 0 : 1); + exit(arg4 == DTRACEFLT_BADADDR && + arg5 == (uint64_t)&`dtrace_zero ? 0 : 1); } diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.basic.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.basic.ksh new file mode 100755 index 000000000000..3a5ce6f0d064 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.basic.ksh @@ -0,0 +1,77 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# ASSERTION: Make sure that we can map in and read the Xen trace buffers. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +# +# Do not fail the test in a domU +# +if [ ! -c /dev/xen/privcmd ]; then + exit 0 +fi + +dtrace=$1 + +script() +{ + $dtrace -qs /dev/stdin <<EOF + xdt:sched::on-cpu + /arg0 == 0/ + { + self->on++; + } + + xdt:sched::off-cpu + /arg0 == 0 && self->on/ + { + self->off++; + } + + xdt:sched::off-cpu + /self->on > 50 && self->off > 50/ + { + exit(0); + } + + profile:::tick-1sec + /n++ > 10/ + { + exit(1); + } +EOF +} + +script +status=$? + +exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.hvmenable.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.hvmenable.ksh new file mode 100755 index 000000000000..3719c2026545 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.hvmenable.ksh @@ -0,0 +1,64 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +# +# ASSERTION: HVM probes should enable successfully. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +# +# Do not fail the test in a domU +# +if [ ! -c /dev/xen/privcmd ]; then + exit 0 +fi + +dtrace=$1 + +script() +{ + $dtrace -qs /dev/stdin <<EOF + dtrace:::BEGIN + { + exit(0); + } + + xdt:hvm::vmentry, + xdt:hvm::vmexit + {} +EOF +} + +script +status=$? + +exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.memenable.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.memenable.ksh new file mode 100755 index 000000000000..25d39cbfbc86 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.memenable.ksh @@ -0,0 +1,65 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +# +# ASSERTION: Mem probes should enable successfully. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +# +# Do not fail the test in a domU +# +if [ ! -c /dev/xen/privcmd ]; then + exit 0 +fi + +dtrace=$1 + +script() +{ + $dtrace -qs /dev/stdin <<EOF + dtrace:::BEGIN + { + exit(0); + } + + xdt:mem::page-grant-map, + xdt:mem::page-grant-unmap, + xdt:mem::page-grant-transfer + {} +EOF +} + +script +status=$? + +exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.schedargs.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.schedargs.ksh new file mode 100755 index 000000000000..5b14fc989138 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.schedargs.ksh @@ -0,0 +1,121 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# ASSERTION: Sched probe arguments should be valid. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +# +# do not fail test in a domU +# +if [ ! -c /dev/xen/privcmd ]; then + exit 0 +fi + +dtrace=$1 +outf=/tmp/sched.args.$$ + +script() +{ + $dtrace -c '/usr/bin/sleep 10' -o $outf -qs /dev/stdin <<EOF + xdt:sched::off-cpu, + xdt:sched::on-cpu, + xdt:sched::block, + xdt:sched::sleep, + xdt:sched::wake, + xdt:sched::yield + { + /* print domid vcpu pcpu probename */ + printf("%d %d %d %s\n", arg0, arg1, \`xdt_curpcpu, probename); + } +EOF +} + +validate() +{ + /usr/bin/nawk ' + BEGIN { + while (("/usr/sbin/xm vcpu-list" | getline)) { + if ($1 != "Name") { + domid = $2 + vcpu = $3 + + vcpumap[domid, vcpu] = 1 + + split($7, affinity, ",") + for (i in affinity) { + if (split(affinity[i], p, "-") > 1) { + for (pcpu = p[1]; pcpu <= p[2];\ + pcpu++) { + cpumap[domid, vcpu, + pcpu] = 1 + } + } else { + cpumap[domid, vcpu, + affinity[i]] = 1 + } + } + } + } + } + + /^$/ { next } + + /wake/ { + if (vcpumap[$1, $2]) { + next + } else { + print "error: " $0 + exit 1 + } + } + + { + if (cpumap[$1, $2, "any"] || cpumap[$1, $2, $3]) { + next + } else { + print "error: " $0 + exit 1 + } + } + ' $outf +} + +script +status=$? + +if [ $status == 0 ]; then + validate + status=$? +fi + +rm $outf +exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.schedenable.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.schedenable.ksh new file mode 100755 index 000000000000..54c3352ea525 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.schedenable.ksh @@ -0,0 +1,74 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +# +# ASSERTION: Sched probes should enable successfully. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +# +# do not fail test in a domU +# +if [ ! -c /dev/xen/privcmd ]; then + exit 0 +fi + +dtrace=$1 + +script() +{ + $dtrace -qs /dev/stdin <<EOF + dtrace:::BEGIN + { + exit(0); + } + + xdt:sched::off-cpu, + xdt:sched::on-cpu, + xdt:sched::idle-off-cpu, + xdt:sched::idle-on-cpu, + xdt:sched::block, + xdt:sched::sleep, + xdt:sched::wake, + xdt:sched::yield, + xdt:sched::shutdown-poweroff, + xdt:sched::shutdown-reboot, + xdt:sched::shutdown-suspend, + xdt:sched::shutdown-crash + {} +EOF +} + +script +status=$? + +exit $status diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/err.D_PROC_ALIGN.misaligned.exe b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/err.D_PROC_ALIGN.misaligned.exe new file mode 100644 index 000000000000..595db1de33da --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/err.D_PROC_ALIGN.misaligned.exe @@ -0,0 +1,29 @@ +#!/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" + +sleep 1000000 diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/usdt/tst.tailcall.ksh b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/usdt/tst.tailcall.ksh index cfd7a631211a..c3651ecf7eb4 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/usdt/tst.tailcall.ksh +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/usdt/tst.tailcall.ksh @@ -76,7 +76,7 @@ provider test { }; EOF -/usr/ccs/bin/as -xregsym=no -P -D_ASM -o test.o test.s +/usr/bin/as -xregsym=no -P -D_ASM -o test.o test.s if [ $? -ne 0 ]; then print -u2 "failed to compile test.s" exit 1 @@ -127,6 +127,6 @@ EOF status=$? cd / -/usr/bin/rm -rf $DIR +/bin/rm -rf $DIR exit $status diff --git a/cddl/contrib/opensolaris/cmd/plockstat/plockstat.c b/cddl/contrib/opensolaris/cmd/plockstat/plockstat.c new file mode 100644 index 000000000000..aa2c1f9d2db9 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/plockstat/plockstat.c @@ -0,0 +1,1021 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#if defined(sun) +#pragma ident "%Z%%M% %I% %E% SMI" +#endif + +#include <assert.h> +#include <dtrace.h> +#include <limits.h> +#include <link.h> +#include <priv.h> +#include <signal.h> +#include <stdlib.h> +#include <stdarg.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <errno.h> +#include <sys/wait.h> +#include <libgen.h> +#include <libproc.h> +#include <libproc_compat.h> + +static char *g_pname; +static dtrace_hdl_t *g_dtp; +struct ps_prochandle *g_pr; + +#define E_SUCCESS 0 +#define E_ERROR 1 +#define E_USAGE 2 + +/* + * For hold times we use a global associative array since for mutexes, in + * user-land, it's not invalid to release a sychonization primitive that + * another thread acquired; rwlocks require a thread-local associative array + * since multiple thread can hold the same lock for reading. Note that we + * ignore recursive mutex acquisitions and releases as they don't truly + * affect lock contention. + */ +static const char *g_hold_init = +"plockstat$target:::rw-acquire\n" +"{\n" +" self->rwhold[arg0] = timestamp;\n" +"}\n" +"plockstat$target:::mutex-acquire\n" +"/arg1 == 0/\n" +"{\n" +" mtxhold[arg0] = timestamp;\n" +"}\n"; + +static const char *g_hold_histogram = +"plockstat$target:::rw-release\n" +"/self->rwhold[arg0] && arg1 == 1/\n" +"{\n" +" @rw_w_hold[arg0, ustack()] =\n" +" quantize(timestamp - self->rwhold[arg0]);\n" +" self->rwhold[arg0] = 0;\n" +" rw_w_hold_found = 1;\n" +"}\n" +"plockstat$target:::rw-release\n" +"/self->rwhold[arg0]/\n" +"{\n" +" @rw_r_hold[arg0, ustack()] =\n" +" quantize(timestamp - self->rwhold[arg0]);\n" +" self->rwhold[arg0] = 0;\n" +" rw_r_hold_found = 1;\n" +"}\n" +"plockstat$target:::mutex-release\n" +"/mtxhold[arg0] && arg1 == 0/\n" +"{\n" +" @mtx_hold[arg0, ustack()] = quantize(timestamp - mtxhold[arg0]);\n" +" mtxhold[arg0] = 0;\n" +" mtx_hold_found = 1;\n" +"}\n" +"\n" +"END\n" +"/mtx_hold_found/\n" +"{\n" +" trace(\"Mutex hold\");\n" +" printa(@mtx_hold);\n" +"}\n" +"END\n" +"/rw_r_hold_found/\n" +"{\n" +" trace(\"R/W reader hold\");\n" +" printa(@rw_r_hold);\n" +"}\n" +"END\n" +"/rw_w_hold_found/\n" +"{\n" +" trace(\"R/W writer hold\");\n" +" printa(@rw_w_hold);\n" +"}\n"; + +static const char *g_hold_times = +"plockstat$target:::rw-release\n" +"/self->rwhold[arg0] && arg1 == 1/\n" +"{\n" +" @rw_w_hold[arg0, ustack(5)] = sum(timestamp - self->rwhold[arg0]);\n" +" @rw_w_hold_count[arg0, ustack(5)] = count();\n" +" self->rwhold[arg0] = 0;\n" +" rw_w_hold_found = 1;\n" +"}\n" +"plockstat$target:::rw-release\n" +"/self->rwhold[arg0]/\n" +"{\n" +" @rw_r_hold[arg0, ustack(5)] = sum(timestamp - self->rwhold[arg0]);\n" +" @rw_r_hold_count[arg0, ustack(5)] = count();\n" +" self->rwhold[arg0] = 0;\n" +" rw_r_hold_found = 1;\n" +"}\n" +"plockstat$target:::mutex-release\n" +"/mtxhold[arg0] && arg1 == 0/\n" +"{\n" +" @mtx_hold[arg0, ustack(5)] = sum(timestamp - mtxhold[arg0]);\n" +" @mtx_hold_count[arg0, ustack(5)] = count();\n" +" mtxhold[arg0] = 0;\n" +" mtx_hold_found = 1;\n" +"}\n" +"\n" +"END\n" +"/mtx_hold_found/\n" +"{\n" +" trace(\"Mutex hold\");\n" +" printa(@mtx_hold, @mtx_hold_count);\n" +"}\n" +"END\n" +"/rw_r_hold_found/\n" +"{\n" +" trace(\"R/W reader hold\");\n" +" printa(@rw_r_hold, @rw_r_hold_count);\n" +"}\n" +"END\n" +"/rw_w_hold_found/\n" +"{\n" +" trace(\"R/W writer hold\");\n" +" printa(@rw_w_hold, @rw_w_hold_count);\n" +"}\n"; + + +/* + * For contention, we use thread-local associative arrays since we're tracing + * a single thread's activity in libc and multiple threads can be blocking or + * spinning on the same sychonization primitive. + */ +static const char *g_ctnd_init = +"plockstat$target:::rw-block\n" +"{\n" +" self->rwblock[arg0] = timestamp;\n" +"}\n" +"plockstat$target:::mutex-block\n" +"{\n" +" self->mtxblock[arg0] = timestamp;\n" +"}\n" +"plockstat$target:::mutex-spin\n" +"{\n" +" self->mtxspin[arg0] = timestamp;\n" +"}\n"; + +static const char *g_ctnd_histogram = +"plockstat$target:::rw-blocked\n" +"/self->rwblock[arg0] && arg1 == 1 && arg2 != 0/\n" +"{\n" +" @rw_w_block[arg0, ustack()] =\n" +" quantize(timestamp - self->rwblock[arg0]);\n" +" self->rwblock[arg0] = 0;\n" +" rw_w_block_found = 1;\n" +"}\n" +"plockstat$target:::rw-blocked\n" +"/self->rwblock[arg0] && arg2 != 0/\n" +"{\n" +" @rw_r_block[arg0, ustack()] =\n" +" quantize(timestamp - self->rwblock[arg0]);\n" +" self->rwblock[arg0] = 0;\n" +" rw_r_block_found = 1;\n" +"}\n" +"plockstat$target:::rw-blocked\n" +"/self->rwblock[arg0]/\n" +"{\n" +" self->rwblock[arg0] = 0;\n" +"}\n" +"plockstat$target:::mutex-spun\n" +"/self->mtxspin[arg0] && arg1 != 0/\n" +"{\n" +" @mtx_spin[arg0, ustack()] =\n" +" quantize(timestamp - self->mtxspin[arg0]);\n" +" self->mtxspin[arg0] = 0;\n" +" mtx_spin_found = 1;\n" +"}\n" +"plockstat$target:::mutex-spun\n" +"/self->mtxspin[arg0]/\n" +"{\n" +" @mtx_vain_spin[arg0, ustack()] =\n" +" quantize(timestamp - self->mtxspin[arg0]);\n" +" self->mtxspin[arg0] = 0;\n" +" mtx_vain_spin_found = 1;\n" +"}\n" +"plockstat$target:::mutex-blocked\n" +"/self->mtxblock[arg0] && arg1 != 0/\n" +"{\n" +" @mtx_block[arg0, ustack()] =\n" +" quantize(timestamp - self->mtxblock[arg0]);\n" +" self->mtxblock[arg0] = 0;\n" +" mtx_block_found = 1;\n" +"}\n" +"plockstat$target:::mutex-blocked\n" +"/self->mtxblock[arg0]/\n" +"{\n" +" self->mtxblock[arg0] = 0;\n" +"}\n" +"\n" +"END\n" +"/mtx_block_found/\n" +"{\n" +" trace(\"Mutex block\");\n" +" printa(@mtx_block);\n" +"}\n" +"END\n" +"/mtx_spin_found/\n" +"{\n" +" trace(\"Mutex spin\");\n" +" printa(@mtx_spin);\n" +"}\n" +"END\n" +"/mtx_vain_spin_found/\n" +"{\n" +" trace(\"Mutex unsuccessful spin\");\n" +" printa(@mtx_vain_spin);\n" +"}\n" +"END\n" +"/rw_r_block_found/\n" +"{\n" +" trace(\"R/W reader block\");\n" +" printa(@rw_r_block);\n" +"}\n" +"END\n" +"/rw_w_block_found/\n" +"{\n" +" trace(\"R/W writer block\");\n" +" printa(@rw_w_block);\n" +"}\n"; + + +static const char *g_ctnd_times = +"plockstat$target:::rw-blocked\n" +"/self->rwblock[arg0] && arg1 == 1 && arg2 != 0/\n" +"{\n" +" @rw_w_block[arg0, ustack(5)] =\n" +" sum(timestamp - self->rwblock[arg0]);\n" +" @rw_w_block_count[arg0, ustack(5)] = count();\n" +" self->rwblock[arg0] = 0;\n" +" rw_w_block_found = 1;\n" +"}\n" +"plockstat$target:::rw-blocked\n" +"/self->rwblock[arg0] && arg2 != 0/\n" +"{\n" +" @rw_r_block[arg0, ustack(5)] =\n" +" sum(timestamp - self->rwblock[arg0]);\n" +" @rw_r_block_count[arg0, ustack(5)] = count();\n" +" self->rwblock[arg0] = 0;\n" +" rw_r_block_found = 1;\n" +"}\n" +"plockstat$target:::rw-blocked\n" +"/self->rwblock[arg0]/\n" +"{\n" +" self->rwblock[arg0] = 0;\n" +"}\n" +"plockstat$target:::mutex-spun\n" +"/self->mtxspin[arg0] && arg1 != 0/\n" +"{\n" +" @mtx_spin[arg0, ustack(5)] =\n" +" sum(timestamp - self->mtxspin[arg0]);\n" +" @mtx_spin_count[arg0, ustack(5)] = count();\n" +" self->mtxspin[arg0] = 0;\n" +" mtx_spin_found = 1;\n" +"}\n" +"plockstat$target:::mutex-spun\n" +"/self->mtxspin[arg0]/\n" +"{\n" +" @mtx_vain_spin[arg0, ustack(5)] =\n" +" sum(timestamp - self->mtxspin[arg0]);\n" +" @mtx_vain_spin_count[arg0, ustack(5)] = count();\n" +" self->mtxspin[arg0] = 0;\n" +" mtx_vain_spin_found = 1;\n" +"}\n" +"plockstat$target:::mutex-blocked\n" +"/self->mtxblock[arg0] && arg1 != 0/\n" +"{\n" +" @mtx_block[arg0, ustack(5)] =\n" +" sum(timestamp - self->mtxblock[arg0]);\n" +" @mtx_block_count[arg0, ustack(5)] = count();\n" +" self->mtxblock[arg0] = 0;\n" +" mtx_block_found = 1;\n" +"}\n" +"plockstat$target:::mutex-blocked\n" +"/self->mtxblock[arg0]/\n" +"{\n" +" self->mtxblock[arg0] = 0;\n" +"}\n" +"\n" +"END\n" +"/mtx_block_found/\n" +"{\n" +" trace(\"Mutex block\");\n" +" printa(@mtx_block, @mtx_block_count);\n" +"}\n" +"END\n" +"/mtx_spin_found/\n" +"{\n" +" trace(\"Mutex spin\");\n" +" printa(@mtx_spin, @mtx_spin_count);\n" +"}\n" +"END\n" +"/mtx_vain_spin_found/\n" +"{\n" +" trace(\"Mutex unsuccessful spin\");\n" +" printa(@mtx_vain_spin, @mtx_vain_spin_count);\n" +"}\n" +"END\n" +"/rw_r_block_found/\n" +"{\n" +" trace(\"R/W reader block\");\n" +" printa(@rw_r_block, @rw_r_block_count);\n" +"}\n" +"END\n" +"/rw_w_block_found/\n" +"{\n" +" trace(\"R/W writer block\");\n" +" printa(@rw_w_block, @rw_w_block_count);\n" +"}\n"; + +static char g_prog[4096]; +static size_t g_proglen; +static int g_opt_V, g_opt_s; +static int g_intr; +static int g_exited; +static dtrace_optval_t g_nframes; +static ulong_t g_nent = ULONG_MAX; + +#define PLOCKSTAT_OPTSTR "n:ps:e:vx:ACHV" + +static void +usage(void) +{ + (void) fprintf(stderr, "Usage:\n" + "\t%s [-vACHV] [-n count] [-s depth] [-e secs] [-x opt[=val]]\n" + "\t command [arg...]\n" + "\t%s [-vACHV] [-n count] [-s depth] [-e secs] [-x opt[=val]]\n" + "\t -p pid\n", g_pname, g_pname); + + exit(E_USAGE); +} + +static void +verror(const char *fmt, va_list ap) +{ + int error = errno; + + (void) fprintf(stderr, "%s: ", g_pname); + (void) vfprintf(stderr, fmt, ap); + + if (fmt[strlen(fmt) - 1] != '\n') + (void) fprintf(stderr, ": %s\n", strerror(error)); +} + +/*PRINTFLIKE1*/ +static void +fatal(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + verror(fmt, ap); + va_end(ap); + + if (g_pr != NULL && g_dtp != NULL) + dtrace_proc_release(g_dtp, g_pr); + + exit(E_ERROR); +} + +/*PRINTFLIKE1*/ +static void +dfatal(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + + (void) fprintf(stderr, "%s: ", g_pname); + if (fmt != NULL) + (void) vfprintf(stderr, fmt, ap); + + va_end(ap); + + if (fmt != NULL && fmt[strlen(fmt) - 1] != '\n') { + (void) fprintf(stderr, ": %s\n", + dtrace_errmsg(g_dtp, dtrace_errno(g_dtp))); + } else if (fmt == NULL) { + (void) fprintf(stderr, "%s\n", + dtrace_errmsg(g_dtp, dtrace_errno(g_dtp))); + } + + if (g_pr != NULL) { + dtrace_proc_continue(g_dtp, g_pr); + dtrace_proc_release(g_dtp, g_pr); + } + + exit(E_ERROR); +} + +/*PRINTFLIKE1*/ +static void +notice(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + verror(fmt, ap); + va_end(ap); +} + +static void +dprog_add(const char *prog) +{ + size_t len = strlen(prog); + bcopy(prog, g_prog + g_proglen, len + 1); + g_proglen += len; + assert(g_proglen < sizeof (g_prog)); +} + +static void +dprog_compile(void) +{ + dtrace_prog_t *prog; + dtrace_proginfo_t info; + + if (g_opt_V) { + (void) fprintf(stderr, "%s: vvvv D program vvvv\n", g_pname); + (void) fputs(g_prog, stderr); + (void) fprintf(stderr, "%s: ^^^^ D program ^^^^\n", g_pname); + } + + if ((prog = dtrace_program_strcompile(g_dtp, g_prog, + DTRACE_PROBESPEC_NAME, 0, 0, NULL)) == NULL) + dfatal("failed to compile program"); + + if (dtrace_program_exec(g_dtp, prog, &info) == -1) + dfatal("failed to enable probes"); +} + +void +print_legend(void) +{ + (void) printf("%5s %8s %-28s %s\n", "Count", "nsec", "Lock", "Caller"); +} + +void +print_bar(void) +{ + (void) printf("---------------------------------------" + "----------------------------------------\n"); +} + +void +print_histogram_header(void) +{ + (void) printf("\n%10s ---- Time Distribution --- %5s %s\n", + "nsec", "count", "Stack"); +} + +/* + * Convert an address to a symbolic string or a numeric string. If nolocks + * is set, we return an error code if this symbol appears to be a mutex- or + * rwlock-related symbol in libc so the caller has a chance to find a more + * helpful symbol. + */ +static int +getsym(struct ps_prochandle *P, uintptr_t addr, char *buf, size_t size, + int nolocks) +{ + char name[256]; + GElf_Sym sym; +#if defined(sun) + prsyminfo_t info; +#else + prmap_t *map; + int info; /* XXX unused */ +#endif + size_t len; + + if (P == NULL || Pxlookup_by_addr(P, addr, name, sizeof (name), + &sym, &info) != 0) { + (void) snprintf(buf, size, "%#lx", addr); + return (0); + } +#if defined(sun) + if (info.prs_object == NULL) + info.prs_object = "<unknown>"; + + if (info.prs_lmid != LM_ID_BASE) { + len = snprintf(buf, size, "LM%lu`", info.prs_lmid); + buf += len; + size -= len; + } + + len = snprintf(buf, size, "%s`%s", info.prs_object, info.prs_name); +#else + map = proc_addr2map(P, addr); + len = snprintf(buf, size, "%s`%s", map->pr_mapname, name); +#endif + buf += len; + size -= len; + + if (sym.st_value != addr) + len = snprintf(buf, size, "+%#lx", addr - sym.st_value); + + if (nolocks && strcmp("libc.so.1", map->pr_mapname) == 0 && + (strstr("mutex", name) == 0 || + strstr("rw", name) == 0)) + return (-1); + + return (0); +} + +/*ARGSUSED*/ +static int +process_aggregate(const dtrace_aggdata_t **aggsdata, int naggvars, void *arg) +{ + const dtrace_recdesc_t *rec; + uintptr_t lock; + uint64_t *stack; + caddr_t data; + pid_t pid; + struct ps_prochandle *P; + char buf[256]; + int i, j; + uint64_t sum, count, avg; + + if ((*(uint_t *)arg)++ >= g_nent) + return (DTRACE_AGGWALK_NEXT); + + rec = aggsdata[0]->dtada_desc->dtagd_rec; + data = aggsdata[0]->dtada_data; + + /*LINTED - alignment*/ + lock = (uintptr_t)*(uint64_t *)(data + rec[1].dtrd_offset); + /*LINTED - alignment*/ + stack = (uint64_t *)(data + rec[2].dtrd_offset); + + if (!g_opt_s) { + /*LINTED - alignment*/ + sum = *(uint64_t *)(aggsdata[1]->dtada_data + + aggsdata[1]->dtada_desc->dtagd_rec[3].dtrd_offset); + /*LINTED - alignment*/ + count = *(uint64_t *)(aggsdata[2]->dtada_data + + aggsdata[2]->dtada_desc->dtagd_rec[3].dtrd_offset); + } else { + uint64_t *a; + + /*LINTED - alignment*/ + a = (uint64_t *)(aggsdata[1]->dtada_data + + aggsdata[1]->dtada_desc->dtagd_rec[3].dtrd_offset); + + print_bar(); + print_legend(); + + for (count = sum = 0, i = DTRACE_QUANTIZE_ZEROBUCKET, j = 0; + i < DTRACE_QUANTIZE_NBUCKETS; i++, j++) { + count += a[i]; + sum += a[i] << (j - 64); + } + } + + avg = sum / count; + (void) printf("%5llu %8llu ", (u_longlong_t)count, (u_longlong_t)avg); + + pid = stack[0]; + P = dtrace_proc_grab(g_dtp, pid, PGRAB_RDONLY); + + (void) getsym(P, lock, buf, sizeof (buf), 0); + (void) printf("%-28s ", buf); + + for (i = 2; i <= 5; i++) { + if (getsym(P, stack[i], buf, sizeof (buf), 1) == 0) + break; + } + (void) printf("%s\n", buf); + + if (g_opt_s) { + int stack_done = 0; + int quant_done = 0; + int first_bin, last_bin; + uint64_t bin_size, *a; + + /*LINTED - alignment*/ + a = (uint64_t *)(aggsdata[1]->dtada_data + + aggsdata[1]->dtada_desc->dtagd_rec[3].dtrd_offset); + + print_histogram_header(); + + for (first_bin = DTRACE_QUANTIZE_ZEROBUCKET; + a[first_bin] == 0; first_bin++) + continue; + for (last_bin = DTRACE_QUANTIZE_ZEROBUCKET + 63; + a[last_bin] == 0; last_bin--) + continue; + + for (i = 0; !stack_done || !quant_done; i++) { + if (!stack_done) { + (void) getsym(P, stack[i + 2], buf, + sizeof (buf), 0); + } else { + buf[0] = '\0'; + } + + if (!quant_done) { + bin_size = a[first_bin]; + + (void) printf("%10llu |%-24.*s| %5llu %s\n", + 1ULL << + (first_bin - DTRACE_QUANTIZE_ZEROBUCKET), + (int)(24.0 * bin_size / count), + "@@@@@@@@@@@@@@@@@@@@@@@@@@", + (u_longlong_t)bin_size, buf); + } else { + (void) printf("%43s %s\n", "", buf); + } + + if (i + 1 >= g_nframes || stack[i + 3] == 0) + stack_done = 1; + + if (first_bin++ == last_bin) + quant_done = 1; + } + } + + dtrace_proc_release(g_dtp, P); + + return (DTRACE_AGGWALK_NEXT); +} + +/*ARGSUSED*/ +static void +prochandler(struct ps_prochandle *P, const char *msg, void *arg) +{ +#if defined(sun) + const psinfo_t *prp = Ppsinfo(P); + int pid = Pstatus(P)->pr_pid; +#else + int pid = proc_getpid(P); + int wstat = proc_getwstat(P); +#endif + char name[SIG2STR_MAX]; + + if (msg != NULL) { + notice("pid %d: %s\n", pid, msg); + return; + } + + switch (Pstate(P)) { + case PS_UNDEAD: + /* + * Ideally we would like to always report pr_wstat here, but it + * isn't possible given current /proc semantics. If we grabbed + * the process, Ppsinfo() will either fail or return a zeroed + * psinfo_t depending on how far the parent is in reaping it. + * When /proc provides a stable pr_wstat in the status file, + * this code can be improved by examining this new pr_wstat. + */ + if (WIFSIGNALED(wstat)) { + notice("pid %d terminated by %s\n", pid, + proc_signame(WTERMSIG(wstat), + name, sizeof (name))); + } else if (WEXITSTATUS(wstat) != 0) { + notice("pid %d exited with status %d\n", + pid, WEXITSTATUS(wstat)); + } else { + notice("pid %d has exited\n", pid); + } + g_exited = 1; + break; + + case PS_LOST: + notice("pid %d exec'd a set-id or unobservable program\n", pid); + g_exited = 1; + break; + } +} + +/*ARGSUSED*/ +static int +chewrec(const dtrace_probedata_t *data, const dtrace_recdesc_t *rec, void *arg) +{ + dtrace_eprobedesc_t *epd = data->dtpda_edesc; + dtrace_aggvarid_t aggvars[2]; + const void *buf; + int i, nagv; + + /* + * A NULL rec indicates that we've processed the last record. + */ + if (rec == NULL) + return (DTRACE_CONSUME_NEXT); + + buf = data->dtpda_data - rec->dtrd_offset; + + switch (rec->dtrd_action) { + case DTRACEACT_DIFEXPR: + (void) printf("\n%s\n\n", (char *)buf + rec->dtrd_offset); + if (!g_opt_s) { + print_legend(); + print_bar(); + } + return (DTRACE_CONSUME_NEXT); + + case DTRACEACT_PRINTA: + for (nagv = 0, i = 0; i < epd->dtepd_nrecs - 1; i++) { + const dtrace_recdesc_t *nrec = &rec[i]; + + if (nrec->dtrd_uarg != rec->dtrd_uarg) + break; + + /*LINTED - alignment*/ + aggvars[nagv++] = *(dtrace_aggvarid_t *)((caddr_t)buf + + nrec->dtrd_offset); + } + + if (nagv == (g_opt_s ? 1 : 2)) { + uint_t nent = 0; + if (dtrace_aggregate_walk_joined(g_dtp, aggvars, nagv, + process_aggregate, &nent) != 0) + dfatal("failed to walk aggregate"); + } + + return (DTRACE_CONSUME_NEXT); + } + + return (DTRACE_CONSUME_THIS); +} + +/*ARGSUSED*/ +static void +intr(int signo) +{ + g_intr = 1; +} + +int +main(int argc, char **argv) +{ +#if defined(sun) + ucred_t *ucp; +#endif + int err; + int opt_C = 0, opt_H = 0, opt_p = 0, opt_v = 0; + char c, *p, *end; + struct sigaction act; + int done = 0; + + g_pname = basename(argv[0]); + argv[0] = g_pname; /* rewrite argv[0] for getopt errors */ +#if defined(sun) + /* + * Make sure we have the required dtrace_proc privilege. + */ + if ((ucp = ucred_get(getpid())) != NULL) { + const priv_set_t *psp; + if ((psp = ucred_getprivset(ucp, PRIV_EFFECTIVE)) != NULL && + !priv_ismember(psp, PRIV_DTRACE_PROC)) { + fatal("dtrace_proc privilege required\n"); + } + + ucred_free(ucp); + } +#endif + + while ((c = getopt(argc, argv, PLOCKSTAT_OPTSTR)) != EOF) { + switch (c) { + case 'n': + errno = 0; + g_nent = strtoul(optarg, &end, 10); + if (*end != '\0' || errno != 0) { + (void) fprintf(stderr, "%s: invalid count " + "'%s'\n", g_pname, optarg); + usage(); + } + break; + + case 'p': + opt_p = 1; + break; + + case 'v': + opt_v = 1; + break; + + case 'A': + opt_C = opt_H = 1; + break; + + case 'C': + opt_C = 1; + break; + + case 'H': + opt_H = 1; + break; + + case 'V': + g_opt_V = 1; + break; + + default: + if (strchr(PLOCKSTAT_OPTSTR, c) == NULL) + usage(); + } + } + + /* + * We need a command or at least one pid. + */ + if (argc == optind) + usage(); + + if (opt_C == 0 && opt_H == 0) + opt_C = 1; + + if ((g_dtp = dtrace_open(DTRACE_VERSION, 0, &err)) == NULL) + fatal("failed to initialize dtrace: %s\n", + dtrace_errmsg(NULL, err)); + + /* + * The longest string we trace is 23 bytes long -- so 32 is plenty. + */ + if (dtrace_setopt(g_dtp, "strsize", "32") == -1) + dfatal("failed to set 'strsize'"); + + /* + * 1k should be more than enough for all trace() and printa() actions. + */ + if (dtrace_setopt(g_dtp, "bufsize", "1k") == -1) + dfatal("failed to set 'bufsize'"); + + /* + * The table we produce has the hottest locks at the top. + */ + if (dtrace_setopt(g_dtp, "aggsortrev", NULL) == -1) + dfatal("failed to set 'aggsortrev'"); + + /* + * These are two reasonable defaults which should suffice. + */ + if (dtrace_setopt(g_dtp, "aggsize", "256k") == -1) + dfatal("failed to set 'aggsize'"); + if (dtrace_setopt(g_dtp, "aggrate", "1sec") == -1) + dfatal("failed to set 'aggrate'"); + + /* + * Take a second pass through to look for options that set options now + * that we have an open dtrace handle. + */ + optind = 1; + while ((c = getopt(argc, argv, PLOCKSTAT_OPTSTR)) != EOF) { + switch (c) { + case 's': + g_opt_s = 1; + if (dtrace_setopt(g_dtp, "ustackframes", optarg) == -1) + dfatal("failed to set 'ustackframes'"); + break; + + case 'x': + if ((p = strchr(optarg, '=')) != NULL) + *p++ = '\0'; + + if (dtrace_setopt(g_dtp, optarg, p) != 0) + dfatal("failed to set -x %s", optarg); + break; + + case 'e': + errno = 0; + (void) strtoul(optarg, &end, 10); + if (*optarg == '-' || *end != '\0' || errno != 0) { + (void) fprintf(stderr, "%s: invalid timeout " + "'%s'\n", g_pname, optarg); + usage(); + } + + /* + * Construct a DTrace enabling that will exit after + * the specified number of seconds. + */ + dprog_add("BEGIN\n{\n\tend = timestamp + "); + dprog_add(optarg); + dprog_add(" * 1000000000;\n}\n"); + dprog_add("tick-10hz\n/timestamp >= end/\n"); + dprog_add("{\n\texit(0);\n}\n"); + break; + } + } + + argc -= optind; + argv += optind; + + if (opt_H) { + dprog_add(g_hold_init); + if (!g_opt_s) + dprog_add(g_hold_times); + else + dprog_add(g_hold_histogram); + } + + if (opt_C) { + dprog_add(g_ctnd_init); + if (!g_opt_s) + dprog_add(g_ctnd_times); + else + dprog_add(g_ctnd_histogram); + } + + if (opt_p) { + ulong_t pid; + + if (argc > 1) { + (void) fprintf(stderr, "%s: only one pid is allowed\n", + g_pname); + usage(); + } + + errno = 0; + pid = strtoul(argv[0], &end, 10); + if (*end != '\0' || errno != 0 || (pid_t)pid != pid) { + (void) fprintf(stderr, "%s: invalid pid '%s'\n", + g_pname, argv[0]); + usage(); + } + + if ((g_pr = dtrace_proc_grab(g_dtp, (pid_t)pid, 0)) == NULL) + dfatal(NULL); + } else { + if ((g_pr = dtrace_proc_create(g_dtp, argv[0], argv, NULL, NULL)) == NULL) + dfatal(NULL); + } + + dprog_compile(); + + if (dtrace_handle_proc(g_dtp, &prochandler, NULL) == -1) + dfatal("failed to establish proc handler"); + + (void) sigemptyset(&act.sa_mask); + act.sa_flags = 0; + act.sa_handler = intr; + (void) sigaction(SIGINT, &act, NULL); + (void) sigaction(SIGTERM, &act, NULL); + + if (dtrace_go(g_dtp) != 0) + dfatal("dtrace_go()"); + + if (dtrace_getopt(g_dtp, "ustackframes", &g_nframes) != 0) + dfatal("failed to get 'ustackframes'"); + + dtrace_proc_continue(g_dtp, g_pr); + + if (opt_v) + (void) printf("%s: tracing enabled for pid %d\n", g_pname, +#if defined(sun) + (int)Pstatus(g_pr)->pr_pid); +#else + (int)proc_getpid(g_pr)); +#endif + + do { + if (!g_intr && !done) + dtrace_sleep(g_dtp); + + if (done || g_intr || g_exited) { + done = 1; + if (dtrace_stop(g_dtp) == -1) + dfatal("couldn't stop tracing"); + } + + switch (dtrace_work(g_dtp, stdout, NULL, chewrec, NULL)) { + case DTRACE_WORKSTATUS_DONE: + done = 1; + break; + case DTRACE_WORKSTATUS_OKAY: + break; + default: + dfatal("processing aborted"); + } + + } while (!done); + + dtrace_close(g_dtp); + + return (0); +} diff --git a/cddl/contrib/opensolaris/common/avl/avl.c b/cddl/contrib/opensolaris/common/avl/avl.c index 7403e813014c..dd39c12d215e 100644 --- a/cddl/contrib/opensolaris/common/avl/avl.c +++ b/cddl/contrib/opensolaris/common/avl/avl.c @@ -19,13 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - - /* * AVL - generic AVL tree implementation for kernel use * @@ -243,7 +240,7 @@ avl_nearest(avl_tree_t *tree, avl_index_t where, int direction) * "void *" of the found tree node */ void * -avl_find(avl_tree_t *tree, void *value, avl_index_t *where) +avl_find(avl_tree_t *tree, const void *value, avl_index_t *where) { avl_node_t *node; avl_node_t *prev = NULL; @@ -808,6 +805,64 @@ avl_remove(avl_tree_t *tree, void *data) } while (parent != NULL); } +#define AVL_REINSERT(tree, obj) \ + avl_remove((tree), (obj)); \ + avl_add((tree), (obj)) + +boolean_t +avl_update_lt(avl_tree_t *t, void *obj) +{ + void *neighbor; + + ASSERT(((neighbor = AVL_NEXT(t, obj)) == NULL) || + (t->avl_compar(obj, neighbor) <= 0)); + + neighbor = AVL_PREV(t, obj); + if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) < 0)) { + AVL_REINSERT(t, obj); + return (B_TRUE); + } + + return (B_FALSE); +} + +boolean_t +avl_update_gt(avl_tree_t *t, void *obj) +{ + void *neighbor; + + ASSERT(((neighbor = AVL_PREV(t, obj)) == NULL) || + (t->avl_compar(obj, neighbor) >= 0)); + + neighbor = AVL_NEXT(t, obj); + if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) > 0)) { + AVL_REINSERT(t, obj); + return (B_TRUE); + } + + return (B_FALSE); +} + +boolean_t +avl_update(avl_tree_t *t, void *obj) +{ + void *neighbor; + + neighbor = AVL_PREV(t, obj); + if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) < 0)) { + AVL_REINSERT(t, obj); + return (B_TRUE); + } + + neighbor = AVL_NEXT(t, obj); + if ((neighbor != NULL) && (t->avl_compar(obj, neighbor) > 0)) { + AVL_REINSERT(t, obj); + return (B_TRUE); + } + + return (B_FALSE); +} + /* * initialize a new AVL tree */ @@ -853,6 +908,12 @@ avl_numnodes(avl_tree_t *tree) return (tree->avl_numnodes); } +boolean_t +avl_is_empty(avl_tree_t *tree) +{ + ASSERT(tree); + return (tree->avl_numnodes == 0); +} #define CHILDBIT (1L) diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c b/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c index c983c5b595a8..7a14dd38d31e 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <unistd.h> #include <fcntl.h> #include <dlfcn.h> @@ -37,6 +34,8 @@ #include <stdlib.h> #include <string.h> #include <errno.h> +#include <libelf.h> +#include <gelf.h> /* * In Solaris 10 GA, the only mechanism for communicating helper information @@ -56,18 +55,23 @@ */ static const char *devnamep = "/dev/dtrace/helper"; +#if defined(sun) static const char *olddevname = "/devices/pseudo/dtrace@0:helper"; +#endif static const char *modname; /* Name of this load object */ static int gen; /* DOF helper generation */ +#if defined(sun) extern dof_hdr_t __SUNW_dof; /* DOF defined in the .SUNW_dof section */ +#endif +static boolean_t dof_init_debug = B_FALSE; /* From DTRACE_DOF_INIT_DEBUG */ static void dprintf(int debug, const char *fmt, ...) { va_list ap; - if (debug && getenv("DTRACE_DOF_INIT_DEBUG") == NULL) + if (debug && !dof_init_debug) return; va_start(ap, fmt); @@ -85,6 +89,36 @@ dprintf(int debug, const char *fmt, ...) va_end(ap); } +#if !defined(sun) +static void +fixsymbol(Elf *e, Elf_Data *data, size_t idx, int nprobes, char *buf, + dof_sec_t *sec, int *fixedprobes, char *dofstrtab) +{ + GElf_Sym sym; + char *s; + unsigned char *funcname; + dof_probe_t *prb; + int j = 0; + int ndx; + + while (gelf_getsym(data, j++, &sym) != NULL) { + prb = (dof_probe_t *)(buf + sec->dofs_offset); + + for (ndx = nprobes; ndx; ndx--, prb += 1) { + funcname = dofstrtab + prb->dofpr_func; + s = elf_strptr(e, idx, sym.st_name); + if (strcmp(s, funcname) == 0) { + dprintf(1, "fixing %s() symbol\n", s); + prb->dofpr_addr = sym.st_value; + (*fixedprobes)++; + } + } + if (*fixedprobes == nprobes) + break; + } +} +#endif + #if defined(sun) #pragma init(dtrace_dof_init) #else @@ -94,26 +128,46 @@ static void dtrace_dof_init(void) __attribute__ ((constructor)); static void dtrace_dof_init(void) { +#if defined(sun) dof_hdr_t *dof = &__SUNW_dof; +#else + dof_hdr_t *dof = NULL; +#endif #ifdef _LP64 Elf64_Ehdr *elf; #else Elf32_Ehdr *elf; #endif dof_helper_t dh; -#if defined(sun) Link_map *lmp; +#if defined(sun) Lmid_t lmid; #else - struct link_map *lmp; u_long lmid = 0; + dof_sec_t *sec; + size_t i; #endif int fd; const char *p; +#if !defined(sun) + Elf *e; + Elf_Scn *scn = NULL; + Elf_Data *symtabdata = NULL, *dynsymdata = NULL; + GElf_Shdr shdr; + int efd, nprobes; + char *s; + size_t shstridx, symtabidx = 0, dynsymidx = 0; + unsigned char *dofstrtab = NULL; + unsigned char *buf; + int fixedprobes = 0; +#endif if (getenv("DTRACE_DOF_INIT_DISABLE") != NULL) return; + if (getenv("DTRACE_DOF_INIT_DEBUG") != NULL) + dof_init_debug = B_TRUE; + if (dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &lmp) == -1 || lmp == NULL) { dprintf(1, "couldn't discover module name or address\n"); return; @@ -126,10 +180,46 @@ dtrace_dof_init(void) } #endif + if ((modname = strrchr(lmp->l_name, '/')) == NULL) modname = lmp->l_name; else modname++; +#if !defined(sun) + elf_version(EV_CURRENT); + if ((efd = open(lmp->l_name, O_RDONLY, 0)) < 0) { + dprintf(1, "couldn't open file for reading\n"); + return; + } + if ((e = elf_begin(efd, ELF_C_READ, NULL)) == NULL) { + dprintf(1, "elf_begin failed\n"); + close(efd); + return; + } + elf_getshdrstrndx(e, &shstridx); + dof = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + gelf_getshdr(scn, &shdr); + if (shdr.sh_type == SHT_SYMTAB) { + symtabidx = shdr.sh_link; + symtabdata = elf_getdata(scn, NULL); + } else if (shdr.sh_type == SHT_DYNSYM) { + dynsymidx = shdr.sh_link; + dynsymdata = elf_getdata(scn, NULL); + } else if (shdr.sh_type == SHT_PROGBITS) { + s = elf_strptr(e, shstridx, shdr.sh_name); + if (s && strcmp(s, ".SUNW_dof") == 0) { + dof = elf_getdata(scn, NULL)->d_buf; + } + } + } + if (dof == NULL) { + dprintf(1, "SUNW_dof section not found\n"); + elf_end(e); + close(efd); + return; + } +#endif if (dof->dofh_ident[DOF_ID_MAG0] != DOF_MAG_MAG0 || dof->dofh_ident[DOF_ID_MAG1] != DOF_MAG_MAG1 || @@ -157,7 +247,7 @@ dtrace_dof_init(void) if ((fd = open64(devnamep, O_RDWR)) < 0) { dprintf(1, "failed to open helper device %s", devnamep); - +#if defined(sun) /* * If the device path wasn't explicitly set, try again with * the old device path. @@ -171,14 +261,79 @@ dtrace_dof_init(void) dprintf(1, "failed to open helper device %s", devnamep); return; } +#else + return; +#endif } - +#if !defined(sun) + /* + * We need to fix the base address of each probe since this wasn't + * done by ld(1). (ld(1) needs to grow support for parsing the + * SUNW_dof section). + * + * The complexity of this is not that great. The first for loop + * iterates over the sections inside the DOF file. There are usually + * 10 sections here. We asume the STRTAB section comes first and the + * PROBES section comes after. Since we are only interested in fixing + * data inside the PROBES section we quit the for loop after processing + * the PROBES section. It's usually the case that the first section + * is the STRTAB section and the second section is the PROBES section, + * so this for loop is not meaningful when doing complexity analysis. + * + * After finding the probes section, we iterate over the symbols + * in the symtab section. When we find a symbol name that matches + * the probe function name, we fix it. If we have fixed all the + * probes, we exit all the loops and we are done. + * The number of probes is given by the variable 'nprobes' and this + * depends entirely on the user, but some optimizations were done. + * + * We are assuming the number of probes is less than the number of + * symbols (libc can have 4k symbols, for example). + */ + sec = (dof_sec_t *)(dof + 1); + buf = (char *)dof; + for (i = 0; i < dof->dofh_secnum; i++, sec++) { + if (sec->dofs_type == DOF_SECT_STRTAB) + dofstrtab = (unsigned char *)(buf + sec->dofs_offset); + else if (sec->dofs_type == DOF_SECT_PROBES && dofstrtab) + break; + + } + nprobes = sec->dofs_size / sec->dofs_entsize; + fixsymbol(e, symtabdata, symtabidx, nprobes, buf, sec, &fixedprobes, + dofstrtab); + if (fixedprobes != nprobes) { + /* + * If we haven't fixed all the probes using the + * symtab section, look inside the dynsym + * section. + */ + fixsymbol(e, dynsymdata, dynsymidx, nprobes, buf, sec, + &fixedprobes, dofstrtab); + } + if (fixedprobes != nprobes) { + fprintf(stderr, "WARNING: number of probes " + "fixed does not match the number of " + "defined probes (%d != %d, " + "respectively)\n", fixedprobes, nprobes); + fprintf(stderr, "WARNING: some probes might " + "not fire or your program might crash\n"); + } +#endif if ((gen = ioctl(fd, DTRACEHIOC_ADDDOF, &dh)) == -1) dprintf(1, "DTrace ioctl failed for DOF at %p", dof); - else + else { dprintf(1, "DTrace ioctl succeeded for DOF at %p\n", dof); +#if !defined(sun) + gen = dh.gen; +#endif + } (void) close(fd); +#if !defined(sun) + elf_end(e); + (void) close(efd); +#endif } #if defined(sun) @@ -197,7 +352,7 @@ dtrace_dof_fini(void) return; } - if ((gen = ioctl(fd, DTRACEHIOC_REMOVE, gen)) == -1) + if ((gen = ioctl(fd, DTRACEHIOC_REMOVE, &gen)) == -1) dprintf(1, "DTrace ioctl failed to remove DOF (%d)\n", gen); else dprintf(1, "DTrace ioctl removed DOF (%d)\n", gen); diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c index ac32f769a934..f6c9622c6c86 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c @@ -36,6 +36,7 @@ #include <alloca.h> #else #include <sys/sysctl.h> +#include <libproc_compat.h> #endif #include <limits.h> @@ -264,11 +265,7 @@ dt_aggregate_usym(dtrace_hdl_t *dtp, uint64_t *data) dt_proc_lock(dtp, P); -#if defined(sun) if (Plookup_by_addr(P, *pc, NULL, 0, &sym) == 0) -#else - if (proc_addr2sym(P, *pc, NULL, 0, &sym) == 0) -#endif *pc = sym.st_value; dt_proc_unlock(dtp, P); @@ -291,11 +288,7 @@ dt_aggregate_umod(dtrace_hdl_t *dtp, uint64_t *data) dt_proc_lock(dtp, P); -#if defined(sun) if ((map = Paddr_to_map(P, *pc)) != NULL) -#else - if ((map = proc_addr2map(P, *pc)) != NULL) -#endif *pc = map->pr_vaddr; dt_proc_unlock(dtp, P); diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c index 8bd09151d1c4..5250641b5a2d 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_cc.c @@ -20,12 +20,9 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * DTrace D Language Compiler * @@ -2165,11 +2162,11 @@ dt_compile(dtrace_hdl_t *dtp, int context, dtrace_probespec_t pspec, void *arg, if (dt_list_next(&dtp->dt_lib_path) != NULL && dt_load_libs(dtp) != 0) return (NULL); /* errno is set for us */ - (void) ctf_discard(dtp->dt_cdefs->dm_ctfp); - (void) ctf_discard(dtp->dt_ddefs->dm_ctfp); + if (dtp->dt_globals->dh_nelems != 0) + (void) dt_idhash_iter(dtp->dt_globals, dt_idreset, NULL); - (void) dt_idhash_iter(dtp->dt_globals, dt_idreset, NULL); - (void) dt_idhash_iter(dtp->dt_tls, dt_idreset, NULL); + if (dtp->dt_tls->dh_nelems != 0) + (void) dt_idhash_iter(dtp->dt_tls, dt_idreset, NULL); if (fp && (cflags & DTRACE_C_CPP) && (fp = dt_preproc(dtp, fp)) == NULL) return (NULL); /* errno is set for us */ diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c index 776fd17c0309..911478ee0753 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdlib.h> #include <strings.h> #include <errno.h> @@ -36,6 +34,9 @@ #include <alloca.h> #endif #include <dt_impl.h> +#if !defined(sun) +#include <libproc_compat.h> +#endif #define DT_MASK_LO 0x00000000FFFFFFFFULL @@ -954,17 +955,9 @@ dt_print_ustack(dtrace_hdl_t *dtp, FILE *fp, const char *format, if ((err = dt_printf(dtp, fp, "%*s", indent, "")) < 0) break; -#if defined(sun) if (P != NULL && Plookup_by_addr(P, pc[i], -#else - if (P != NULL && proc_addr2sym(P, pc[i], -#endif name, sizeof (name), &sym) == 0) { -#if defined(sun) (void) Pobjname(P, pc[i], objname, sizeof (objname)); -#else - (void) proc_objname(P, pc[i], objname, sizeof (objname)); -#endif if (pc[i] > sym.st_value) { (void) snprintf(c, sizeof (c), @@ -975,12 +968,8 @@ dt_print_ustack(dtrace_hdl_t *dtp, FILE *fp, const char *format, "%s`%s", dt_basename(objname), name); } } else if (str != NULL && str[0] != '\0' && str[0] != '@' && -#if defined(sun) (P != NULL && ((map = Paddr_to_map(P, pc[i])) == NULL || (map->pr_mflags & MA_WRITE)))) { -#else - (P != NULL && ((map = proc_addr2map(P, pc[i])) == NULL))) { -#endif /* * If the current string pointer in the string table * does not point to an empty string _and_ the program @@ -996,11 +985,7 @@ dt_print_ustack(dtrace_hdl_t *dtp, FILE *fp, const char *format, */ (void) snprintf(c, sizeof (c), "%s", str); } else { -#if defined(sun) if (P != NULL && Pobjname(P, pc[i], objname, -#else - if (P != NULL && proc_objname(P, pc[i], objname, -#endif sizeof (objname)) != 0) { (void) snprintf(c, sizeof (c), "%s`0x%llx", dt_basename(objname), (u_longlong_t)pc[i]); @@ -1070,11 +1055,7 @@ dt_print_usym(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr, dtrace_actkind_t act) dt_proc_lock(dtp, P); -#if defined(sun) if (Plookup_by_addr(P, pc, NULL, 0, &sym) == 0) -#else - if (proc_addr2sym(P, pc, NULL, 0, &sym) == 0) -#endif pc = sym.st_value; dt_proc_unlock(dtp, P); @@ -1085,7 +1066,7 @@ dt_print_usym(dtrace_hdl_t *dtp, FILE *fp, caddr_t addr, dtrace_actkind_t act) do { n = len; s = alloca(n); - } while ((len = dtrace_uaddr2str(dtp, pid, pc, s, n)) >= n); + } while ((len = dtrace_uaddr2str(dtp, pid, pc, s, n)) > n); return (dt_printf(dtp, fp, format, s)); } @@ -1117,11 +1098,7 @@ dt_print_umod(dtrace_hdl_t *dtp, FILE *fp, const char *format, caddr_t addr) if (P != NULL) dt_proc_lock(dtp, P); /* lock handle while we perform lookups */ -#if defined(sun) if (P != NULL && Pobjname(P, pc, objname, sizeof (objname)) != 0) { -#else - if (P != NULL && proc_objname(P, pc, objname, sizeof (objname)) != 0) { -#endif (void) snprintf(c, sizeof (c), "%s", dt_basename(objname)); } else { (void) snprintf(c, sizeof (c), "0x%llx", (u_longlong_t)pc); diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c index f35a386c5d7d..6ed9480ecfa9 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c @@ -20,12 +20,9 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #if defined(sun) #include <sys/sysmacros.h> @@ -838,7 +835,6 @@ dtrace_dof_create(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t flags) */ h.dofh_secnum = ddo->ddo_nsecs; ssize = sizeof (h) + dt_buf_len(&ddo->ddo_secs); - assert(ssize == sizeof (h) + sizeof (dof_sec_t) * ddo->ddo_nsecs); h.dofh_loadsz = ssize + dt_buf_len(&ddo->ddo_ldata) + @@ -864,6 +860,7 @@ dtrace_dof_create(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t flags) sp = dt_buf_ptr(&ddo->ddo_secs); assert(sp[ddo->ddo_strsec].dofs_type == DOF_SECT_STRTAB); + assert(ssize == sizeof (h) + sizeof (dof_sec_t) * ddo->ddo_nsecs); sp[ddo->ddo_strsec].dofs_offset = ssize + dt_buf_len(&ddo->ddo_ldata); sp[ddo->ddo_strsec].dofs_size = dt_buf_len(&ddo->ddo_strs); diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c index 263f70c85ecc..a28505c12de6 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_error.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <string.h> #include <strings.h> #include <dt_impl.h> @@ -106,7 +104,8 @@ static const struct { { EDT_BADSETOPT, "Invalid setopt() library action" }, { EDT_BADSTACKPC, "Invalid stack program counter size" }, { EDT_BADAGGVAR, "Invalid aggregation variable identifier" }, - { EDT_OVERSION, "Client requested deprecated version of library" } + { EDT_OVERSION, "Client requested deprecated version of library" }, + { EDT_ENABLING_ERR, "Failed to enable probe" } }; static const int _dt_nerr = sizeof (_dt_errlist) / sizeof (_dt_errlist[0]); diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h index a712d24955c6..bfdaecd0b670 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h @@ -20,15 +20,13 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _DT_IMPL_H #define _DT_IMPL_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/param.h> #include <sys/objfs.h> #if !defined(sun) @@ -42,6 +40,9 @@ #include <libctf.h> #include <dtrace.h> #include <gelf.h> +#if defined(sun) +#include <synch.h> +#endif #ifdef __cplusplus extern "C" { @@ -519,7 +520,8 @@ enum { EDT_BADSETOPT, /* invalid setopt library action */ EDT_BADSTACKPC, /* invalid stack program counter size */ EDT_BADAGGVAR, /* invalid aggregation variable identifier */ - EDT_OVERSION /* client is requesting deprecated version */ + EDT_OVERSION, /* client is requesting deprecated version */ + EDT_ENABLING_ERR /* failed to enable probe */ }; /* @@ -599,19 +601,18 @@ extern int dt_buffered_flush(dtrace_hdl_t *, dtrace_probedata_t *, extern void dt_buffered_disable(dtrace_hdl_t *); extern void dt_buffered_destroy(dtrace_hdl_t *); +extern uint64_t dt_stddev(uint64_t *, uint64_t); + extern int dt_rw_read_held(pthread_rwlock_t *); extern int dt_rw_write_held(pthread_rwlock_t *); extern int dt_mutex_held(pthread_mutex_t *); - -extern uint64_t dt_stddev(uint64_t *, uint64_t); - -#define DT_RW_READ_HELD(x) dt_rw_read_held(x) -#define DT_RW_WRITE_HELD(x) dt_rw_write_held(x) -#define DT_RW_LOCK_HELD(x) (DT_RW_READ_HELD(x) || DT_RW_WRITE_HELD(x)) -#define DT_MUTEX_HELD(x) dt_mutex_held(x) - extern int dt_options_load(dtrace_hdl_t *); +#define DT_RW_READ_HELD(x) dt_rw_read_held(x) +#define DT_RW_WRITE_HELD(x) dt_rw_write_held(x) +#define DT_RW_LOCK_HELD(x) (DT_RW_READ_HELD(x) || DT_RW_WRITE_HELD(x)) +#define DT_MUTEX_HELD(x) dt_mutex_held(x) + extern void dt_dprintf(const char *, ...); extern void dt_setcontext(dtrace_hdl_t *, dtrace_probedesc_t *); diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_lex.l b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_lex.l index 48975274dede..90feceaa5efe 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_lex.l +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_lex.l @@ -18,12 +18,11 @@ * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END - * - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + */ #include <string.h> #include <stdlib.h> @@ -826,7 +825,7 @@ input(void) else if (yypcb->pcb_fileptr != NULL) c = fgetc(yypcb->pcb_fileptr); else if (yypcb->pcb_strptr < yypcb->pcb_string + yypcb->pcb_strlen) - c = *yypcb->pcb_strptr++; + c = *(unsigned char *)(yypcb->pcb_strptr++); else c = EOF; diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c index aa78658b5fca..ca355eacdd77 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_link.c @@ -51,6 +51,9 @@ #include <wait.h> #else #include <sys/wait.h> +#include <libelf.h> +#include <gelf.h> +#include <sys/mman.h> #endif #include <assert.h> #include <sys/ipc.h> @@ -412,7 +415,6 @@ prepare_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf64_t *dep) s = &dofs[dofrh->dofr_tgtsec]; for (j = 0; j < nrel; j++) { -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); #ifdef DOODAD #if defined(__arm__) /* XXX */ @@ -1519,14 +1521,29 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp) off = rela.r_offset - fsym.st_value; if (dt_modtext(dtp, data_tgt->d_buf, eprobe, - &rela, &off) != 0) { + &rela, &off) != 0) goto err; - } if (dt_probe_define(pvp, prp, s, r, off, eprobe) != 0) { return (dt_link_error(dtp, elf, fd, bufs, "failed to allocate space for probe")); } +#if !defined(sun) + /* + * Our linker doesn't understand the SUNW_IGNORE ndx and + * will try to use this relocation when we build the + * final executable. Since we are done processing this + * relocation, mark it as inexistant and let libelf + * remove it from the file. + * If this wasn't done, we would have garbage added to + * the executable file as the symbol is going to be + * change from UND to ABS. + */ + rela.r_offset = 0; + rela.r_info = 0; + rela.r_addend = 0; + (void) gelf_update_rela(data_rel, i, &rela); +#endif mod = 1; (void) elf_flagdata(data_tgt, ELF_C_SET, ELF_F_DIRTY); @@ -1538,13 +1555,13 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp) * already been processed by an earlier link * invocation. */ -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); -#ifdef DOODAD +#if !defined(sun) +#define SHN_SUNW_IGNORE SHN_ABS +#endif if (rsym.st_shndx != SHN_SUNW_IGNORE) { rsym.st_shndx = SHN_SUNW_IGNORE; (void) gelf_update_sym(data_sym, ndx, &rsym); } -#endif } } @@ -1554,6 +1571,9 @@ printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); (void) elf_end(elf); (void) close(fd); +#if !defined(sun) + if (nsym > 0) +#endif while ((pair = bufs) != NULL) { bufs = pair->dlp_next; dt_free(dtp, pair->dlp_str); @@ -1574,6 +1594,19 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, { #if !defined(sun) char tfile[PATH_MAX]; + Elf *e; + Elf_Scn *scn; + Elf_Data *data; + GElf_Shdr shdr; + int efd; + size_t stridx; + unsigned char *buf; + char *s; + int loc; + GElf_Ehdr ehdr; + Elf_Scn *scn0; + GElf_Shdr shdr0; + uint64_t off, rc; #endif char drti[PATH_MAX]; dof_hdr_t *dof; @@ -1583,6 +1616,18 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, int eprobes = 0, ret = 0; #if !defined(sun) + if (access(file, R_OK) == 0) { + fprintf(stderr, "dtrace: target object (%s) already exists. " + "Please remove the target\ndtrace: object and rebuild all " + "the source objects if you wish to run the DTrace\n" + "dtrace: linking process again\n", file); + /* + * Several build infrastructures run DTrace twice (e.g. + * postgres) and we don't want the build to fail. Return + * 0 here since this isn't really a fatal error. + */ + return (0); + } /* XXX Should get a temp file name here. */ snprintf(tfile, sizeof(tfile), "%s.tmp", file); #endif @@ -1697,12 +1742,17 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, (void) unlink(file); #endif +#if defined(sun) if (dtp->dt_oflags & DTRACE_O_LP64) status = dump_elf64(dtp, dof, fd); else status = dump_elf32(dtp, dof, fd); if (status != 0 || lseek(fd, 0, SEEK_SET) != 0) { +#else + /* We don't write the ELF header, just the DOF section */ + if (dt_write(dtp, fd, dof, dof->dofh_filesz) < dof->dofh_filesz) { +#endif return (dt_link_error(dtp, NULL, -1, NULL, "failed to write %s: %s", file, strerror(errno))); } @@ -1726,7 +1776,7 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, (void) snprintf(cmd, len, fmt, dtp->dt_ld_path, file, fd, drti); #else - const char *fmt = "%s -o %s -r %s %s"; + const char *fmt = "%s -o %s -r %s"; #if defined(__amd64__) /* @@ -1748,11 +1798,14 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, len = snprintf(&tmp, 1, fmt, dtp->dt_ld_path, file, tfile, drti) + 1; +#if !defined(sun) + len *= 2; +#endif cmd = alloca(len); - (void) snprintf(cmd, len, fmt, dtp->dt_ld_path, file, tfile, drti); + (void) snprintf(cmd, len, fmt, dtp->dt_ld_path, file, + drti); #endif - if ((status = system(cmd)) == -1) { ret = dt_link_error(dtp, NULL, -1, NULL, "failed to run %s: %s", dtp->dt_ld_path, @@ -1760,8 +1813,6 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, goto done; } - (void) close(fd); /* release temporary file */ - if (WIFSIGNALED(status)) { ret = dt_link_error(dtp, NULL, -1, NULL, "failed to link %s: %s failed due to signal %d", @@ -1775,6 +1826,138 @@ dtrace_program_link(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t dflags, file, dtp->dt_ld_path, WEXITSTATUS(status)); goto done; } +#if !defined(sun) +#define BROKEN_LIBELF + /* + * FreeBSD's ld(1) is not instructed to interpret and add + * correctly the SUNW_dof section present in tfile. + * We use libelf to add this section manually and hope the next + * ld invocation won't remove it. + */ + elf_version(EV_CURRENT); + if ((efd = open(file, O_RDWR, 0)) < 0) { + ret = dt_link_error(dtp, NULL, -1, NULL, + "failed to open file %s: %s", + file, strerror(errno)); + goto done; + } + if ((e = elf_begin(efd, ELF_C_RDWR, NULL)) == NULL) { + close(efd); + ret = dt_link_error(dtp, NULL, -1, NULL, + "failed to open elf file: %s", + elf_errmsg(elf_errno())); + goto done; + } + /* + * Add the string '.SUWN_dof' to the shstrtab section. + */ +#ifdef BROKEN_LIBELF + elf_flagelf(e, ELF_C_SET, ELF_F_LAYOUT); +#endif + elf_getshdrstrndx(e, &stridx); + scn = elf_getscn(e, stridx); + gelf_getshdr(scn, &shdr); + data = elf_newdata(scn); + data->d_off = shdr.sh_size; + data->d_buf = ".SUNW_dof"; + data->d_size = 10; + data->d_type = ELF_T_BYTE; + loc = shdr.sh_size; + shdr.sh_size += data->d_size; + gelf_update_shdr(scn, &shdr); +#ifdef BROKEN_LIBELF + off = shdr.sh_offset; + rc = shdr.sh_offset + shdr.sh_size; + gelf_getehdr(e, &ehdr); + if (ehdr.e_shoff > off) { + off = ehdr.e_shoff + ehdr.e_shnum * ehdr.e_shentsize; + rc = roundup(rc, 8); + ehdr.e_shoff = rc; + gelf_update_ehdr(e, &ehdr); + rc += ehdr.e_shnum * ehdr.e_shentsize; + } + for (;;) { + scn0 = NULL; + scn = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + gelf_getshdr(scn, &shdr); + if (shdr.sh_type == SHT_NOBITS || + shdr.sh_offset < off) + continue; + /* Find the immediately adjcent section. */ + if (scn0 == NULL || + shdr.sh_offset < shdr0.sh_offset) { + scn0 = scn; + gelf_getshdr(scn0, &shdr0); + } + } + if (scn0 == NULL) + break; + /* Load section data to work around another bug */ + elf_getdata(scn0, NULL); + /* Update section header, assure section alignment */ + off = shdr0.sh_offset + shdr0.sh_size; + rc = roundup(rc, shdr0.sh_addralign); + shdr0.sh_offset = rc; + gelf_update_shdr(scn0, &shdr0); + rc += shdr0.sh_size; + } + if (elf_update(e, ELF_C_WRITE) < 0) { + ret = dt_link_error(dtp, NULL, -1, NULL, + "failed to add append the shstrtab section: %s", + elf_errmsg(elf_errno())); + elf_end(e); + close(efd); + goto done; + } + elf_end(e); + e = elf_begin(efd, ELF_C_RDWR, NULL); +#endif + /* + * Construct the .SUNW_dof section. + */ + scn = elf_newscn(e); + data = elf_newdata(scn); + buf = mmap(NULL, dof->dofh_filesz, PROT_READ, MAP_SHARED, + fd, 0); + if (buf == MAP_FAILED) { + ret = dt_link_error(dtp, NULL, -1, NULL, + "failed to mmap buffer %s", strerror(errno)); + elf_end(e); + close(efd); + goto done; + } + data->d_buf = buf; + data->d_align = 4; + data->d_size = dof->dofh_filesz; + data->d_version = EV_CURRENT; + gelf_getshdr(scn, &shdr); + shdr.sh_name = loc; + shdr.sh_flags = SHF_ALLOC; + /* + * Actually this should be SHT_SUNW_dof, but FreeBSD's ld(1) + * will remove this 'unknown' section when we try to create an + * executable using the object we are modifying, so we stop + * playing by the rules and use SHT_PROGBITS. + * Also, note that our drti has modifications to handle this. + */ + shdr.sh_type = SHT_PROGBITS; + shdr.sh_addralign = 4; + gelf_update_shdr(scn, &shdr); + if (elf_update(e, ELF_C_WRITE) < 0) { + ret = dt_link_error(dtp, NULL, -1, NULL, + "failed to add the SUNW_dof section: %s", + elf_errmsg(elf_errno())); + munmap(buf, dof->dofh_filesz); + elf_end(e); + close(efd); + goto done; + } + munmap(buf, dof->dofh_filesz); + elf_end(e); + close(efd); +#endif + (void) close(fd); /* release temporary file */ } else { (void) close(fd); } diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c index d33fb95e499d..497faa995871 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_module.c @@ -18,13 +18,11 @@ * * CDDL HEADER END */ + /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #if defined(sun) #include <sys/modctl.h> @@ -77,6 +75,10 @@ dt_module_symhash_insert(dt_module_t *dmp, const char *name, uint_t id) static uint_t dt_module_syminit32(dt_module_t *dmp) { +#if STT_NUM != (STT_TLS + 1) +#error "STT_NUM has grown. update dt_module_syminit32()" +#endif + Elf32_Sym *sym = dmp->dm_symtab.cts_data; const char *base = dmp->dm_strtab.cts_data; size_t ss_size = dmp->dm_strtab.cts_size; @@ -123,6 +125,10 @@ dt_module_syminit32(dt_module_t *dmp) static uint_t dt_module_syminit64(dt_module_t *dmp) { +#if STT_NUM != (STT_TLS + 1) +#error "STT_NUM has grown. update dt_module_syminit64()" +#endif + Elf64_Sym *sym = dmp->dm_symtab.cts_data; const char *base = dmp->dm_strtab.cts_data; size_t ss_size = dmp->dm_strtab.cts_size; @@ -512,7 +518,7 @@ dt_module_load_sect(dtrace_hdl_t *dtp, dt_module_t *dmp, ctf_sect_t *ctsp) Elf_Data *dp; Elf_Scn *sp; - if (elf_getshstrndx(dmp->dm_elf, &shstrs) == 0) + if (elf_getshdrstrndx(dmp->dm_elf, &shstrs) == -1) return (dt_set_errno(dtp, EDT_NOTLOADED)); for (sp = NULL; (sp = elf_nextscn(dmp->dm_elf, sp)) != NULL; ) { @@ -778,10 +784,25 @@ dt_module_unload(dtrace_hdl_t *dtp, dt_module_t *dmp) void dt_module_destroy(dtrace_hdl_t *dtp, dt_module_t *dmp) { + uint_t h = dt_strtab_hash(dmp->dm_name, NULL) % dtp->dt_modbuckets; + dt_module_t **dmpp = &dtp->dt_mods[h]; + dt_list_delete(&dtp->dt_modlist, dmp); assert(dtp->dt_nmods != 0); dtp->dt_nmods--; + /* + * Now remove this module from its hash chain. We expect to always + * find the module on its hash chain, so in this loop we assert that + * we don't run off the end of the list. + */ + while (*dmpp != dmp) { + dmpp = &((*dmpp)->dm_next); + assert(*dmpp != NULL); + } + + *dmpp = dmp->dm_next; + dt_module_unload(dtp, dmp); free(dmp); } @@ -903,7 +924,7 @@ dt_module_update(dtrace_hdl_t *dtp, struct kld_file_stat *k_stat) (void) close(fd); if (dmp->dm_elf == NULL || err == -1 || - elf_getshstrndx(dmp->dm_elf, &shstrs) == 0) { + elf_getshdrstrndx(dmp->dm_elf, &shstrs) == -1) { dt_dprintf("failed to load %s: %s\n", fname, elf_errmsg(elf_errno())); dt_module_destroy(dtp, dmp); diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c index 483082268a31..962da1a884b9 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c @@ -20,12 +20,9 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #if defined(sun) #include <sys/modctl.h> @@ -116,8 +113,9 @@ #define DT_VERS_1_6 DT_VERSION_NUMBER(1, 6, 0) #define DT_VERS_1_6_1 DT_VERSION_NUMBER(1, 6, 1) #define DT_VERS_1_6_2 DT_VERSION_NUMBER(1, 6, 2) -#define DT_VERS_LATEST DT_VERS_1_6_2 -#define DT_VERS_STRING "Sun D 1.6.2" +#define DT_VERS_1_6_3 DT_VERSION_NUMBER(1, 6, 3) +#define DT_VERS_LATEST DT_VERS_1_6_3 +#define DT_VERS_STRING "Sun D 1.6.3" const dt_version_t _dtrace_versions[] = { DT_VERS_1_0, /* D API 1.0.0 (PSARC 2001/466) Solaris 10 FCS */ @@ -132,6 +130,7 @@ const dt_version_t _dtrace_versions[] = { DT_VERS_1_6, /* D API 1.6 */ DT_VERS_1_6_1, /* D API 1.6.1 */ DT_VERS_1_6_2, /* D API 1.6.2 */ + DT_VERS_1_6_3, /* D API 1.6.3 */ 0 }; @@ -284,10 +283,8 @@ static const dt_ident_t _dtrace_globals[] = { DT_VERS_1_5, &dt_idops_func, "string(int, void *)" }, { "ipl", DT_IDENT_SCALAR, 0, DIF_VAR_IPL, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "uint_t" }, -#if defined(sun) { "jstack", DT_IDENT_ACTFUNC, 0, DT_ACT_JSTACK, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_func, "stack(...)" }, -#endif { "lltostr", DT_IDENT_FUNC, 0, DIF_SUBR_LLTOSTR, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_func, "string(int64_t)" }, { "lquantize", DT_IDENT_AGGFUNC, 0, DTRACEAGG_LQUANTIZE, @@ -466,8 +463,10 @@ static const dt_ident_t _dtrace_globals[] = { #if defined(sun) { "uaddr", DT_IDENT_ACTFUNC, 0, DT_ACT_UADDR, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" }, +#endif { "ucaller", DT_IDENT_SCALAR, 0, DIF_VAR_UCALLER, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_type, "uint64_t" }, +#if defined(sun) { "ufunc", DT_IDENT_ACTFUNC, 0, DT_ACT_USYM, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" }, #endif @@ -476,6 +475,7 @@ static const dt_ident_t _dtrace_globals[] = { #if defined(sun) { "umod", DT_IDENT_ACTFUNC, 0, DT_ACT_UMOD, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" }, +#endif { "uregs", DT_IDENT_ARRAY, 0, DIF_VAR_UREGS, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_regs, NULL }, { "ustack", DT_IDENT_ACTFUNC, 0, DT_ACT_USTACK, DT_ATTR_STABCMN, DT_VERS_1_0, @@ -483,6 +483,7 @@ static const dt_ident_t _dtrace_globals[] = { { "ustackdepth", DT_IDENT_SCALAR, 0, DIF_VAR_USTACKDEPTH, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_type, "uint32_t" }, +#if defined(sun) { "usym", DT_IDENT_ACTFUNC, 0, DT_ACT_USYM, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" }, #endif @@ -761,9 +762,7 @@ int _dtrace_argmax = 32; /* default maximum number of probe arguments */ int _dtrace_debug = 0; /* debug messages enabled (off) */ const char *const _dtrace_version = DT_VERS_STRING; /* API version string */ -#if defined(sun) int _dtrace_rdvers = RD_VERSION; /* rtld_db feature version */ -#endif typedef struct dt_fdlist { int *df_fds; /* array of provider driver file descriptors */ @@ -781,12 +780,10 @@ _dtrace_init(void) { _dtrace_debug = getenv("DTRACE_DEBUG") != NULL; -#if defined(sun) for (; _dtrace_rdvers > 0; _dtrace_rdvers--) { if (rd_init(_dtrace_rdvers) == RD_OK) break; } -#endif #if defined(__i386__) /* make long doubles 64 bits -sson */ (void) fpsetprec(FP_PE); @@ -1103,7 +1100,11 @@ alloc: bzero(dtp, sizeof (dtrace_hdl_t)); dtp->dt_oflags = flags; +#if defined(sun) dtp->dt_prcmode = DT_PROC_STOP_PREINIT; +#else + dtp->dt_prcmode = DT_PROC_STOP_MAIN; +#endif dtp->dt_linkmode = DT_LINK_KERNEL; dtp->dt_linktype = DT_LTYP_ELF; dtp->dt_xlatemode = DT_XL_STATIC; diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c index 5640b4af053d..b145818db4d6 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_pid.c @@ -20,12 +20,10 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <assert.h> #include <strings.h> #include <stdlib.h> @@ -42,6 +40,9 @@ #include <dt_program.h> #include <dt_pid.h> #include <dt_string.h> +#if !defined(sun) +#include <libproc_compat.h> +#endif typedef struct dt_pid_probe { dtrace_hdl_t *dpp_dtp; @@ -144,7 +145,6 @@ dt_pid_per_sym(dt_pid_probe_t *pp, const GElf_Sym *symp, const char *func) pp->dpp_obj); if (!isdash && gmatch("return", pp->dpp_name)) { -#ifdef DOODAD if (dt_pid_create_return_probe(pp->dpp_pr, dtp, ftp, symp, pp->dpp_stret) < 0) { return (dt_pid_error(dtp, pcb, dpr, ftp, @@ -152,20 +152,17 @@ dt_pid_per_sym(dt_pid_probe_t *pp, const GElf_Sym *symp, const char *func) "for '%s': %s", func, dtrace_errmsg(dtp, dtrace_errno(dtp)))); } -#endif nmatches++; } if (!isdash && gmatch("entry", pp->dpp_name)) { -#ifdef DOODAD if (dt_pid_create_entry_probe(pp->dpp_pr, dtp, ftp, symp) < 0) { return (dt_pid_error(dtp, pcb, dpr, ftp, D_PROC_CREATEFAIL, "failed to create entry probe " "for '%s': %s", func, dtrace_errmsg(dtp, dtrace_errno(dtp)))); } -#endif nmatches++; } @@ -184,10 +181,8 @@ dt_pid_per_sym(dt_pid_probe_t *pp, const GElf_Sym *symp, const char *func) (u_longlong_t)off, func)); } -#ifdef DOODAD err = dt_pid_create_offset_probe(pp->dpp_pr, pp->dpp_dtp, ftp, symp, off); -#endif if (err == DT_PROC_ERR) { return (dt_pid_error(dtp, pcb, dpr, ftp, @@ -205,7 +200,6 @@ dt_pid_per_sym(dt_pid_probe_t *pp, const GElf_Sym *symp, const char *func) nmatches++; } else if (glob && !isdash) { -#ifdef DOODAD if (dt_pid_create_glob_offset_probes(pp->dpp_pr, pp->dpp_dtp, ftp, symp, pp->dpp_name) < 0) { return (dt_pid_error(dtp, pcb, dpr, ftp, @@ -213,7 +207,6 @@ dt_pid_per_sym(dt_pid_probe_t *pp, const GElf_Sym *symp, const char *func) "failed to create offset probes in '%s': %s", func, dtrace_errmsg(dtp, dtrace_errno(dtp)))); } -#endif nmatches++; } @@ -281,7 +274,6 @@ dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj) pp->dpp_obj = obj; else pp->dpp_obj++; - #if defined(sun) if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, ".stret1", &sym, NULL) == 0) @@ -307,25 +299,10 @@ dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj) else pp->dpp_stret[3] = 0; #else - if (proc_name2sym(pp->dpp_pr, obj, ".stret1", &sym) == 0) - pp->dpp_stret[0] = sym.st_value; - else - pp->dpp_stret[0] = 0; - - if (proc_name2sym(pp->dpp_pr, obj, ".stret2", &sym) == 0) - pp->dpp_stret[1] = sym.st_value; - else - pp->dpp_stret[1] = 0; - - if (proc_name2sym(pp->dpp_pr, obj, ".stret4", &sym) == 0) - pp->dpp_stret[2] = sym.st_value; - else - pp->dpp_stret[2] = 0; - - if (proc_name2sym(pp->dpp_pr, obj, ".stret8", &sym) == 0) - pp->dpp_stret[3] = sym.st_value; - else - pp->dpp_stret[3] = 0; + pp->dpp_stret[0] = 0; + pp->dpp_stret[1] = 0; + pp->dpp_stret[2] = 0; + pp->dpp_stret[3] = 0; #endif dt_dprintf("%s stret %llx %llx %llx %llx\n", obj, @@ -347,12 +324,8 @@ dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj) * just fail silently in the hopes that some other object will * contain the desired symbol. */ -#if defined(sun) if (Pxlookup_by_name(pp->dpp_pr, pp->dpp_lmid, obj, pp->dpp_func, &sym, NULL) != 0) { -#else - if (proc_name2sym(pp->dpp_pr, obj, pp->dpp_func, &sym) != 0) { -#endif if (strcmp("-", pp->dpp_func) == 0) { sym.st_name = 0; sym.st_info = @@ -392,16 +365,11 @@ dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj) return (0); #endif -#if defined(sun) (void) Plookup_by_addr(pp->dpp_pr, sym.st_value, pp->dpp_func, -#else - (void) proc_addr2sym(pp->dpp_pr, sym.st_value, pp->dpp_func, -#endif DTRACE_FUNCNAMELEN, &sym); return (dt_pid_per_sym(pp, &sym, pp->dpp_func)); } else { -#ifdef DOODAD uint_t nmatches = pp->dpp_nmatches; if (Psymbol_iter_by_addr(pp->dpp_pr, obj, PR_SYMTAB, @@ -417,7 +385,6 @@ dt_pid_per_mod(void *arg, const prmap_t *pmp, const char *obj) BIND_ANY | TYPE_FUNC, dt_pid_sym_filt, pp) == 1) return (1); } -#endif } return (0); @@ -443,7 +410,14 @@ dt_pid_mod_filt(void *arg, const prmap_t *pmp, const char *obj) else pp->dpp_obj++; - dt_pid_objname(name, sizeof (name), pp->dpp_lmid, obj); + if (gmatch(pp->dpp_obj, pp->dpp_mod)) + return (dt_pid_per_mod(pp, pmp, obj)); + +#if defined(sun) + (void) Plmid(pp->dpp_pr, pmp->pr_vaddr, &pp->dpp_lmid); +#endif + + dt_pid_objname(name, sizeof (name), pp->dpp_lmid, pp->dpp_obj); if (gmatch(name, pp->dpp_mod)) return (dt_pid_per_mod(pp, pmp, obj)); @@ -454,14 +428,16 @@ dt_pid_mod_filt(void *arg, const prmap_t *pmp, const char *obj) static const prmap_t * dt_pid_fix_mod(dtrace_probedesc_t *pdp, struct ps_prochandle *P) { -#ifdef DOODAD char m[MAXPATHLEN]; +#if defined(sun) Lmid_t lmid = PR_LMID_EVERY; - const char *obj; +#else + Lmid_t lmid = 0; #endif + const char *obj; const prmap_t *pmp; -#ifdef DOODAD +#if defined(sun) /* * Pick apart the link map from the library name. */ @@ -482,10 +458,14 @@ dt_pid_fix_mod(dtrace_probedesc_t *pdp, struct ps_prochandle *P) } else { obj = pdp->dtpd_mod; } +#else + obj = pdp->dtpd_mod; +#endif if ((pmp = Plmid_to_map(P, lmid, obj)) == NULL) return (NULL); +#if defined(sun) (void) Pobjname(P, pmp->pr_vaddr, m, sizeof (m)); if ((obj = strrchr(m, '/')) == NULL) obj = &m[0]; @@ -493,11 +473,9 @@ dt_pid_fix_mod(dtrace_probedesc_t *pdp, struct ps_prochandle *P) obj++; (void) Plmid(P, pmp->pr_vaddr, &lmid); +#endif dt_pid_objname(pdp->dtpd_mod, sizeof (pdp->dtpd_mod), lmid, obj); -#else -pmp = NULL; -#endif return (pmp); } @@ -539,13 +517,8 @@ dt_pid_create_pid_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, pp.dpp_mod = pdp->dtpd_mod; (void) strcpy(pdp->dtpd_mod, "a.out"); } else if (strisglob(pp.dpp_mod) || -#if defined(sun) (aout = Pname_to_map(pp.dpp_pr, "a.out")) == NULL || (pmp = Pname_to_map(pp.dpp_pr, pp.dpp_mod)) == NULL || -#else - (aout = proc_name2map(pp.dpp_pr, "a.out")) == NULL || - (pmp = proc_name2map(pp.dpp_pr, pp.dpp_mod)) == NULL || -#endif aout->pr_vaddr != pmp->pr_vaddr) { return (dt_pid_error(dtp, pcb, dpr, NULL, D_PROC_LIB, "only the a.out module is valid with the " @@ -564,7 +537,6 @@ dt_pid_create_pid_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, * to iterate over each module and compare its name against the * pattern. An empty module name is treated as '*'. */ -#ifdef DOODAD if (strisglob(pp.dpp_mod)) { ret = Pobject_iter(pp.dpp_pr, dt_pid_mod_filt, &pp); } else { @@ -585,7 +557,6 @@ dt_pid_create_pid_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, ret = dt_pid_per_mod(&pp, pmp, obj); } } -#endif return (ret); } @@ -611,12 +582,8 @@ dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname) * run the code to instantiate these providers. */ for (i = 0; i < 2; i++) { -#if defined(sun) if (Pxlookup_by_name(P, PR_LMID_EVERY, oname, syms[i], &sym, &sip) != 0) { -#else - if (proc_name2sym(P, oname, syms[i], &sym) != 0) { -#endif continue; } @@ -627,13 +594,11 @@ dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname) dt_dprintf("lookup of %s succeeded for %s\n", syms[i], mname); -#ifdef DOODAD if (Pread(P, &e_type, sizeof (e_type), pmp->pr_vaddr + offsetof(Elf64_Ehdr, e_type)) != sizeof (e_type)) { dt_dprintf("read of ELF header failed"); continue; } -#endif dh.dofhp_dof = sym.st_value; dh.dofhp_addr = (e_type == ET_EXEC) ? 0 : pmp->pr_vaddr; @@ -645,7 +610,7 @@ dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname) 0, mname); #endif -#ifdef DOODAD +#if defined(sun) if (fd == -1 && (fd = pr_open(P, "/dev/dtrace/helper", O_RDWR, 0)) < 0) { dt_dprintf("pr_open of helper device failed: %s\n", @@ -658,7 +623,7 @@ dt_pid_usdt_mapping(void *data, const prmap_t *pmp, const char *oname) #endif } -#ifdef DOODAD +#if defined(sun) if (fd != -1) (void) pr_close(P, fd); #endif @@ -674,8 +639,7 @@ dt_pid_create_usdt_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, int ret = 0; assert(DT_MUTEX_HELD(&dpr->dpr_lock)); - -#ifdef DOODAD +#if defined(sun) (void) Pupdate_maps(P); if (Pobject_iter(P, dt_pid_usdt_mapping, P) != 0) { ret = -1; @@ -687,6 +651,8 @@ dt_pid_create_usdt_probes(dtrace_probedesc_t *pdp, dtrace_hdl_t *dtp, (int)proc_getpid(P), strerror(errno)); #endif } +#else + ret = 0; #endif /* diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c index 8e45a91358ff..2619818b50b8 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_printf.c @@ -20,12 +20,9 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #if defined(sun) #include <sys/sysmacros.h> #else @@ -41,6 +38,11 @@ #include <ctype.h> #include <errno.h> #include <limits.h> +#include <sys/socket.h> +#include <netdb.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <arpa/nameser.h> #include <dt_printf.h> #include <dt_string.h> @@ -339,7 +341,7 @@ pfprint_addr(dtrace_hdl_t *dtp, FILE *fp, const char *format, do { n = len; s = alloca(n); - } while ((len = dtrace_addr2str(dtp, val, s, n)) >= n); + } while ((len = dtrace_addr2str(dtp, val, s, n)) > n); return (dt_printf(dtp, fp, format, s)); } @@ -392,7 +394,7 @@ pfprint_uaddr(dtrace_hdl_t *dtp, FILE *fp, const char *format, do { n = len; s = alloca(n); - } while ((len = dtrace_uaddr2str(dtp, pid, val, s, n)) >= n); + } while ((len = dtrace_uaddr2str(dtp, pid, val, s, n)) > n); return (dt_printf(dtp, fp, format, s)); } @@ -507,6 +509,58 @@ pfprint_time822(dtrace_hdl_t *dtp, FILE *fp, const char *format, /*ARGSUSED*/ static int +pfprint_port(dtrace_hdl_t *dtp, FILE *fp, const char *format, + const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal) +{ + uint16_t port = htons(*((uint16_t *)addr)); + char buf[256]; + struct servent *sv, res; + +#if defined(sun) + if ((sv = getservbyport_r(port, NULL, &res, buf, sizeof (buf))) != NULL) +#else + if (getservbyport_r(port, NULL, &res, buf, sizeof (buf), &sv) > 0) +#endif + return (dt_printf(dtp, fp, format, sv->s_name)); + + (void) snprintf(buf, sizeof (buf), "%d", *((uint16_t *)addr)); + return (dt_printf(dtp, fp, format, buf)); +} + +/*ARGSUSED*/ +static int +pfprint_inetaddr(dtrace_hdl_t *dtp, FILE *fp, const char *format, + const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal) +{ + char *s = alloca(size + 1); + struct hostent *host, res; + char inetaddr[NS_IN6ADDRSZ]; + char buf[1024]; + int e; + + bcopy(addr, s, size); + s[size] = '\0'; + + if (strchr(s, ':') == NULL && inet_pton(AF_INET, s, inetaddr) != -1) { +#if defined(sun) + if ((host = gethostbyaddr_r(inetaddr, NS_INADDRSZ, + AF_INET, &res, buf, sizeof (buf), &e)) != NULL) +#else + if (gethostbyaddr_r(inetaddr, NS_INADDRSZ, + AF_INET, &res, buf, sizeof (buf), &host, &e) > 0) +#endif + return (dt_printf(dtp, fp, format, host->h_name)); + } else if (inet_pton(AF_INET6, s, inetaddr) != -1) { + if ((host = getipnodebyaddr(inetaddr, NS_IN6ADDRSZ, + AF_INET6, &e)) != NULL) + return (dt_printf(dtp, fp, format, host->h_name)); + } + + return (dt_printf(dtp, fp, format, s)); +} + +/*ARGSUSED*/ +static int pfprint_cstr(dtrace_hdl_t *dtp, FILE *fp, const char *format, const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal) { @@ -610,6 +664,7 @@ static const dt_pfconv_t _dtrace_conversions[] = { { "hx", "x", "short", pfcheck_xshort, pfprint_uint }, { "hX", "X", "short", pfcheck_xshort, pfprint_uint }, { "i", "i", pfproto_xint, pfcheck_dint, pfprint_dint }, +{ "I", "s", pfproto_cstr, pfcheck_str, pfprint_inetaddr }, { "k", "s", "stack", pfcheck_stack, pfprint_stack }, { "lc", "lc", "int", pfcheck_type, pfprint_sint }, /* a.k.a. wint_t */ { "ld", "d", "long", pfcheck_type, pfprint_sint }, @@ -632,6 +687,7 @@ static const dt_pfconv_t _dtrace_conversions[] = { { "LG", "G", "long double", pfcheck_type, pfprint_fp }, { "o", "o", pfproto_xint, pfcheck_xint, pfprint_uint }, { "p", "x", pfproto_addr, pfcheck_addr, pfprint_uint }, +{ "P", "s", "uint16_t", pfcheck_type, pfprint_port }, { "s", "s", "char [] or string (or use stringof)", pfcheck_str, pfprint_cstr }, { "S", "s", pfproto_cstr, pfcheck_str, pfprint_estr }, { "T", "s", "int64_t", pfcheck_time, pfprint_time822 }, @@ -1238,6 +1294,20 @@ pfprint_average(dtrace_hdl_t *dtp, FILE *fp, const char *format, /*ARGSUSED*/ static int +pfprint_stddev(dtrace_hdl_t *dtp, FILE *fp, const char *format, + const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal) +{ + const uint64_t *data = addr; + + if (size != sizeof (uint64_t) * 4) + return (dt_set_errno(dtp, EDT_DMISMATCH)); + + return (dt_printf(dtp, fp, format, + dt_stddev((uint64_t *)data, normal))); +} + +/*ARGSUSED*/ +static int pfprint_quantize(dtrace_hdl_t *dtp, FILE *fp, const char *format, const dt_pfargd_t *pfd, const void *addr, size_t size, uint64_t normal) { @@ -1428,6 +1498,9 @@ dt_printf_format(dtrace_hdl_t *dtp, FILE *fp, const dt_pfargv_t *pfv, case DTRACEAGG_AVG: func = pfprint_average; break; + case DTRACEAGG_STDDEV: + func = pfprint_stddev; + break; case DTRACEAGG_QUANTIZE: func = pfprint_quantize; break; diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c index f420a0c2b3ca..664a1225b311 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.c @@ -20,12 +20,10 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * DTrace Process Control * @@ -91,11 +89,15 @@ #include <dt_pid.h> #include <dt_impl.h> -#define IS_SYS_EXEC(w) (w == SYS_exec || w == SYS_execve) -#define IS_SYS_FORK(w) (w == SYS_vfork || w == SYS_fork1 || \ - w == SYS_forkall || w == SYS_forksys) +#if !defined(sun) +#include <sys/syscall.h> +#include <libproc_compat.h> +#define SYS_forksys SYS_fork +#endif + +#define IS_SYS_EXEC(w) (w == SYS_execve) +#define IS_SYS_FORK(w) (w == SYS_vfork || w == SYS_forksys) -#ifdef DOODAD static dt_bkpt_t * dt_proc_bpcreate(dt_proc_t *dpr, uintptr_t addr, dt_bkpt_f *func, void *data) { @@ -117,53 +119,62 @@ dt_proc_bpcreate(dt_proc_t *dpr, uintptr_t addr, dt_bkpt_f *func, void *data) return (dbp); } -#endif static void dt_proc_bpdestroy(dt_proc_t *dpr, int delbkpts) { -#if defined(sun) int state = Pstate(dpr->dpr_proc); -#else - int state = proc_state(dpr->dpr_proc); -#endif dt_bkpt_t *dbp, *nbp; assert(DT_MUTEX_HELD(&dpr->dpr_lock)); for (dbp = dt_list_next(&dpr->dpr_bps); dbp != NULL; dbp = nbp) { -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); -#ifdef DOODAD if (delbkpts && dbp->dbp_active && state != PS_LOST && state != PS_UNDEAD) { (void) Pdelbkpt(dpr->dpr_proc, dbp->dbp_addr, dbp->dbp_instr); } -#endif nbp = dt_list_next(dbp); dt_list_delete(&dpr->dpr_bps, dbp); dt_free(dpr->dpr_hdl, dbp); } } -#ifdef DOODAD static void dt_proc_bpmatch(dtrace_hdl_t *dtp, dt_proc_t *dpr) { +#if defined(sun) const lwpstatus_t *psp = &Pstatus(dpr->dpr_proc)->pr_lwp; +#else + unsigned long pc; +#endif dt_bkpt_t *dbp; assert(DT_MUTEX_HELD(&dpr->dpr_lock)); +#if !defined(sun) + proc_regget(dpr->dpr_proc, REG_PC, &pc); + proc_bkptregadj(&pc); +#endif + for (dbp = dt_list_next(&dpr->dpr_bps); dbp != NULL; dbp = dt_list_next(dbp)) { +#if defined(sun) if (psp->pr_reg[R_PC] == dbp->dbp_addr) break; +#else + if (pc == dbp->dbp_addr) + break; +#endif } if (dbp == NULL) { dt_dprintf("pid %d: spurious breakpoint wakeup for %lx\n", +#if defined(sun) (int)dpr->dpr_pid, (ulong_t)psp->pr_reg[R_PC]); +#else + (int)dpr->dpr_pid, pc); +#endif return; } @@ -173,7 +184,6 @@ dt_proc_bpmatch(dtrace_hdl_t *dtp, dt_proc_t *dpr) dbp->dbp_func(dtp, dpr, dbp->dbp_data); (void) Pxecbkpt(dpr->dpr_proc, dbp->dbp_instr); } -#endif static void dt_proc_bpenable(dt_proc_t *dpr) @@ -184,12 +194,9 @@ dt_proc_bpenable(dt_proc_t *dpr) for (dbp = dt_list_next(&dpr->dpr_bps); dbp != NULL; dbp = dt_list_next(dbp)) { -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); -#ifdef DOODAD if (!dbp->dbp_active && Psetbkpt(dpr->dpr_proc, dbp->dbp_addr, &dbp->dbp_instr) == 0) dbp->dbp_active = B_TRUE; -#endif } dt_dprintf("breakpoints enabled\n"); @@ -204,12 +211,9 @@ dt_proc_bpdisable(dt_proc_t *dpr) for (dbp = dt_list_next(&dpr->dpr_bps); dbp != NULL; dbp = dt_list_next(dbp)) { -printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); -#ifdef DOODAD if (dbp->dbp_active && Pdelbkpt(dpr->dpr_proc, dbp->dbp_addr, dbp->dbp_instr) == 0) dbp->dbp_active = B_FALSE; -#endif } dt_dprintf("breakpoints disabled\n"); @@ -282,7 +286,6 @@ dt_proc_bpmain(dtrace_hdl_t *dtp, dt_proc_t *dpr, const char *fname) dt_proc_stop(dpr, DT_PROC_STOP_MAIN); } -#if defined(sun) static void dt_proc_rdevent(dtrace_hdl_t *dtp, dt_proc_t *dpr, const char *evname) { @@ -339,7 +342,12 @@ dt_proc_rdwatch(dt_proc_t *dpr, rd_event_e event, const char *evname) } (void) dt_proc_bpcreate(dpr, rdn.u.bptaddr, +#if defined(sun) (dt_bkpt_f *)dt_proc_rdevent, (void *)evname); +#else + /* XXX ugly */ + (dt_bkpt_f *)dt_proc_rdevent, __DECONST(void *, evname)); +#endif } /* @@ -349,25 +357,34 @@ dt_proc_rdwatch(dt_proc_t *dpr, rd_event_e event, const char *evname) static void dt_proc_attach(dt_proc_t *dpr, int exec) { +#if defined(sun) const pstatus_t *psp = Pstatus(dpr->dpr_proc); +#endif rd_err_e err; GElf_Sym sym; assert(DT_MUTEX_HELD(&dpr->dpr_lock)); if (exec) { +#if defined(sun) if (psp->pr_lwp.pr_errno != 0) return; /* exec failed: nothing needs to be done */ +#endif dt_proc_bpdestroy(dpr, B_FALSE); +#if defined(sun) Preset_maps(dpr->dpr_proc); +#endif } - if ((dpr->dpr_rtld = Prd_agent(dpr->dpr_proc)) != NULL && (err = rd_event_enable(dpr->dpr_rtld, B_TRUE)) == RD_OK) { +#if defined(sun) dt_proc_rdwatch(dpr, RD_PREINIT, "RD_PREINIT"); +#endif dt_proc_rdwatch(dpr, RD_POSTINIT, "RD_POSTINIT"); +#if defined(sun) dt_proc_rdwatch(dpr, RD_DLACTIVITY, "RD_DLACTIVITY"); +#endif } else { dt_dprintf("pid %d: failed to enable rtld events: %s\n", (int)dpr->dpr_pid, dpr->dpr_rtld ? rd_errstr(err) : @@ -409,6 +426,8 @@ dt_proc_attach(dt_proc_t *dpr, int exec) static void dt_proc_waitrun(dt_proc_t *dpr) { +printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__); +#ifdef DOODAD struct ps_prochandle *P = dpr->dpr_proc; const lwpstatus_t *psp = &Pstatus(P)->pr_lwp; @@ -458,8 +477,8 @@ dt_proc_waitrun(dt_proc_t *dpr) } (void) pthread_mutex_lock(&dpr->dpr_lock); -} #endif +} typedef struct dt_proc_control_data { dtrace_hdl_t *dpcd_hdl; /* DTrace handle */ @@ -522,7 +541,6 @@ dt_proc_control(void *arg) * We must trace exit from exec() system calls so that if the exec is * successful, we can reset our breakpoints and re-initialize libproc. */ - (void) Psysexit(P, SYS_exec, B_TRUE); (void) Psysexit(P, SYS_execve, B_TRUE); /* @@ -533,43 +551,30 @@ dt_proc_control(void *arg) */ (void) Psysentry(P, SYS_vfork, B_TRUE); (void) Psysexit(P, SYS_vfork, B_TRUE); - (void) Psysentry(P, SYS_fork1, B_TRUE); - (void) Psysexit(P, SYS_fork1, B_TRUE); - (void) Psysentry(P, SYS_forkall, B_TRUE); - (void) Psysexit(P, SYS_forkall, B_TRUE); (void) Psysentry(P, SYS_forksys, B_TRUE); (void) Psysexit(P, SYS_forksys, B_TRUE); Psync(P); /* enable all /proc changes */ +#endif dt_proc_attach(dpr, B_FALSE); /* enable rtld breakpoints */ /* * If PR_KLC is set, we created the process; otherwise we grabbed it. * Check for an appropriate stop request and wait for dt_proc_continue. */ +#if defined(sun) if (Pstatus(P)->pr_flags & PR_KLC) - dt_proc_stop(dpr, DT_PROC_STOP_CREATE); - else - dt_proc_stop(dpr, DT_PROC_STOP_GRAB); - - if (Psetrun(P, 0, 0) == -1) { - dt_dprintf("pid %d: failed to set running: %s\n", - (int)dpr->dpr_pid, strerror(errno)); - } #else - /* - * If PR_KLC is set, we created the process; otherwise we grabbed it. - * Check for an appropriate stop request and wait for dt_proc_continue. - */ if (proc_getflags(P) & PR_KLC) +#endif dt_proc_stop(dpr, DT_PROC_STOP_CREATE); else dt_proc_stop(dpr, DT_PROC_STOP_GRAB); - if (proc_continue(P) != 0) + if (Psetrun(P, 0, 0) == -1) { dt_dprintf("pid %d: failed to set running: %s\n", (int)dpr->dpr_pid, strerror(errno)); -#endif + } (void) pthread_mutex_unlock(&dpr->dpr_lock); @@ -583,14 +588,16 @@ dt_proc_control(void *arg) * Pwait() (which will return immediately) and do our processing. */ while (!dpr->dpr_quit) { -#if defined(sun) const lwpstatus_t *psp; +#if defined(sun) if (write(pfd, &wstop, sizeof (wstop)) == -1 && errno == EINTR) continue; /* check dpr_quit and continue waiting */ #else /* Wait for the process to report status. */ - proc_wait(P); + proc_wstatus(P); + if (errno == EINTR) + continue; /* check dpr_quit and continue waiting */ #endif (void) pthread_mutex_lock(&dpr->dpr_lock); @@ -603,14 +610,13 @@ pwait_locked: } #endif -#if defined(sun) switch (Pstate(P)) { -#else - switch (proc_state(P)) { -#endif case PS_STOP: -#ifdef DOODAD +#if defined(sun) psp = &Pstatus(P)->pr_lwp; +#else + psp = proc_getlwpstatus(P); +#endif dt_dprintf("pid %d: proc stopped showing %d/%d\n", pid, psp->pr_why, psp->pr_what); @@ -652,7 +658,6 @@ pwait_locked: else if (psp->pr_why == PR_SYSEXIT && IS_SYS_EXEC(psp->pr_what)) dt_proc_attach(dpr, B_TRUE); -#endif break; case PS_LOST: @@ -675,12 +680,10 @@ pwait_locked: break; } -#if defined(sun) if (Pstate(P) != PS_UNDEAD && Psetrun(P, 0, 0) == -1) { dt_dprintf("pid %d: failed to set running: %s\n", (int)dpr->dpr_pid, strerror(errno)); } -#endif (void) pthread_mutex_unlock(&dpr->dpr_lock); } @@ -720,11 +723,7 @@ dt_proc_error(dtrace_hdl_t *dtp, dt_proc_t *dpr, const char *format, ...) va_end(ap); if (dpr->dpr_proc != NULL) -#if defined(sun) Prelease(dpr->dpr_proc, 0); -#else - proc_detach(dpr->dpr_proc); -#endif dt_free(dtp, dpr); (void) dt_set_errno(dtp, EDT_COMPILER); @@ -779,14 +778,17 @@ dt_proc_destroy(dtrace_hdl_t *dtp, struct ps_prochandle *P) if (!(proc_getflags(dpr->dpr_proc) & (PR_KLC | PR_RLC))) { #endif dt_dprintf("abandoning pid %d\n", (int)dpr->dpr_pid); -#if defined(sun) rflag = PRELEASE_HANG; +#if defined(sun) + } else if (Pstatus(dpr->dpr_proc)->pr_flags & PR_KLC) { #else - rflag = 0 /* XXX */; + } else if (proc_getflags(dpr->dpr_proc) & PR_KLC) { #endif + dt_dprintf("killing pid %d\n", (int)dpr->dpr_pid); + rflag = PRELEASE_KILL; /* apply kill-on-last-close */ } else { dt_dprintf("releasing pid %d\n", (int)dpr->dpr_pid); - rflag = 0; /* apply kill or run-on-last-close */ + rflag = 0; /* apply run-on-last-close */ } if (dpr->dpr_tid) { @@ -809,7 +811,7 @@ dt_proc_destroy(dtrace_hdl_t *dtp, struct ps_prochandle *P) #if defined(sun) (void) _lwp_kill(dpr->dpr_tid, SIGCANCEL); #else - (void) pthread_kill(dpr->dpr_tid, SIGUSR1); + pthread_kill(dpr->dpr_tid, SIGUSR1); #endif /* @@ -858,11 +860,7 @@ dt_proc_destroy(dtrace_hdl_t *dtp, struct ps_prochandle *P) } dt_list_delete(&dph->dph_lrulist, dpr); -#if defined(sun) Prelease(dpr->dpr_proc, rflag); -#else - proc_detach(dpr->dpr_proc); -#endif dt_free(dtp, dpr); } @@ -917,18 +915,15 @@ dt_proc_create_thread(dtrace_hdl_t *dtp, dt_proc_t *dpr, uint_t stop) #if defined(sun) const psinfo_t *prp = Ppsinfo(dpr->dpr_proc); int stat = prp ? prp->pr_wstat : 0; -#endif int pid = dpr->dpr_pid; - -#if defined(sun) - if (Pstate(dpr->dpr_proc) == PS_LOST) { #else - if (proc_state(dpr->dpr_proc) == PS_LOST) { + int stat = proc_getwstat(dpr->dpr_proc); + int pid = proc_getpid(dpr->dpr_proc); #endif + if (proc_state(dpr->dpr_proc) == PS_LOST) { (void) dt_proc_error(dpr->dpr_hdl, dpr, "failed to control pid %d: process exec'd " "set-id or unobservable program\n", pid); -#if defined(sun) } else if (WIFSIGNALED(stat)) { (void) dt_proc_error(dpr->dpr_hdl, dpr, "failed to control pid %d: process died " @@ -937,7 +932,6 @@ dt_proc_create_thread(dtrace_hdl_t *dtp, dt_proc_t *dpr, uint_t stop) (void) dt_proc_error(dpr->dpr_hdl, dpr, "failed to control pid %d: process exited " "with status %d\n", pid, WEXITSTATUS(stat)); -#endif } err = ESRCH; /* cause grab() or create() to fail */ @@ -970,30 +964,25 @@ dt_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv, #if defined(sun) if ((dpr->dpr_proc = Pcreate(file, argv, &err, NULL, 0)) == NULL) { +#else + if ((err = proc_create(file, argv, pcf, child_arg, + &dpr->dpr_proc)) != 0) { +#endif return (dt_proc_error(dtp, dpr, "failed to execute %s: %s\n", file, Pcreate_error(err))); } dpr->dpr_hdl = dtp; +#if defined(sun) dpr->dpr_pid = Pstatus(dpr->dpr_proc)->pr_pid; - - (void) Punsetflags(dpr->dpr_proc, PR_RLC); - (void) Psetflags(dpr->dpr_proc, PR_KLC); #else - (void) proc_clearflags(dpr->dpr_proc, PR_RLC); - (void) proc_setflags(dpr->dpr_proc, PR_KLC); - if ((err = proc_create(file, argv, pcf, child_arg, &dpr->dpr_proc)) != 0) - return (dt_proc_error(dtp, dpr, - "failed to execute %s: %s\n", file, strerror(err))); - dpr->dpr_hdl = dtp; dpr->dpr_pid = proc_getpid(dpr->dpr_proc); #endif -#if defined(sun) + (void) Punsetflags(dpr->dpr_proc, PR_RLC); + (void) Psetflags(dpr->dpr_proc, PR_KLC); + if (dt_proc_create_thread(dtp, dpr, dtp->dt_prcmode) != 0) -#else - if (dt_proc_create_thread(dtp, dpr, DT_PROC_STOP_IDLE) != 0) -#endif return (NULL); /* dt_proc_error() has been called for us */ dpr->dpr_hash = dph->dph_hash[dpr->dpr_pid & (dph->dph_hashlen - 1)]; @@ -1051,25 +1040,18 @@ dt_proc_grab(dtrace_hdl_t *dtp, pid_t pid, int flags, int nomonitor) #if defined(sun) if ((dpr->dpr_proc = Pgrab(pid, flags, &err)) == NULL) { +#else + if ((err = proc_attach(pid, flags, &dpr->dpr_proc)) != 0) { +#endif return (dt_proc_error(dtp, dpr, "failed to grab pid %d: %s\n", (int)pid, Pgrab_error(err))); } -#else - if ((err = proc_attach(pid, flags, &dpr->dpr_proc)) != 0) - return (dt_proc_error(dtp, dpr, - "failed to grab pid %d: %s\n", (int) pid, strerror(err))); -#endif dpr->dpr_hdl = dtp; dpr->dpr_pid = pid; -#if defined(sun) (void) Punsetflags(dpr->dpr_proc, PR_KLC); (void) Psetflags(dpr->dpr_proc, PR_RLC); -#else - (void) proc_clearflags(dpr->dpr_proc, PR_KLC); - (void) proc_setflags(dpr->dpr_proc, PR_RLC); -#endif /* * If we are attempting to grab the process without a monitor @@ -1190,12 +1172,13 @@ dtrace_proc_create(dtrace_hdl_t *dtp, const char *file, char *const *argv, dt_ident_t *idp = dt_idhash_lookup(dtp->dt_macros, "target"); struct ps_prochandle *P = dt_proc_create(dtp, file, argv, pcf, child_arg); - if (P != NULL && idp != NULL && idp->di_id == 0) + if (P != NULL && idp != NULL && idp->di_id == 0) { #if defined(sun) idp->di_id = Pstatus(P)->pr_pid; /* $target = created pid */ #else idp->di_id = proc_getpid(P); /* $target = created pid */ #endif + } return (P); } diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.h index b469f55b847d..d1fc7652385d 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.h +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_proc.h @@ -44,9 +44,7 @@ typedef struct dt_proc { dtrace_hdl_t *dpr_hdl; /* back pointer to libdtrace handle */ struct ps_prochandle *dpr_proc; /* proc handle for libproc calls */ char dpr_errmsg[BUFSIZ]; /* error message */ -#if defined(sun) rd_agent_t *dpr_rtld; /* rtld handle for librtld_db calls */ -#endif pthread_mutex_t dpr_lock; /* lock for manipulating dpr_hdl */ pthread_cond_t dpr_cv; /* cond for dpr_stop/quit/done */ pid_t dpr_pid; /* pid of process */ diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_program.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_program.c index e4fa8011f66b..b110df396718 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_program.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_program.c @@ -20,12 +20,9 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <unistd.h> #include <strings.h> #include <stdlib.h> @@ -46,10 +43,12 @@ dt_program_create(dtrace_hdl_t *dtp) { dtrace_prog_t *pgp = dt_zalloc(dtp, sizeof (dtrace_prog_t)); - if (pgp != NULL) + if (pgp != NULL) { dt_list_append(&dtp->dt_programs, pgp); - else + } else { (void) dt_set_errno(dtp, EDT_NOMEM); + return (NULL); + } /* * By default, programs start with DOF version 1 so that output files @@ -178,6 +177,9 @@ dtrace_program_exec(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, case E2BIG: err = EDT_DIFSIZE; break; + case EBUSY: + err = EDT_ENABLING_ERR; + break; default: err = errno; } @@ -555,6 +557,10 @@ dt_header_provider(dtrace_hdl_t *dtp, dt_provider_t *pvp, FILE *out) info.dthi_pfname = alloca(strlen(pvp->pv_desc.dtvd_name) + 1 + i); dt_header_fmt_func(info.dthi_pfname, pvp->pv_desc.dtvd_name); +#ifdef __FreeBSD__ + if (fprintf(out, "#include <sys/sdt.h>\n\n") < 0) + return (dt_set_errno(dtp, errno)); +#endif if (fprintf(out, "#if _DTRACE_VERSION\n\n") < 0) return (dt_set_errno(dtp, errno)); diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_string.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_string.c index 02fa50720370..3a5315eef99a 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_string.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_string.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,19 +18,18 @@ * * CDDL HEADER END */ + /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <strings.h> #include <stdlib.h> #include <errno.h> #include <ctype.h> #include <dt_string.h> +#include <dt_impl.h> /* * Create a copy of string s, but only duplicate the first n bytes. @@ -41,6 +39,9 @@ strndup(const char *s, size_t n) { char *s2 = malloc(n + 1); + if (s2 == NULL) + longjmp(yypcb->pcb_jmpbuf, EDT_NOMEM); + (void) strncpy(s2, s, n); s2[n] = '\0'; return (s2); diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c index 12f186ae51fd..f4eadbc4f13f 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,13 +18,12 @@ * * CDDL HEADER END */ + /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #if defined(sun) #include <sys/sysmacros.h> #endif @@ -42,6 +40,7 @@ #include <alloca.h> #else #include <sys/sysctl.h> +#include <libproc_compat.h> #endif #include <assert.h> #include <libgen.h> @@ -63,8 +62,8 @@ int dtrace_xstr2desc(dtrace_hdl_t *dtp, dtrace_probespec_t spec, const char *s, int argc, char *const argv[], dtrace_probedesc_t *pdp) { - size_t off, len, vlen; - const char *p, *q, *v; + size_t off, len, vlen, wlen; + const char *p, *q, *v, *w; char buf[32]; /* for id_t as %d (see below) */ @@ -80,6 +79,8 @@ dtrace_xstr2desc(dtrace_hdl_t *dtp, dtrace_probespec_t spec, q = p + 1; vlen = 0; + w = NULL; + wlen = 0; if ((v = strchr(q, '$')) != NULL && v < q + len) { /* @@ -104,14 +105,14 @@ dtrace_xstr2desc(dtrace_hdl_t *dtp, dtrace_probespec_t spec, } if (isdigit(v[1])) { - char *end; long i; errno = 0; - i = strtol(v + 1, &end, 10); + i = strtol(v + 1, (char **)&w, 10); + + wlen = vlen - (w - v); - if (i < 0 || i >= argc || - errno != 0 || end != v + vlen) + if (i < 0 || i >= argc || errno != 0) return (dt_set_errno(dtp, EDT_BADSPCV)); v = argv[i]; @@ -147,7 +148,7 @@ dtrace_xstr2desc(dtrace_hdl_t *dtp, dtrace_probespec_t spec, off = dtrace_probespecs[spec--].dtps_offset; bcopy(q, (char *)pdp + off, len); bcopy(v, (char *)pdp + off + len, vlen); - + bcopy(w, (char *)pdp + off + len + vlen, wlen); } while (--p >= s); pdp->dtpd_id = DTRACE_IDNONE; @@ -963,13 +964,8 @@ dtrace_uaddr2str(dtrace_hdl_t *dtp, pid_t pid, dt_proc_lock(dtp, P); -#if defined(sun) if (Plookup_by_addr(P, addr, name, sizeof (name), &sym) == 0) { (void) Pobjname(P, addr, objname, sizeof (objname)); -#else - if (proc_addr2sym(P, addr, name, sizeof (name), &sym) == 0) { - (void) proc_objname(P, addr, objname, sizeof (objname)); -#endif obj = dt_basename(objname); @@ -979,11 +975,7 @@ dtrace_uaddr2str(dtrace_hdl_t *dtp, pid_t pid, } else { (void) snprintf(c, sizeof (c), "%s`%s", obj, name); } -#if defined(sun) } else if (Pobjname(P, addr, objname, sizeof (objname)) != 0) { -#else - } else if (proc_objname(P, addr, objname, sizeof (objname)) != 0) { -#endif (void) snprintf(c, sizeof (c), "%s`0x%llx", dt_basename(objname), addr); } else { diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h index 00b32eebf07a..13c27765bd4b 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h @@ -34,6 +34,9 @@ #include <stdio.h> #include <gelf.h> #include <libproc.h> +#if !defined(sun) +#include <rtld_db.h> +#endif #ifdef __cplusplus extern "C" { diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrno.sh b/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrno.sh new file mode 100755 index 000000000000..50b7f1c1b908 --- /dev/null +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrno.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2003 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" + +echo "\ +/*\n\ + * Copyright 2003 Sun Microsystems, Inc. All rights reserved.\n\ + * Use is subject to license terms.\n\ + */\n\ +\n\ +#pragma ident\t\"%Z%%M%\t%I%\t%E% SMI\"\n" + +pattern='^#define[ ]\(E[A-Z0-9]*\)[ ]*\([A-Z0-9]*\).*$' +replace='inline int \1 = \2;@#pragma D binding "1.0" \1' + +sed -n "s/$pattern/$replace/p" | tr '@' '\n' diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/mksignal.sh b/cddl/contrib/opensolaris/lib/libdtrace/common/mksignal.sh new file mode 100755 index 000000000000..1bffa6468c2b --- /dev/null +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/mksignal.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2003 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" + +echo "\ +/*\n\ + * Copyright 2003 Sun Microsystems, Inc. All rights reserved.\n\ + * Use is subject to license terms.\n\ + */\n\ +\n\ +#pragma ident\t\"%Z%%M%\t%I%\t%E% SMI\"\n" + +pattern='^#define[ ]*_*\(SIG[A-Z0-9]*\)[ ]\{1,\}\([A-Z0-9]*\).*$' +replace='inline int \1 = \2;@#pragma D binding "1.0" \1' + +sed -n "s/$pattern/$replace/p;/SIGRTMAX/q" | tr '@' '\n' diff --git a/cddl/contrib/opensolaris/lib/libdtrace/i386/dt_isadep.c b/cddl/contrib/opensolaris/lib/libdtrace/i386/dt_isadep.c new file mode 100644 index 000000000000..ad1c0324de6a --- /dev/null +++ b/cddl/contrib/opensolaris/lib/libdtrace/i386/dt_isadep.c @@ -0,0 +1,532 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <stdlib.h> +#include <assert.h> +#include <errno.h> +#include <string.h> +#include <libgen.h> + +#include <dt_impl.h> +#include <dt_pid.h> + +#include <dis_tables.h> + +#if !defined(sun) +#define PR_MODEL_ILP32 1 +#define PR_MODEL_LP64 2 +#include <libproc_compat.h> +#endif + +#define DT_POPL_EBP 0x5d +#define DT_RET 0xc3 +#define DT_RET16 0xc2 +#define DT_LEAVE 0xc9 +#define DT_JMP32 0xe9 +#define DT_JMP8 0xeb +#define DT_REP 0xf3 + +#define DT_MOVL_EBP_ESP 0xe58b + +#define DT_ISJ32(op16) (((op16) & 0xfff0) == 0x0f80) +#define DT_ISJ8(op8) (((op8) & 0xf0) == 0x70) + +#define DT_MODRM_REG(modrm) (((modrm) >> 3) & 0x7) + +static int dt_instr_size(uchar_t *, dtrace_hdl_t *, pid_t, uintptr_t, char); + +/*ARGSUSED*/ +int +dt_pid_create_entry_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp, + fasttrap_probe_spec_t *ftp, const GElf_Sym *symp) +{ + ftp->ftps_type = DTFTP_ENTRY; + ftp->ftps_pc = (uintptr_t)symp->st_value; + ftp->ftps_size = (size_t)symp->st_size; + ftp->ftps_noffs = 1; + ftp->ftps_offs[0] = 0; + + if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) { + dt_dprintf("fasttrap probe creation ioctl failed: %s\n", + strerror(errno)); + return (dt_set_errno(dtp, errno)); + } + + return (1); +} + +static int +dt_pid_has_jump_table(struct ps_prochandle *P, dtrace_hdl_t *dtp, + uint8_t *text, fasttrap_probe_spec_t *ftp, const GElf_Sym *symp) +{ + ulong_t i; + int size; +#if defined(sun) + pid_t pid = Pstatus(P)->pr_pid; + char dmodel = Pstatus(P)->pr_dmodel; +#else + pid_t pid = proc_getpid(P); +#if __i386__ + char dmodel = PR_MODEL_ILP32; +#elif __amd64__ + char dmodel = PR_MODEL_LP64; +#endif +#endif + + /* + * Take a pass through the function looking for a register-dependant + * jmp instruction. This could be a jump table so we have to be + * ultra conservative. + */ + for (i = 0; i < ftp->ftps_size; i += size) { + size = dt_instr_size(&text[i], dtp, pid, symp->st_value + i, + dmodel); + + /* + * Assume the worst if we hit an illegal instruction. + */ + if (size <= 0) { + dt_dprintf("error at %#lx (assuming jump table)\n", i); + return (1); + } + +#ifdef notyet + /* + * Register-dependant jmp instructions start with a 0xff byte + * and have the modrm.reg field set to 4. They can have an + * optional REX prefix on the 64-bit ISA. + */ + if ((text[i] == 0xff && DT_MODRM_REG(text[i + 1]) == 4) || + (dmodel == PR_MODEL_LP64 && (text[i] & 0xf0) == 0x40 && + text[i + 1] == 0xff && DT_MODRM_REG(text[i + 2]) == 4)) { + dt_dprintf("found a suspected jump table at %s:%lx\n", + ftp->ftps_func, i); + return (1); + } +#endif + } + + return (0); +} + +/*ARGSUSED*/ +int +dt_pid_create_return_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp, + fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, uint64_t *stret) +{ + uint8_t *text; + ulong_t i, end; + int size; +#if defined(sun) + pid_t pid = Pstatus(P)->pr_pid; + char dmodel = Pstatus(P)->pr_dmodel; +#else + pid_t pid = proc_getpid(P); +#if __i386__ + char dmodel = PR_MODEL_ILP32; +#elif __amd64__ + char dmodel = PR_MODEL_LP64; +#endif +#endif + + /* + * We allocate a few extra bytes at the end so we don't have to check + * for overrunning the buffer. + */ + if ((text = calloc(1, symp->st_size + 4)) == NULL) { + dt_dprintf("mr sparkle: malloc() failed\n"); + return (DT_PROC_ERR); + } + + if (Pread(P, text, symp->st_size, symp->st_value) != symp->st_size) { + dt_dprintf("mr sparkle: Pread() failed\n"); + free(text); + return (DT_PROC_ERR); + } + + ftp->ftps_type = DTFTP_RETURN; + ftp->ftps_pc = (uintptr_t)symp->st_value; + ftp->ftps_size = (size_t)symp->st_size; + ftp->ftps_noffs = 0; + + /* + * If there's a jump table in the function we're only willing to + * instrument these specific (and equivalent) instruction sequences: + * leave + * [rep] ret + * and + * movl %ebp,%esp + * popl %ebp + * [rep] ret + * + * We do this to avoid accidentally interpreting jump table + * offsets as actual instructions. + */ + if (dt_pid_has_jump_table(P, dtp, text, ftp, symp)) { + for (i = 0, end = ftp->ftps_size; i < end; i += size) { + size = dt_instr_size(&text[i], dtp, pid, + symp->st_value + i, dmodel); + + /* bail if we hit an invalid opcode */ + if (size <= 0) + break; + + if (text[i] == DT_LEAVE && text[i + 1] == DT_RET) { + dt_dprintf("leave/ret at %lx\n", i + 1); + ftp->ftps_offs[ftp->ftps_noffs++] = i + 1; + size = 2; + } else if (text[i] == DT_LEAVE && + text[i + 1] == DT_REP && text[i + 2] == DT_RET) { + dt_dprintf("leave/rep ret at %lx\n", i + 1); + ftp->ftps_offs[ftp->ftps_noffs++] = i + 1; + size = 3; + } else if (*(uint16_t *)&text[i] == DT_MOVL_EBP_ESP && + text[i + 2] == DT_POPL_EBP && + text[i + 3] == DT_RET) { + dt_dprintf("movl/popl/ret at %lx\n", i + 3); + ftp->ftps_offs[ftp->ftps_noffs++] = i + 3; + size = 4; + } else if (*(uint16_t *)&text[i] == DT_MOVL_EBP_ESP && + text[i + 2] == DT_POPL_EBP && + text[i + 3] == DT_REP && + text[i + 4] == DT_RET) { + dt_dprintf("movl/popl/rep ret at %lx\n", i + 3); + ftp->ftps_offs[ftp->ftps_noffs++] = i + 3; + size = 5; + } + } + } else { + for (i = 0, end = ftp->ftps_size; i < end; i += size) { + size = dt_instr_size(&text[i], dtp, pid, + symp->st_value + i, dmodel); + + /* bail if we hit an invalid opcode */ + if (size <= 0) + break; + + /* ordinary ret */ + if (size == 1 && text[i] == DT_RET) + goto is_ret; + + /* two-byte ret */ + if (size == 2 && text[i] == DT_REP && + text[i + 1] == DT_RET) + goto is_ret; + + /* ret <imm16> */ + if (size == 3 && text[i] == DT_RET16) + goto is_ret; + + /* two-byte ret <imm16> */ + if (size == 4 && text[i] == DT_REP && + text[i + 1] == DT_RET16) + goto is_ret; + + /* 32-bit displacement jmp outside of the function */ + if (size == 5 && text[i] == DT_JMP32 && symp->st_size <= + (uintptr_t)(i + size + *(int32_t *)&text[i + 1])) + goto is_ret; + + /* 8-bit displacement jmp outside of the function */ + if (size == 2 && text[i] == DT_JMP8 && symp->st_size <= + (uintptr_t)(i + size + *(int8_t *)&text[i + 1])) + goto is_ret; + + /* 32-bit disp. conditional jmp outside of the func. */ + if (size == 6 && DT_ISJ32(*(uint16_t *)&text[i]) && + symp->st_size <= + (uintptr_t)(i + size + *(int32_t *)&text[i + 2])) + goto is_ret; + + /* 8-bit disp. conditional jmp outside of the func. */ + if (size == 2 && DT_ISJ8(text[i]) && symp->st_size <= + (uintptr_t)(i + size + *(int8_t *)&text[i + 1])) + goto is_ret; + + continue; +is_ret: + dt_dprintf("return at offset %lx\n", i); + ftp->ftps_offs[ftp->ftps_noffs++] = i; + } + } + + free(text); + if (ftp->ftps_noffs > 0) { + if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) { + dt_dprintf("fasttrap probe creation ioctl failed: %s\n", + strerror(errno)); + return (dt_set_errno(dtp, errno)); + } + } + + return (ftp->ftps_noffs); +} + +/*ARGSUSED*/ +int +dt_pid_create_offset_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp, + fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, ulong_t off) +{ + ftp->ftps_type = DTFTP_OFFSETS; + ftp->ftps_pc = (uintptr_t)symp->st_value; + ftp->ftps_size = (size_t)symp->st_size; + ftp->ftps_noffs = 1; + + if (strcmp("-", ftp->ftps_func) == 0) { + ftp->ftps_offs[0] = off; + } else { + uint8_t *text; + ulong_t i; + int size; +#if defined(sun) + pid_t pid = Pstatus(P)->pr_pid; + char dmodel = Pstatus(P)->pr_dmodel; +#else + pid_t pid = proc_getpid(P); +#if __i386__ + char dmodel = PR_MODEL_ILP32; +#elif __amd64__ + char dmodel = PR_MODEL_LP64; +#endif +#endif + + if ((text = malloc(symp->st_size)) == NULL) { + dt_dprintf("mr sparkle: malloc() failed\n"); + return (DT_PROC_ERR); + } + + if (Pread(P, text, symp->st_size, symp->st_value) != + symp->st_size) { + dt_dprintf("mr sparkle: Pread() failed\n"); + free(text); + return (DT_PROC_ERR); + } + + /* + * We can't instrument offsets in functions with jump tables + * as we might interpret a jump table offset as an + * instruction. + */ + if (dt_pid_has_jump_table(P, dtp, text, ftp, symp)) { + free(text); + return (0); + } + + for (i = 0; i < symp->st_size; i += size) { + if (i == off) { + ftp->ftps_offs[0] = i; + break; + } + + /* + * If we've passed the desired offset without a + * match, then the given offset must not lie on a + * instruction boundary. + */ + if (i > off) { + free(text); + return (DT_PROC_ALIGN); + } + + size = dt_instr_size(&text[i], dtp, pid, + symp->st_value + i, dmodel); + + /* + * If we hit an invalid instruction, bail as if we + * couldn't find the offset. + */ + if (size <= 0) { + free(text); + return (DT_PROC_ALIGN); + } + } + + free(text); + } + + if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) { + dt_dprintf("fasttrap probe creation ioctl failed: %s\n", + strerror(errno)); + return (dt_set_errno(dtp, errno)); + } + + return (ftp->ftps_noffs); +} + +/*ARGSUSED*/ +int +dt_pid_create_glob_offset_probes(struct ps_prochandle *P, dtrace_hdl_t *dtp, + fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, const char *pattern) +{ + uint8_t *text; + int size; + ulong_t i, end = symp->st_size; +#if defined(sun) + pid_t pid = Pstatus(P)->pr_pid; + char dmodel = Pstatus(P)->pr_dmodel; +#else + pid_t pid = proc_getpid(P); +#if __i386__ + char dmodel = PR_MODEL_ILP32; +#elif __amd64__ + char dmodel = PR_MODEL_LP64; +#endif +#endif + + ftp->ftps_type = DTFTP_OFFSETS; + ftp->ftps_pc = (uintptr_t)symp->st_value; + ftp->ftps_size = (size_t)symp->st_size; + ftp->ftps_noffs = 0; + + if ((text = malloc(symp->st_size)) == NULL) { + dt_dprintf("mr sparkle: malloc() failed\n"); + return (DT_PROC_ERR); + } + + if (Pread(P, text, symp->st_size, symp->st_value) != symp->st_size) { + dt_dprintf("mr sparkle: Pread() failed\n"); + free(text); + return (DT_PROC_ERR); + } + + /* + * We can't instrument offsets in functions with jump tables as + * we might interpret a jump table offset as an instruction. + */ + if (dt_pid_has_jump_table(P, dtp, text, ftp, symp)) { + free(text); + return (0); + } + + if (strcmp("*", pattern) == 0) { + for (i = 0; i < end; i += size) { + ftp->ftps_offs[ftp->ftps_noffs++] = i; + + size = dt_instr_size(&text[i], dtp, pid, + symp->st_value + i, dmodel); + + /* bail if we hit an invalid opcode */ + if (size <= 0) + break; + } + } else { + char name[sizeof (i) * 2 + 1]; + + for (i = 0; i < end; i += size) { + (void) snprintf(name, sizeof (name), "%x", i); + if (gmatch(name, pattern)) + ftp->ftps_offs[ftp->ftps_noffs++] = i; + + size = dt_instr_size(&text[i], dtp, pid, + symp->st_value + i, dmodel); + + /* bail if we hit an invalid opcode */ + if (size <= 0) + break; + } + } + + free(text); + if (ftp->ftps_noffs > 0) { + if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) { + dt_dprintf("fasttrap probe creation ioctl failed: %s\n", + strerror(errno)); + return (dt_set_errno(dtp, errno)); + } + } + + return (ftp->ftps_noffs); +} + +typedef struct dtrace_dis { + uchar_t *instr; + dtrace_hdl_t *dtp; + pid_t pid; + uintptr_t addr; +} dtrace_dis_t; + +static int +dt_getbyte(void *data) +{ + dtrace_dis_t *dis = data; + int ret = *dis->instr; + + if (ret == FASTTRAP_INSTR) { + fasttrap_instr_query_t instr; + + instr.ftiq_pid = dis->pid; + instr.ftiq_pc = dis->addr; + + /* + * If we hit a byte that looks like the fasttrap provider's + * trap instruction (which doubles as the breakpoint + * instruction for debuggers) we need to query the kernel + * for the real value. This may just be part of an immediate + * value so there's no need to return an error if the + * kernel doesn't know about this address. + */ + if (ioctl(dis->dtp->dt_ftfd, FASTTRAPIOC_GETINSTR, &instr) == 0) + ret = instr.ftiq_instr; + } + + dis->addr++; + dis->instr++; + + return (ret); +} + +static int +dt_instr_size(uchar_t *instr, dtrace_hdl_t *dtp, pid_t pid, uintptr_t addr, + char dmodel) +{ + dtrace_dis_t data; + dis86_t x86dis; + uint_t cpu_mode; + + data.instr = instr; + data.dtp = dtp; + data.pid = pid; + data.addr = addr; + + x86dis.d86_data = &data; + x86dis.d86_get_byte = dt_getbyte; + x86dis.d86_check_func = NULL; + + cpu_mode = (dmodel == PR_MODEL_ILP32) ? SIZE32 : SIZE64; + + if (dtrace_disx86(&x86dis, cpu_mode) != 0) + return (-1); + + /* + * If the instruction was a single-byte breakpoint, there may be + * another debugger attached to this process. The original instruction + * can't be recovered so this must fail. + */ + if (x86dis.d86_len == 1 && instr[0] == FASTTRAP_INSTR) + return (-1); + + return (x86dis.d86_len); +} diff --git a/cddl/contrib/opensolaris/lib/libdtrace/i386/regs.d.in b/cddl/contrib/opensolaris/lib/libdtrace/i386/regs.d.in new file mode 100644 index 000000000000..3328f33515b0 --- /dev/null +++ b/cddl/contrib/opensolaris/lib/libdtrace/i386/regs.d.in @@ -0,0 +1,117 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +inline int R_GS = @GS@; +#pragma D binding "1.0" R_GS +inline int R_FS = @FS@; +#pragma D binding "1.0" R_FS +inline int R_ES = @ES@; +#pragma D binding "1.0" R_ES +inline int R_DS = @DS@; +#pragma D binding "1.0" R_DS + +inline int R_EDI = @EDI@; +#pragma D binding "1.0" R_EDI +inline int R_ESI = @ESI@; +#pragma D binding "1.0" R_ESI +inline int R_EBP = @EBP@; +#pragma D binding "1.0" R_EBP +inline int R_ESP = @ESP@; +#pragma D binding "1.0" R_ESP +inline int R_EBX = @EBX@; +#pragma D binding "1.0" R_EBX +inline int R_EDX = @EDX@; +#pragma D binding "1.0" R_EDX +inline int R_ECX = @ECX@; +#pragma D binding "1.0" R_ECX +inline int R_EAX = @EAX@; +#pragma D binding "1.0" R_EAX + +inline int R_TRAPNO = @TRAPNO@; +#pragma D binding "1.0" R_TRAPNO +inline int R_ERR = @ERR@; +#pragma D binding "1.0" R_ERR +inline int R_EIP = @EIP@; +#pragma D binding "1.0" R_EIP +inline int R_CS = @CS@; +#pragma D binding "1.0" R_CS +inline int R_EFL = @EFL@; +#pragma D binding "1.0" R_EFL +inline int R_UESP = @UESP@; +#pragma D binding "1.0" R_UESP +inline int R_SS = @SS@; +#pragma D binding "1.0" R_SS + +inline int R_PC = R_EIP; +#pragma D binding "1.0" R_PC +inline int R_SP = R_UESP; +#pragma D binding "1.0" R_SP +inline int R_PS = R_EFL; +#pragma D binding "1.0" R_PS +inline int R_R0 = R_EAX; +#pragma D binding "1.0" R_R0 +inline int R_R1 = R_EBX; +#pragma D binding "1.0" R_R1 + +inline int R_RSP = @REG_RSP@; +#pragma D binding "1.0" R_RSP +inline int R_RFL = @REG_RFL@; +#pragma D binding "1.0" R_RFL +inline int R_RIP = @REG_RIP@; +#pragma D binding "1.0" R_RIP +inline int R_RAX = @REG_RAX@; +#pragma D binding "1.0" R_RAX +inline int R_RCX = @REG_RCX@; +#pragma D binding "1.0" R_RCX +inline int R_RDX = @REG_RDX@; +#pragma D binding "1.0" R_RDX +inline int R_RBX = @REG_RBX@; +#pragma D binding "1.0" R_RBX +inline int R_RBP = @REG_RBP@; +#pragma D binding "1.0" R_RBP +inline int R_RSI = @REG_RSI@; +#pragma D binding "1.0" R_RSI +inline int R_RDI = @REG_RDI@; +#pragma D binding "1.0" R_RDI +inline int R_R8 = @REG_R8@; +#pragma D binding "1.0" R_R8 +inline int R_R9 = @REG_R9@; +#pragma D binding "1.0" R_R9 +inline int R_R10 = @REG_R10@; +#pragma D binding "1.0" R_R10 +inline int R_R11 = @REG_R11@; +#pragma D binding "1.0" R_R11 +inline int R_R12 = @REG_R12@; +#pragma D binding "1.0" R_R12 +inline int R_R13 = @REG_R13@; +#pragma D binding "1.0" R_R13 +inline int R_R14 = @REG_R14@; +#pragma D binding "1.0" R_R14 +inline int R_R15 = @REG_R15@; +#pragma D binding "1.0" R_R15 + diff --git a/cddl/contrib/opensolaris/lib/libdtrace/i386/regs.sed.in b/cddl/contrib/opensolaris/lib/libdtrace/i386/regs.sed.in new file mode 100644 index 000000000000..2b2080fc9d03 --- /dev/null +++ b/cddl/contrib/opensolaris/lib/libdtrace/i386/regs.sed.in @@ -0,0 +1,82 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * This file is a sed script which is first preprocessed by cpp or cc -E to + * define a set of sed directives which replace #define tokens with their + * values. After preprocessing, whitespace is eliminated, and any @ symbols + * are translated into single space. The resulting sed script is then run + * over regs.d.in to replace the #define tokens listed below to create the + * finished regs.d. Refer to the rules in libdtrace/i386/Makefile for more + * information. + */ + +#include <sys/regset.h> + +#define SED_REPLACE(x) s/#x/x/g +#define SED_REPLACE64(x) s/#x/SS @+@1@+@ x/g + +SED_REPLACE(GS) +SED_REPLACE(FS) +SED_REPLACE(ES) +SED_REPLACE(DS) +SED_REPLACE(EDI) +SED_REPLACE(ESI) +SED_REPLACE(EBP) +SED_REPLACE(ESP) +SED_REPLACE(EBX) +SED_REPLACE(EDX) +SED_REPLACE(ECX) +SED_REPLACE(EAX) +SED_REPLACE(TRAPNO) +SED_REPLACE(ERR) +SED_REPLACE(EIP) +SED_REPLACE(CS) +SED_REPLACE(EFL) +SED_REPLACE(UESP) +SED_REPLACE(SS) + +SED_REPLACE64(REG_RSP) +SED_REPLACE64(REG_RFL) +SED_REPLACE64(REG_RIP) +SED_REPLACE64(REG_RAX) +SED_REPLACE64(REG_RCX) +SED_REPLACE64(REG_RDX) +SED_REPLACE64(REG_RBX) +SED_REPLACE64(REG_RBP) +SED_REPLACE64(REG_RSI) +SED_REPLACE64(REG_RDI) +SED_REPLACE64(REG_R8) +SED_REPLACE64(REG_R9) +SED_REPLACE64(REG_R10) +SED_REPLACE64(REG_R11) +SED_REPLACE64(REG_R12) +SED_REPLACE64(REG_R13) +SED_REPLACE64(REG_R14) +SED_REPLACE64(REG_R15) + diff --git a/cddl/contrib/opensolaris/lib/libdtrace/sparc/dt_isadep.c b/cddl/contrib/opensolaris/lib/libdtrace/sparc/dt_isadep.c new file mode 100644 index 000000000000..ed05275e7f83 --- /dev/null +++ b/cddl/contrib/opensolaris/lib/libdtrace/sparc/dt_isadep.c @@ -0,0 +1,338 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdlib.h> +#include <assert.h> +#include <errno.h> +#include <string.h> +#include <libgen.h> + +#include <dt_impl.h> +#include <dt_pid.h> + +#define OP(x) ((x) >> 30) +#define OP2(x) (((x) >> 22) & 0x07) +#define COND(x) (((x) >> 25) & 0x0f) +#define A(x) (((x) >> 29) & 0x01) + +#define OP_BRANCH 0 + +#define OP2_BPcc 0x1 +#define OP2_Bicc 0x2 +#define OP2_BPr 0x3 +#define OP2_FBPfcc 0x5 +#define OP2_FBfcc 0x6 + +/*ARGSUSED*/ +int +dt_pid_create_entry_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp, + fasttrap_probe_spec_t *ftp, const GElf_Sym *symp) +{ + ftp->ftps_type = DTFTP_ENTRY; + ftp->ftps_pc = (uintptr_t)symp->st_value; + ftp->ftps_size = (size_t)symp->st_size; + ftp->ftps_noffs = 1; + ftp->ftps_offs[0] = 0; + + if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) { + dt_dprintf("fasttrap probe creation ioctl failed: %s\n", + strerror(errno)); + return (dt_set_errno(dtp, errno)); + } + + return (1); +} + +int +dt_pid_create_return_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp, + fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, uint64_t *stret) +{ + + uint32_t *text; + int i; + int srdepth = 0; + + if ((text = malloc(symp->st_size + 4)) == NULL) { + dt_dprintf("mr sparkle: malloc() failed\n"); + return (DT_PROC_ERR); + } + + if (Pread(P, text, symp->st_size, symp->st_value) != symp->st_size) { + dt_dprintf("mr sparkle: Pread() failed\n"); + free(text); + return (DT_PROC_ERR); + } + + /* + * Leave a dummy instruction in the last slot to simplify edge + * conditions. + */ + text[symp->st_size / 4] = 0; + + ftp->ftps_type = DTFTP_RETURN; + ftp->ftps_pc = symp->st_value; + ftp->ftps_size = symp->st_size; + ftp->ftps_noffs = 0; + + for (i = 0; i < symp->st_size / 4; i++) { + /* + * If we encounter an existing tracepoint, query the + * kernel to find out the instruction that was + * replaced at this spot. + */ + while (text[i] == FASTTRAP_INSTR) { + fasttrap_instr_query_t instr; + + instr.ftiq_pid = Pstatus(P)->pr_pid; + instr.ftiq_pc = symp->st_value + i * 4; + + if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_GETINSTR, + &instr) != 0) { + + if (errno == ESRCH || errno == ENOENT) { + if (Pread(P, &text[i], 4, + instr.ftiq_pc) != 4) { + dt_dprintf("mr sparkle: " + "Pread() failed\n"); + free(text); + return (DT_PROC_ERR); + } + continue; + } + + free(text); + dt_dprintf("mr sparkle: getinstr query " + "failed: %s\n", strerror(errno)); + return (DT_PROC_ERR); + } + + text[i] = instr.ftiq_instr; + break; + } + + /* save */ + if ((text[i] & 0xc1f80000) == 0x81e00000) { + srdepth++; + continue; + } + + /* restore */ + if ((text[i] & 0xc1f80000) == 0x81e80000) { + srdepth--; + continue; + } + + if (srdepth > 0) { + /* ret */ + if (text[i] == 0x81c7e008) + goto is_ret; + + /* return */ + if (text[i] == 0x81cfe008) + goto is_ret; + + /* call or jmpl w/ restore in the slot */ + if (((text[i] & 0xc0000000) == 0x40000000 || + (text[i] & 0xc1f80000) == 0x81c00000) && + (text[i + 1] & 0xc1f80000) == 0x81e80000) + goto is_ret; + + /* call to one of the stret routines */ + if ((text[i] & 0xc0000000) == 0x40000000) { + int32_t disp = text[i] << 2; + uint64_t dest = ftp->ftps_pc + i * 4 + disp; + + dt_dprintf("dest = %llx\n", (u_longlong_t)dest); + + if (dest == stret[0] || dest == stret[1] || + dest == stret[2] || dest == stret[3]) + goto is_ret; + } + } else { + /* external call */ + if ((text[i] & 0xc0000000) == 0x40000000) { + int32_t dst = text[i] << 2; + + dst += i * 4; + + if ((uintptr_t)dst >= (uintptr_t)symp->st_size) + goto is_ret; + } + + /* jmpl into %g0 -- this includes the retl pseudo op */ + if ((text[i] & 0xfff80000) == 0x81c00000) + goto is_ret; + + /* external branch -- possible return site */ + if (OP(text[i]) == OP_BRANCH) { + int32_t dst; + int baa; + + switch (OP2(text[i])) { + case OP2_BPcc: + dst = text[i] & 0x7ffff; + dst <<= 13; + dst >>= 11; + + baa = COND(text[i]) == 8 && A(text[i]); + break; + case OP2_Bicc: + dst = text[i] & 0x3fffff; + dst <<= 10; + dst >>= 8; + + baa = COND(text[i]) == 8 && A(text[i]); + break; + case OP2_BPr: + dst = (((text[i]) >> 6) & 0xc000) | + ((text[i]) & 0x3fff); + dst <<= 16; + dst >>= 14; + + baa = 0; + break; + case OP2_FBPfcc: + dst = text[i] & 0x7ffff; + dst <<= 13; + dst >>= 11; + + baa = COND(text[i]) == 8 && A(text[i]); + break; + case OP2_FBfcc: + dst = text[i] & 0x3fffff; + dst <<= 10; + dst >>= 8; + + baa = COND(text[i]) == 8 && A(text[i]); + break; + default: + continue; + } + + dst += i * 4; + + /* + * Interpret branches outside of the function's + * bounds as potential return sites. If the + * branch is a ba,a don't skip the instruction + * in the delay slot. + */ + if ((uintptr_t)dst >= + (uintptr_t)symp->st_size) { + if (baa) + goto is_ret_baa; + else + goto is_ret; + } + } + } + + continue; +is_ret: + i++; +is_ret_baa: + dt_dprintf("return at offset %x\n", i * 4); + ftp->ftps_offs[ftp->ftps_noffs++] = i * 4; + } + + free(text); + if (ftp->ftps_noffs > 0) { + if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) { + dt_dprintf("fasttrap probe creation ioctl failed: %s\n", + strerror(errno)); + return (dt_set_errno(dtp, errno)); + } + } + + + return (ftp->ftps_noffs); +} + +/*ARGSUSED*/ +int +dt_pid_create_offset_probe(struct ps_prochandle *P, dtrace_hdl_t *dtp, + fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, ulong_t off) +{ + if (off & 0x3) + return (DT_PROC_ALIGN); + + ftp->ftps_type = DTFTP_OFFSETS; + ftp->ftps_pc = (uintptr_t)symp->st_value; + ftp->ftps_size = (size_t)symp->st_size; + ftp->ftps_noffs = 1; + ftp->ftps_offs[0] = off; + + if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) { + dt_dprintf("fasttrap probe creation ioctl failed: %s\n", + strerror(errno)); + return (dt_set_errno(dtp, errno)); + } + + return (1); +} + +/*ARGSUSED*/ +int +dt_pid_create_glob_offset_probes(struct ps_prochandle *P, dtrace_hdl_t *dtp, + fasttrap_probe_spec_t *ftp, const GElf_Sym *symp, const char *pattern) +{ + ulong_t i; + + ftp->ftps_type = DTFTP_OFFSETS; + ftp->ftps_pc = (uintptr_t)symp->st_value; + ftp->ftps_size = (size_t)symp->st_size; + ftp->ftps_noffs = 0; + + /* + * If we're matching against everything, just iterate through each + * instruction in the function, otherwise look for matching offset + * names by constructing the string and comparing it against the + * pattern. + */ + if (strcmp("*", pattern) == 0) { + for (i = 0; i < symp->st_size; i += 4) { + ftp->ftps_offs[ftp->ftps_noffs++] = i; + } + } else { + char name[sizeof (i) * 2 + 1]; + + for (i = 0; i < symp->st_size; i += 4) { + (void) sprintf(name, "%lx", i); + if (gmatch(name, pattern)) + ftp->ftps_offs[ftp->ftps_noffs++] = i; + } + } + + if (ioctl(dtp->dt_ftfd, FASTTRAPIOC_MAKEPROBE, ftp) != 0) { + dt_dprintf("fasttrap probe creation ioctl failed: %s\n", + strerror(errno)); + return (dt_set_errno(dtp, errno)); + } + + return (ftp->ftps_noffs); +} diff --git a/cddl/contrib/opensolaris/lib/libdtrace/sparc/regs.d b/cddl/contrib/opensolaris/lib/libdtrace/sparc/regs.d new file mode 100644 index 000000000000..7c4bc0fac519 --- /dev/null +++ b/cddl/contrib/opensolaris/lib/libdtrace/sparc/regs.d @@ -0,0 +1,120 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +inline int R_G0 = 0; +#pragma D binding "1.0" R_G0 +inline int R_G1 = 1; +#pragma D binding "1.0" R_G1 +inline int R_G2 = 2; +#pragma D binding "1.0" R_G2 +inline int R_G3 = 3; +#pragma D binding "1.0" R_G3 +inline int R_G4 = 4; +#pragma D binding "1.0" R_G4 +inline int R_G5 = 5; +#pragma D binding "1.0" R_G5 +inline int R_G6 = 6; +#pragma D binding "1.0" R_G6 +inline int R_G7 = 7; +#pragma D binding "1.0" R_G7 + +inline int R_O0 = 8; +#pragma D binding "1.0" R_O0 +inline int R_O1 = 9; +#pragma D binding "1.0" R_O1 +inline int R_O2 = 10; +#pragma D binding "1.0" R_O2 +inline int R_O3 = 11; +#pragma D binding "1.0" R_O3 +inline int R_O4 = 12; +#pragma D binding "1.0" R_O4 +inline int R_O5 = 13; +#pragma D binding "1.0" R_O5 +inline int R_O6 = 14; +#pragma D binding "1.0" R_O6 +inline int R_O7 = 15; +#pragma D binding "1.0" R_O7 + +inline int R_L0 = 16; +#pragma D binding "1.0" R_L0 +inline int R_L1 = 17; +#pragma D binding "1.0" R_L1 +inline int R_L2 = 18; +#pragma D binding "1.0" R_L2 +inline int R_L3 = 19; +#pragma D binding "1.0" R_L3 +inline int R_L4 = 20; +#pragma D binding "1.0" R_L4 +inline int R_L5 = 21; +#pragma D binding "1.0" R_L5 +inline int R_L6 = 22; +#pragma D binding "1.0" R_L6 +inline int R_L7 = 23; +#pragma D binding "1.0" R_L7 + +inline int R_I0 = 24; +#pragma D binding "1.0" R_I0 +inline int R_I1 = 25; +#pragma D binding "1.0" R_I1 +inline int R_I2 = 26; +#pragma D binding "1.0" R_I2 +inline int R_I3 = 27; +#pragma D binding "1.0" R_I3 +inline int R_I4 = 28; +#pragma D binding "1.0" R_I4 +inline int R_I5 = 29; +#pragma D binding "1.0" R_I5 +inline int R_I6 = 30; +#pragma D binding "1.0" R_I6 +inline int R_I7 = 31; +#pragma D binding "1.0" R_I7 + +inline int R_CCR = 32; +#pragma D binding "1.0" R_CCR +inline int R_PC = 33; +#pragma D binding "1.0" R_PC +inline int R_nPC = 34; +#pragma D binding "1.0" R_nPC +inline int R_NPC = R_nPC; +#pragma D binding "1.0" R_NPC +inline int R_Y = 35; +#pragma D binding "1.0" R_Y +inline int R_ASI = 36; +#pragma D binding "1.0" R_ASI +inline int R_FPRS = 37; +#pragma D binding "1.0" R_FPRS +inline int R_PS = R_CCR; +#pragma D binding "1.0" R_PS +inline int R_SP = R_O6; +#pragma D binding "1.0" R_SP +inline int R_FP = R_I6; +#pragma D binding "1.0" R_FP +inline int R_R0 = R_O0; +#pragma D binding "1.0" R_R0 +inline int R_R1 = R_O1; +#pragma D binding "1.0" R_R1 diff --git a/cddl/contrib/opensolaris/lib/libgen/common/gmatch.c b/cddl/contrib/opensolaris/lib/libgen/common/gmatch.c index cfd66e862657..fe4a3825a7a6 100644 --- a/cddl/contrib/opensolaris/lib/libgen/common/gmatch.c +++ b/cddl/contrib/opensolaris/lib/libgen/common/gmatch.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,23 +19,19 @@ * CDDL HEADER END */ -/* Copyright (c) 1988 AT&T */ -/* All Rights Reserved */ - /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.1.5.2 */ +/* Copyright (c) 1988 AT&T */ +/* All Rights Reserved */ -/*LINTLIBRARY*/ +#pragma ident "%Z%%M% %I% %E% SMI" #if defined(sun) #pragma weak gmatch = _gmatch -#endif -#if defined(sun) #include "gen_synonyms.h" #endif #include <sys/types.h> @@ -60,7 +55,7 @@ c = cl; \ if (n <= 0) \ return (0); \ - p += n; + p += n int gmatch(const char *s, const char *p) @@ -101,13 +96,13 @@ gmatch(const char *s, const char *p) notflag = 1; p++; } - Popwchar(p, c) + Popwchar(p, c); do { if (c == '-' && lc && *p != ']') { - Popwchar(p, c) + Popwchar(p, c); if (c == '\\') { - Popwchar(p, c) + Popwchar(p, c); } if (notflag) { if (!multibyte || @@ -126,7 +121,7 @@ gmatch(const char *s, const char *p) } } else if (c == '\\') { /* skip to quoted character */ - Popwchar(p, c) + Popwchar(p, c); } lc = c; if (notflag) { @@ -140,14 +135,14 @@ gmatch(const char *s, const char *p) if (scc == lc) ok++; } - Popwchar(p, c) + Popwchar(p, c); } while (c != ']'); return (ok ? gmatch(s, p) : 0); } case '\\': /* skip to quoted character and see if it matches */ - Popwchar(p, c) + Popwchar(p, c); default: if (c != scc) diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c b/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c index d95dd1db1653..e3ec1e1bf0cf 100644 --- a/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c +++ b/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Create and parse buffers containing CTF data. */ @@ -174,6 +172,12 @@ write_functions(iidesc_t *idp, ctf_buf_t *b) } nargs = idp->ii_nargs + (idp->ii_vargs != 0); + + if (nargs > CTF_MAX_VLEN) { + terminate("function %s has too many args: %d > %d\n", + idp->ii_name, nargs, CTF_MAX_VLEN); + } + fdata[0] = CTF_TYPE_INFO(CTF_K_FUNCTION, 1, nargs); fdata[1] = idp->ii_dtype->t_id; ctf_buf_write(b, fdata, sizeof (fdata)); @@ -316,6 +320,11 @@ write_type(void *arg1, void *arg2) for (i = 0, mp = tp->t_members; mp != NULL; mp = mp->ml_next) i++; /* count up struct or union members */ + if (i > CTF_MAX_VLEN) { + terminate("sou %s has too many members: %d > %d\n", + tdesc_name(tp), i, CTF_MAX_VLEN); + } + if (tp->t_type == STRUCT) ctt.ctt_info = CTF_TYPE_INFO(CTF_K_STRUCT, isroot, i); else @@ -398,8 +407,14 @@ write_type(void *arg1, void *arg2) break; case FUNCTION: - ctt.ctt_info = CTF_TYPE_INFO(CTF_K_FUNCTION, isroot, - tp->t_fndef->fn_nargs + tp->t_fndef->fn_vargs); + i = tp->t_fndef->fn_nargs + tp->t_fndef->fn_vargs; + + if (i > CTF_MAX_VLEN) { + terminate("function %s has too many args: %d > %d\n", + i, CTF_MAX_VLEN); + } + + ctt.ctt_info = CTF_TYPE_INFO(CTF_K_FUNCTION, isroot, i); ctt.ctt_type = tp->t_fndef->fn_ret->t_id; write_unsized_type_rec(b, &ctt); @@ -938,7 +953,7 @@ resurrect_types(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize, if (CTF_NAME_STID(ctt->ctt_name) != CTF_STRTAB_0) parseterminate( - "Unable to cope with non-zero strtab id"); + "Unable to cope with non-zero strtab id"); if (CTF_NAME_OFFSET(ctt->ctt_name) != 0) { tdp->t_name = xstrdup(sbuf + CTF_NAME_OFFSET(ctt->ctt_name)); diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c b/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c index 546dcdfc9386..fa4fbebb45d2 100644 --- a/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c +++ b/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -650,6 +650,7 @@ wq_init(workqueue_t *wq, int nfiles) wq->wq_wip = xcalloc(sizeof (wip_t) * nslots); wq->wq_nwipslots = nslots; wq->wq_nthreads = MIN(sysconf(_SC_NPROCESSORS_ONLN) * 3 / 2, nslots); + wq->wq_thread = xmalloc(sizeof (pthread_t) * wq->wq_nthreads); if (getenv("CTFMERGE_INPUT_THROTTLE")) throttle = atoi(getenv("CTFMERGE_INPUT_THROTTLE")); @@ -692,7 +693,6 @@ wq_init(workqueue_t *wq, int nfiles) static void start_threads(workqueue_t *wq) { - pthread_t thrid; sigset_t sets; int i; @@ -703,8 +703,8 @@ start_threads(workqueue_t *wq) pthread_sigmask(SIG_BLOCK, &sets, NULL); for (i = 0; i < wq->wq_nthreads; i++) { - pthread_create(&thrid, NULL, (void *(*)(void *))worker_thread, - wq); + pthread_create(&wq->wq_thread[i], NULL, + (void *(*)(void *))worker_thread, wq); } #if defined(sun) @@ -719,6 +719,16 @@ start_threads(workqueue_t *wq) pthread_sigmask(SIG_UNBLOCK, &sets, NULL); } +static void +join_threads(workqueue_t *wq) +{ + int i; + + for (i = 0; i < wq->wq_nthreads; i++) { + pthread_join(wq->wq_thread[i], NULL); + } +} + static int strcompare(const void *p1, const void *p2) { @@ -728,10 +738,18 @@ strcompare(const void *p1, const void *p2) return (strcmp(s1, s2)); } +/* + * Core work queue structure; passed to worker threads on thread creation + * as the main point of coordination. Allocate as a static structure; we + * could have put this into a local variable in main, but passing a pointer + * into your stack to another thread is fragile at best and leads to some + * hard-to-debug failure modes. + */ +static workqueue_t wq; + int main(int argc, char **argv) { - workqueue_t wq; tdata_t *mstrtd, *savetd; char *uniqfile = NULL, *uniqlabel = NULL; char *withfile = NULL; @@ -913,6 +931,8 @@ main(int argc, char **argv) pthread_cond_wait(&wq.wq_alldone_cv, &wq.wq_queue_lock); pthread_mutex_unlock(&wq.wq_queue_lock); + join_threads(&wq); + /* * All requested files have been merged, with the resulting tree in * mstrtd. savetd is the tree that will be placed into the output file. diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.h b/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.h index 38560eab6446..ce40803d52a8 100644 --- a/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.h +++ b/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -78,6 +77,8 @@ typedef struct workqueue { int wq_nomorefiles; + pthread_t *wq_thread; + barrier_t wq_bar1; barrier_t wq_bar2; } workqueue_t; diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/st_parse.c b/cddl/contrib/opensolaris/tools/ctf/cvt/st_parse.c index 53643204c1c6..1dca82a0d3b2 100644 --- a/cddl/contrib/opensolaris/tools/ctf/cvt/st_parse.c +++ b/cddl/contrib/opensolaris/tools/ctf/cvt/st_parse.c @@ -19,12 +19,9 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * This file is a sewer. */ @@ -481,7 +478,8 @@ whitesp(char *cp) { char c; - for (c = *cp++; isspace(c); c = *cp++); + for (c = *cp++; isspace(c); c = *cp++) + ; --cp; return (cp); } @@ -496,8 +494,8 @@ name(char *cp, char **w) c = *cp++; if (c == ':') *w = NULL; - else if (isalpha(c) || strchr("_.$", c)) { - for (c = *cp++; isalnum(c) || strchr(" _.$", c); c = *cp++) + else if (isalpha(c) || strchr("_.$#", c)) { + for (c = *cp++; isalnum(c) || strchr(" _.$#", c); c = *cp++) ; if (c != ':') reset(); @@ -990,14 +988,28 @@ arraydef(char *cp, tdesc_t **rtdp) expected("arraydef/2", ";", cp - 1); if (*cp == 'S') { - /* variable length array - treat as null dimensioned */ + /* + * variable length array - treat as null dimensioned + * + * For VLA variables on sparc, SS12 generated stab entry + * looks as follows: + * .stabs "buf:(0,28)=zr(0,4);0;S-12;(0,1)", 0x80, 0, 0, -16 + * Whereas SS12u1 generated stab entry looks like this: + * .stabs "buf:(0,28)=zr(0,4);0;S0;(0,1)", 0x80, 0, 0, 0 + * On x86, both versions generate the first type of entry. + * We should be able to parse both. + */ cp++; - if (*cp++ != '-') - expected("arraydef/fpoff-sep", "-", cp - 1); + if (*cp == '-') + cp++; cp = number(cp, &end); end = start; } else { - /* normal fixed-dimension array */ + /* + * normal fixed-dimension array + * Stab entry for this looks as follows : + * .stabs "x:(0,28)=ar(0,4);0;9;(0,3)", 0x80, 0, 40, 0 + */ cp = number(cp, &end); /* upper */ } diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/tdata.c b/cddl/contrib/opensolaris/tools/ctf/cvt/tdata.c index 4a0cc79600e7..1ccd6cde5f59 100644 --- a/cddl/contrib/opensolaris/tools/ctf/cvt/tdata.c +++ b/cddl/contrib/opensolaris/tools/ctf/cvt/tdata.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Routines for manipulating tdesc and tdata structures */ @@ -86,9 +84,10 @@ tdesc_layouthash(int nbuckets, void *node) * Unnamed structures, which cannot have forward * declarations pointing to them. We can therefore * incorporate the name of the first member into - * the hash value. + * the hash value, assuming there are any. */ - name = tdp->t_members->ml_name; + if (tdp->t_members != NULL) + name = tdp->t_members->ml_name; break; case ENUM: /* Use the first element in the hash value */ diff --git a/cddl/lib/Makefile b/cddl/lib/Makefile index 5e995f4b60f4..52e97d74be99 100644 --- a/cddl/lib/Makefile +++ b/cddl/lib/Makefile @@ -2,10 +2,10 @@ .include <bsd.own.mk> -SUBDIR= drti \ +SUBDIR= ${_drti} \ libavl \ libctf \ - libdtrace \ + ${_libdtrace} \ libnvpair \ libumem \ libuutil \ @@ -19,4 +19,9 @@ _libzpool= libzpool .endif .endif +.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386" +_drti= drti +_libdtrace= libdtrace +.endif + .include <bsd.subdir.mk> diff --git a/cddl/lib/drti/Makefile b/cddl/lib/drti/Makefile index 4be57a54b2c4..faa016951a8b 100644 --- a/cddl/lib/drti/Makefile +++ b/cddl/lib/drti/Makefile @@ -18,6 +18,7 @@ CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris \ -I${OPENSOLARIS_USR_DISTDIR}/head \ -I${OPENSOLARIS_USR_DISTDIR}/lib/libctf/common \ -I${OPENSOLARIS_USR_DISTDIR}/lib/libdtrace/common \ - -I${OPENSOLARIS_SYS_DISTDIR}/uts/common + -I${OPENSOLARIS_SYS_DISTDIR}/uts/common \ + -DPIC -fpic .include <bsd.prog.mk> diff --git a/cddl/lib/libdtrace/Makefile b/cddl/lib/libdtrace/Makefile index 071d9504c0dd..86ec23a0dc27 100644 --- a/cddl/lib/libdtrace/Makefile +++ b/cddl/lib/libdtrace/Makefile @@ -21,6 +21,7 @@ SRCS= dt_aggregate.c \ dt_grammar.y \ dt_handle.c \ dt_ident.c \ + dt_isadep.c \ dt_inttab.c \ dt_lex.l \ dt_link.c \ @@ -44,7 +45,8 @@ SRCS= dt_aggregate.c \ dt_subr.c \ dt_work.c \ dt_xlator.c \ - gmatch.c + gmatch.c \ + dis_tables.c DSRCS= errno.d \ psinfo.d \ @@ -54,7 +56,8 @@ DSRCS= errno.d \ .PATH: ${OPENSOLARIS_USR_DISTDIR}/lib/libdtrace/common .PATH: ${OPENSOLARIS_USR_DISTDIR}/lib/libgen/common -CFLAGS+= -I${.OBJDIR} \ +CFLAGS+= -I${.OBJDIR} -I${.CURDIR} \ + -I${.CURDIR}/../../../sys/cddl/dev/dtrace/${MACHINE_ARCH} \ -I${.CURDIR}/../../../sys/cddl/compat/opensolaris \ -I${.CURDIR}/../../../cddl/compat/opensolaris/include \ -I${OPENSOLARIS_USR_DISTDIR}/head \ @@ -65,14 +68,21 @@ CFLAGS+= -I${.OBJDIR} \ #CFLAGS+= -DYYDEBUG .if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "amd64" -CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/intel +CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/intel -DDIS_MEM +.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/i386 +.PATH: ${.CURDIR}/../../../sys/cddl/dev/dtrace/${MACHINE_ARCH} .elif ${MACHINE_ARCH} == "sparc64" CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/sparc +.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/lib/libdtrace/sparc .else # temporary hack CFLAGS+= -I${OPENSOLARIS_SYS_DISTDIR}/uts/intel .endif +.if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "amd64" +DSRCS+= regs_x86.d +.endif + LFLAGS+=-l YFLAGS+=-d diff --git a/cddl/lib/libdtrace/libproc_compat.h b/cddl/lib/libdtrace/libproc_compat.h new file mode 100644 index 000000000000..a561157c0ba2 --- /dev/null +++ b/cddl/lib/libdtrace/libproc_compat.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Rui Paulo under sponsorship from the + * FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +/* + * Compatibility functions between Solaris libproc and FreeBSD libproc. + * Functions sorted alphabetically. + */ +#define PR_LMID_EVERY 0 +#define Psetrun(p, a1, a2) proc_continue((p)) +#define Pxlookup_by_addr(p, a, n, s, sym, i) \ + proc_addr2sym(p, a, n, s, sym) +#define Pxlookup_by_name(p, l, s1, s2, sym, a) \ + proc_name2sym((p), (s1), (s2), (sym)) +#define Paddr_to_map proc_addr2map +#define Pcreate_error strerror +#define Pdelbkpt proc_bkptdel +#define Pgrab_error strerror +#define Plmid_to_map(p, l, o) proc_obj2map((p), (o)) +#define Plookup_by_addr proc_addr2sym +#define Pname_to_map proc_name2map +#define Pobject_iter proc_iter_objs +#define Pobjname proc_objname +#define Pread proc_read +#define Prd_agent proc_rdagent +#define Prelease proc_detach +#define Psetbkpt proc_bkptset +#define Psetflags proc_setflags +#define Pstate proc_state +#define Pstate proc_state +#define Psymbol_iter_by_addr proc_iter_symbyaddr +#define Punsetflags proc_clearflags +#define Pupdate_maps(p) do { } while (0) +#define Pupdate_syms proc_updatesyms +#define Pxecbkpt proc_bkptexec diff --git a/cddl/lib/libdtrace/regs_x86.d b/cddl/lib/libdtrace/regs_x86.d new file mode 100644 index 000000000000..7dce19717642 --- /dev/null +++ b/cddl/lib/libdtrace/regs_x86.d @@ -0,0 +1,121 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * Portions Copyright 2009 Stacey Son sson@FreeBSD.org + * + * $FreeBSD$ + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "@(#)regs.d.in 1.1 04/09/28 SMI" + +inline int R_GS = 0; +#pragma D binding "1.0" R_GS +inline int R_FS = 1; +#pragma D binding "1.0" R_FS +inline int R_ES = 2; +#pragma D binding "1.0" R_ES +inline int R_DS = 3; +#pragma D binding "1.0" R_DS + +inline int R_EDI = 4; +#pragma D binding "1.0" R_EDI +inline int R_ESI = 5; +#pragma D binding "1.0" R_ESI +inline int R_EBP = 6; +#pragma D binding "1.0" R_EBP +inline int R_ESP = 7; +#pragma D binding "1.0" R_ESP +inline int R_EBX = 8; +#pragma D binding "1.0" R_EBX +inline int R_EDX = 9; +#pragma D binding "1.0" R_EDX +inline int R_ECX = 10; +#pragma D binding "1.0" R_ECX +inline int R_EAX = 11; +#pragma D binding "1.0" R_EAX + +inline int R_TRAPNO = 12; +#pragma D binding "1.0" R_TRAPNO +inline int R_ERR = 13; +#pragma D binding "1.0" R_ERR +inline int R_EIP = 14; +#pragma D binding "1.0" R_EIP +inline int R_CS = 15; +#pragma D binding "1.0" R_CS +inline int R_EFL = 16; +#pragma D binding "1.0" R_EFL +inline int R_UESP = 17; +#pragma D binding "1.0" R_UESP +inline int R_SS = 18; +#pragma D binding "1.0" R_SS + +inline int R_PC = R_EIP; +#pragma D binding "1.0" R_PC +inline int R_SP = R_UESP; +#pragma D binding "1.0" R_SP +inline int R_PS = R_EFL; +#pragma D binding "1.0" R_PS +inline int R_R0 = R_EAX; +#pragma D binding "1.0" R_R0 +inline int R_R1 = R_EBX; +#pragma D binding "1.0" R_R1 + +inline int R_RSP = 18 + 1 + 20; +#pragma D binding "1.0" R_RSP +inline int R_RFL = 18 + 1 + 19; +#pragma D binding "1.0" R_RFL +inline int R_RIP = 18 + 1 + 17; +#pragma D binding "1.0" R_RIP +inline int R_RAX = 18 + 1 + 14; +#pragma D binding "1.0" R_RAX +inline int R_RCX = 18 + 1 + 13; +#pragma D binding "1.0" R_RCX +inline int R_RDX = 18 + 1 + 12; +#pragma D binding "1.0" R_RDX +inline int R_RBX = 18 + 1 + 11; +#pragma D binding "1.0" R_RBX +inline int R_RBP = 18 + 1 + 10; +#pragma D binding "1.0" R_RBP +inline int R_RSI = 18 + 1 + 9; +#pragma D binding "1.0" R_RSI +inline int R_RDI = 18 + 1 + 8; +#pragma D binding "1.0" R_RDI +inline int R_R8 = 18 + 1 + 7; +#pragma D binding "1.0" R_R8 +inline int R_R9 = 18 + 1 + 6; +#pragma D binding "1.0" R_R9 +inline int R_R10 = 18 + 1 + 5; +#pragma D binding "1.0" R_R10 +inline int R_R11 = 18 + 1 + 4; +#pragma D binding "1.0" R_R11 +inline int R_R12 = 18 + 1 + 3; +#pragma D binding "1.0" R_R12 +inline int R_R13 = 18 + 1 + 2; +#pragma D binding "1.0" R_R13 +inline int R_R14 = 18 + 1 + 1; +#pragma D binding "1.0" R_R14 +inline int R_R15 = 18 + 1 + 0; +#pragma D binding "1.0" R_R15 + diff --git a/cddl/usr.bin/ctfconvert/Makefile b/cddl/usr.bin/ctfconvert/Makefile index 57a08dd04c6d..ff9432265ff2 100644 --- a/cddl/usr.bin/ctfconvert/Makefile +++ b/cddl/usr.bin/ctfconvert/Makefile @@ -7,7 +7,6 @@ DEBUG_FLAGS= -g PROG= ctfconvert - SRCS= alist.c \ ctf.c \ ctfconvert.c \ @@ -46,6 +45,4 @@ LDADD+= -lctf -ldwarf -lelf -lz -lthr .PATH: ${OPENSOLARIS_USR_DISTDIR}/tools/ctf/common .PATH: ${OPENSOLARIS_USR_DISTDIR}/tools/ctf/cvt -MK_MAN= no - .include <bsd.prog.mk> diff --git a/cddl/usr.bin/ctfconvert/ctfconvert.1 b/cddl/usr.bin/ctfconvert/ctfconvert.1 new file mode 100644 index 000000000000..5844632664a8 --- /dev/null +++ b/cddl/usr.bin/ctfconvert/ctfconvert.1 @@ -0,0 +1,85 @@ +.\" +.\" Copyright (c) 2010 The FreeBSD Foundation +.\" All rights reserved. +.\" +.\" This software was developed by Rui Paulo under sponsorship from the +.\" FreeBSD Foundation. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd July 7, 2010 +.Dt CTFCONVERT 1 +.Os +.Sh NAME +.Nm ctfconvert +.Nd convert debug data to CTF data +.Sh SYNOPSIS +.Nm +.Op Fl gis +.Fl l Ar label +.Fl L Ar labelenv +.Op Fl o Ar outfile +object_file +.Sh DESCRIPTION +The +.Nm +utility converts debug information from a binary file to CTF data and replaces +the debug section of that file with a CTF section called SUNW_ctf. +This new section is added to the input file, unless the -o +option is present. +You can also opt to keep the original debugging section with the +-g option. +.Pp +The following options are available: +.Bl -tag -width indent +.It Fl l Ar label +Sets the label as +.Ar label . +.It Fl L Ar labelenv +Instructs +.Nm +to read the label from the environment variable +.Ar labelenv . +.It Fl g +Don't delete the original debugging section. +.It Fl i +Ignore object files built from other languages than C. +.It Fl s +Use the .dynsym ELF section instead of the .symtab ELF section. +.It Fl o Ar outfile +Write the output to file in +.Ar outfile . +.El +.Sh EXIT STATUS +.Ex -std +.Sh SEE ALSO +.Xr ctfmerge 1 , +.Xr ctfdump 1 +.Sh HISTORY +The +.Nm +utility first appeared in +.Fx 7.0 . +.Sh AUTHORS +The CTF utilities came from OpenSolaris. diff --git a/cddl/usr.bin/ctfdump/Makefile b/cddl/usr.bin/ctfdump/Makefile index 9a65c15efd31..5231d9499f05 100644 --- a/cddl/usr.bin/ctfdump/Makefile +++ b/cddl/usr.bin/ctfdump/Makefile @@ -3,7 +3,6 @@ .include "../../Makefile.inc" PROG= ctfdump - SRCS= dump.c \ symbol.c \ utils.c @@ -26,6 +25,4 @@ LDADD+= -lelf -lz .PATH: ${OPENSOLARIS_USR_DISTDIR}/tools/ctf/common .PATH: ${OPENSOLARIS_USR_DISTDIR}/tools/ctf/dump -NO_MAN= - .include <bsd.prog.mk> diff --git a/cddl/usr.bin/ctfdump/ctfdump.1 b/cddl/usr.bin/ctfdump/ctfdump.1 new file mode 100644 index 000000000000..d64a88a60548 --- /dev/null +++ b/cddl/usr.bin/ctfdump/ctfdump.1 @@ -0,0 +1,83 @@ +.\" +.\" Copyright (c) 2010 The FreeBSD Foundation +.\" All rights reserved. +.\" +.\" This software was developed by Rui Paulo under sponsorship from the +.\" FreeBSD Foundation. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd July 7, 2010 +.Dt CTFDUMP 1 +.Os +.Sh NAME +.Nm ctfdump +.Nd dump the SUNW_ctf section of an ELF file +.Sh SYNOPSIS +.Nm +.Op Fl dfhlsSt +.Fl u Ar file +file +.Sh DESCRIPTION +The +.Nm +utility dumps the contents of the CTF data section (SUNW_ctf) present in +an ELF binary file. +This section was previously created with +.Xr ctfconvert 1 +or +.Xr ctfmerge 1 . +.Pp +The following options are available: +.Bl -tag -width indent +.It Fl d +Show the data object section. +.It Fl f +Show the function section. +.It Fl h +Show the header. +.It Fl l +Show the label section. +.It Fl s +Show the string table. +.It Fl S +Show statistics. +.It Fl t +Show the type section. +.It Fl u Ar ufile +Write the uncompressed CTF data to a raw CTF file called +.Ar ufile . +.El +.Sh EXIT STATUS +.Ex -std +.Sh SEE ALSO +.Xr ctfconvert 1 , +.Xr ctfmerge 1 +.Sh HISTORY +The +.Nm +utility first appeared in +.Fx 7.0 . +.Sh AUTHORS +The CTF utilities came from OpenSolaris. diff --git a/cddl/usr.bin/ctfmerge/Makefile b/cddl/usr.bin/ctfmerge/Makefile index 051fa0b434d3..35b1d06073f2 100644 --- a/cddl/usr.bin/ctfmerge/Makefile +++ b/cddl/usr.bin/ctfmerge/Makefile @@ -7,7 +7,6 @@ WARNS= 1 PROG= ctfmerge - SRCS= alist.c \ barrier.c \ ctf.c \ @@ -42,6 +41,4 @@ LDADD+= -lctf -ldwarf -lelf -lz -lthr .PATH: ${OPENSOLARIS_USR_DISTDIR}/tools/ctf/common .PATH: ${OPENSOLARIS_USR_DISTDIR}/tools/ctf/cvt -MK_MAN= no - .include <bsd.prog.mk> diff --git a/cddl/usr.bin/ctfmerge/ctfmerge.1 b/cddl/usr.bin/ctfmerge/ctfmerge.1 new file mode 100644 index 000000000000..47151d6a1f04 --- /dev/null +++ b/cddl/usr.bin/ctfmerge/ctfmerge.1 @@ -0,0 +1,120 @@ +.\" +.\" Copyright (c) 2010 The FreeBSD Foundation +.\" All rights reserved. +.\" +.\" This software was developed by Rui Paulo under sponsorship from the +.\" FreeBSD Foundation. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd July 7, 2010 +.Dt CTFMERGE 1 +.Os +.Sh NAME +.Nm ctfmerge +.Nd merge several CTF data sections into one +.Sh SYNOPSIS +.Nm +.Op Fl fgstv +.Fl l Ar label +.Fl L Ar labelenv +.Fl o Ar outfile +file ... +.Nm +.Op Fl fgstv +.Fl l Ar label +.Fl L Ar labelenv +.Fl o Ar outfile +.Fl d Ar uniqfile +.Op Fl g +.Op Fl D Ar uniqlabel +file ... +.Nm +.Op Fl fgstv +.Fl l Ar label +.Fl L Ar labelenv +.Fl o Ar outfile +.Fl w Ar withfile +file ... +.Nm +.Op Fl g +.Fl c Ar srcfile +.Ar destfile +.Sh DESCRIPTION +The +.Nm +utility merges several CTF data sections from several files into one +output file, unifying common data. +.Pp +The following options are available: +.Bl -tag -width indent +.It Fl f +Match global symbols to global CTF data. +.It Fl g +Don't delete the original debugging sections. +.It Fl s +Use the .dynsym ELF section instead of the .symtab ELF section. +.It Fl t +Make sure that all object files have a CTF section. +.It Fl v +Enable verbose mode. +.It Fl l Ar label +Sets the label as +.Ar label . +.It Fl L Ar labelenv +Instructs +.Nm +to read the label from the environment variable +.Ar labelenv . +.It Fl o Ar outfile +Use +.Ar outfile +to store the merged CTF data. +.It Fl d Ar uniqfile +Uniquify against +.Ar uniqfile . +.It Fl d Ar uniqlabel +Uniquify against label +.Ar uniqlabel +.It Fl w Ar withfile +Additive merge with +.Ar withfile . +.It Fl c Ar srcfile Ar destfile +Copy CTF data from +.Ar srcfile +into +.Ar destfile . +.El +.Sh EXIT STATUS +.Ex -std +.Sh SEE ALSO +.Xr ctfconvert 1 , +.Xr ctfdump 1 +.Sh HISTORY +The +.Nm +utility first appeared in +.Fx 7.0 . +.Sh AUTHORS +The CTF utilities came from OpenSolaris. diff --git a/cddl/usr.sbin/Makefile b/cddl/usr.sbin/Makefile index f7c32f38f93d..49db06b61082 100644 --- a/cddl/usr.sbin/Makefile +++ b/cddl/usr.sbin/Makefile @@ -2,8 +2,9 @@ .include <bsd.own.mk> -SUBDIR= dtrace \ - lockstat \ +SUBDIR= ${_dtrace} \ + ${_dtruss} \ + ${_lockstat} \ ${_zdb} .if ${MK_ZFS} != "no" @@ -12,4 +13,10 @@ _zdb= zdb .endif .endif +.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386" +_dtrace= dtrace +_dtruss= dtruss +_lockstat= lockstat +.endif + .include <bsd.subdir.mk> diff --git a/cddl/usr.sbin/dtrace/Makefile b/cddl/usr.sbin/dtrace/Makefile index 44116fcbc4ef..9e8e34835f90 100644 --- a/cddl/usr.sbin/dtrace/Makefile +++ b/cddl/usr.sbin/dtrace/Makefile @@ -24,14 +24,9 @@ CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris \ #CFLAGS+= -DNEED_ERRLOC #YFLAGS+= -d -LDFLAGS+= -pthread \ - -L${.OBJDIR}/../../lib/libdtrace \ - -L${.OBJDIR}/../../lib/libproc \ - -L${.OBJDIR}/../../lib/libctf \ - -L${.OBJDIR}/../../../lib/libelf - -LDADD+= -ldtrace -ly -ll -lproc -lctf -lelf -lz - -DPADD+= ${LIBDTRACE} ${LIBCTF} ${LIBELF} ${LIBPTHREAD} ${LIBL} ${LIBY} ${LIBZ} +DPADD= ${LIBPTHREAD} ${LIBDTRACE} ${LIBY} ${LIBL} ${LIBPROC} \ + ${LIBCTF} ${LIBELF} ${LIBZ} ${LIBUTIL} ${LIBRTLD_DB} +LDADD= -lpthread -ldtrace -ly -ll -lproc -lctf -lelf -lz -lutil \ + -lrtld_db .include <bsd.prog.mk> diff --git a/cddl/usr.sbin/dtruss/Makefile b/cddl/usr.sbin/dtruss/Makefile new file mode 100644 index 000000000000..39161ec0f8d1 --- /dev/null +++ b/cddl/usr.sbin/dtruss/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../../cddl/contrib/dtracetoolkit + +SCRIPTS=dtruss +MAN=dtruss.1 + +.include <bsd.prog.mk> diff --git a/cddl/usr.sbin/dtruss/dtruss.1 b/cddl/usr.sbin/dtruss/dtruss.1 new file mode 100644 index 000000000000..d408e81bd80d --- /dev/null +++ b/cddl/usr.sbin/dtruss/dtruss.1 @@ -0,0 +1,89 @@ +.\" +.\" Copyright (c) 2010 The FreeBSD Foundation +.\" All rights reserved. +.\" +.\" This software was developed by Rui Paulo under sponsorship from the +.\" FreeBSD Foundation. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd August 26, 2010 +.Dt DTRUSS 1 +.Os +.Sh NAME +.Nm dtruss +.Nd Trace system calls and userland stacks using DTrace +.Sh SYNOPSIS +.Nm +.Op Fl acdefholLs +.Op Fl t Ar syscall +.Op Fl n Ar name Fl p Ar pid Ar command +.Sh DESCRIPTION +The +.Nm +utility traces system calls and (optionally) userland stack traces for the +specified programs. +.Pp +The following options are available: +.Bl -tag -width indent +.It Fl p Ar pid +Trace the process with PID +.Ar pid . +.It Fl n Ar name +Trace the process with name +.Ar name . +.It Fl t Ar syscall +Trace the specified syscall only. +.It Fl a +Print all details. +.It Fl c +Print syscall counts. +.It Fl d +Print relative times (in microseconds). +.It Fl e +Print elapsed times (in microseconds). +.It Fl f +Follow the children processes. +.It Fl l +Force printing PID / TID. +.It Fl o +Print time spent on CPU. +.It Fl s +Print userland stack backtraces. +.It Fl L +Don't print PID / TID. +.It Fl b Ar bufsize +Specify the DTrace buffer size. +.El +.Sh EXIT STATUS +.Ex -std +.Sh SEE ALSO +.Xr dtrace 1 +.Sh HISTORY +The +.Nm +utility comes from the DTraceToolkit and was first imported into +.Fx 9.0 . +.Sh AUTHORS +.An Brendan Gregg diff --git a/cddl/usr.sbin/lockstat/Makefile b/cddl/usr.sbin/lockstat/Makefile index 9c135f91263f..98732934fe97 100644 --- a/cddl/usr.sbin/lockstat/Makefile +++ b/cddl/usr.sbin/lockstat/Makefile @@ -25,15 +25,11 @@ CFLAGS+= -DNEED_ERRLOC -g #YFLAGS+= -d -LDFLAGS+= -pthread \ - -L${.OBJDIR}/../../lib/libdtrace \ - -L${.OBJDIR}/../../lib/libproc \ - -L${.OBJDIR}/../../lib/libctf \ - -L${.OBJDIR}/../../../lib/libelf - -LDADD+= -ldtrace -ly -ll -lproc -lctf -lelf -lz -lrt - -#DPADD+= ${LIBDTRACE} ${LIBPTHREAD} ${LIBL} ${LIBY} ${LIBZ} +DPADD= ${LIBPTHREAD} ${LIBDTRACE} ${LIBY} ${LIBL} ${LIBPROC} \ + ${LIBCTF} ${LIBELF} ${LIBZ} ${LIBRT} ${LIBUTIL} \ + ${LIBRTLD_DB} +LDADD= -lpthread -ldtrace -ly -ll -lproc -lctf -lelf -lz -lrt -lutil \ + -lrtld_db NO_MAN= diff --git a/cddl/usr.sbin/plockstat/Makefile b/cddl/usr.sbin/plockstat/Makefile new file mode 100644 index 000000000000..059295898110 --- /dev/null +++ b/cddl/usr.sbin/plockstat/Makefile @@ -0,0 +1,26 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/cmd/plockstat + +PROG= plockstat +SRCS= plockstat.c +BINDIR?= /usr/sbin + +WARNS?= 1 + +CFLAGS+= -I${.CURDIR}/../../../sys/cddl/compat/opensolaris \ + -I${.CURDIR}/../../../cddl/compat/opensolaris/include \ + -I${OPENSOLARIS_USR_DISTDIR}/head \ + -I${OPENSOLARIS_USR_DISTDIR}/lib/libdtrace/common \ + -I${OPENSOLARIS_USR_DISTDIR}/lib/libproc/common \ + -I${OPENSOLARIS_SYS_DISTDIR}/uts/common \ + -I${OPENSOLARIS_SYS_DISTDIR}/compat \ + -I${.CURDIR}/../../../cddl/lib/libdtrace \ + -I${.CURDIR}/../../../sys + +DPADD= ${LIBPTHREAD} ${LIBDTRACE} ${LIBY} ${LIBL} ${LIBPROC} ${LIBCTF}\ + ${LIBELF} ${LIBZ} ${LIBRT} ${LIBRTLD_DB} ${LIBUTIL} +LDADD= -lpthread -ldtrace -ly -ll -lproc -lctf -lelf -lz -lrt \ + -lrtld_db -lutil + +.include <bsd.prog.mk> diff --git a/cddl/usr.sbin/plockstat/plockstat.1 b/cddl/usr.sbin/plockstat/plockstat.1 new file mode 100644 index 000000000000..ca97f39a6db7 --- /dev/null +++ b/cddl/usr.sbin/plockstat/plockstat.1 @@ -0,0 +1,95 @@ +.\" +.\" Copyright (c) 2010 The FreeBSD Foundation +.\" All rights reserved. +.\" +.\" This software was developed by Rui Paulo under sponsorship from the +.\" FreeBSD Foundation. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd September 13, 2010 +.Dt PLOCKSTAT 1 +.Os +.Sh NAME +.Nm plockstat +.Nd Trace pthread lock statistics using DTrace +.Sh SYNOPSIS +.Nm +.Op Fl vACHV +.Op Fl n Ar count +.Op Fl s Ar depth +.Op Fl e Ar secs +.Op Fl x Ar opt Ns = Ns Ar val +.Ar command +.Op arg... +.Nm +.Op Fl vACHV +.Op Fl n Ar count +.Op Fl s Ar depth +.Op Fl e Ar secs +.Op Fl x Ar opt Ns = Ns Ar val +.Fl p Ar pid +.Sh DESCRIPTION +The +.Nm +utility traces pthread locks (mutexes and rwlocks) and prints statistics about +them. +You can use +.Nm +to investigate bottlenecks in your software. +.Pp +The following options are available: +.Bl -tag -width indent +.It Fl v +Be verbose. +.It Fl A +Print all statistics. +.It Fl C +Print commulative statistics (the default). +.It Fl H +Print an histogram. +.It Fl V +Print the DTrace script about to be used to stderr. +.It Fl n Ar count +Set the aggregation count for the data set. +.It Fl s Ar depth +Set the ustack (userland stack) caller depth. +.It Fl e Ar secs +Does nothing at the moment. +.It Fl x Ar opt Ns = Ns Ar val +Specify DTrace options. +See the +.Xr dtrace 1 +man page for more details. +.El +.Sh EXIT STATUS +.Ex -std +.Sh SEE ALSO +.Xr dtrace 1 , +.Xr pthread 3 +.Sh HISTORY +The +.Nm +utility comes from the OpenSolaris and was first imported into +.Fx 9.0 . diff --git a/lib/libproc/Makefile b/lib/libproc/Makefile index d6d29b3eaaf4..1bf19c4f7989 100644 --- a/lib/libproc/Makefile +++ b/lib/libproc/Makefile @@ -2,9 +2,11 @@ LIB= proc -SRCS= \ +SRCS= proc_bkpt.c \ proc_create.c \ + proc_regs.c \ proc_sym.c \ + proc_rtld.c \ proc_util.c INCS= libproc.h diff --git a/lib/libproc/_libproc.h b/lib/libproc/_libproc.h index 536227e29bf3..aee1ac1f67f8 100644 --- a/lib/libproc/_libproc.h +++ b/lib/libproc/_libproc.h @@ -31,6 +31,7 @@ #include <sys/types.h> #include <sys/event.h> #include <sys/ptrace.h> +#include <rtld_db.h> #include "libproc.h" @@ -39,5 +40,16 @@ struct proc_handle { int kq; /* Kernel event queue ID. */ int flags; /* Process flags. */ int status; /* Process status (PS_*). */ + int wstat; /* Process wait status. */ + rd_agent_t *rdap; /* librtld_db agent */ + rd_loadobj_t *rdobjs; + size_t rdobjsz; + size_t nobjs; + struct lwpstatus lwps; }; +#ifdef DEBUG +#define DPRINTF(fmt, ...) warn(fmt, __VA_ARGS__) +#else +#define DPRINTF(fmt, ...) +#endif diff --git a/lib/libproc/libproc.h b/lib/libproc/libproc.h index eccf37d849f4..d80e88c466a0 100644 --- a/lib/libproc/libproc.h +++ b/lib/libproc/libproc.h @@ -1,7 +1,11 @@ /*- + * Copyright (c) 2010 The FreeBSD Foundation * Copyright (c) 2008 John Birrell (jb@freebsd.org) * All rights reserved. * + * Portions of this software were developed by Rui Paulo under sponsorship + * from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -30,6 +34,8 @@ #define _LIBPROC_H_ #include <gelf.h> +#include <rtld_db.h> +#include <limits.h> struct proc_handle; @@ -43,30 +49,100 @@ typedef void (*proc_child_func)(void *); #define PS_DEAD 5 #define PS_LOST 6 +/* Reason values for proc_detach(). */ +#define PRELEASE_HANG 1 +#define PRELEASE_KILL 2 + typedef struct prmap { uintptr_t pr_vaddr; /* Virtual address. */ + size_t pr_size; /* Mapping size in bytes */ + size_t pr_offset; /* Mapping offset in object */ + char pr_mapname[PATH_MAX]; /* Mapping filename */ + uint8_t pr_mflags; /* Protection flags */ +#define MA_READ 0x01 +#define MA_WRITE 0x02 +#define MA_EXEC 0x04 +#define MA_COW 0x08 +#define MA_NEEDS_COPY 0x10 +#define MA_NOCOREDUMP 0x20 } prmap_t; +typedef int proc_map_f(void *, const prmap_t *, const char *); +typedef int proc_sym_f(void *, const GElf_Sym *, const char *); + +/* Values for ELF sections */ +#define PR_SYMTAB 1 +#define PR_DYNSYM 2 + +/* Values for the 'mask' parameter in the iteration functions */ +#define BIND_LOCAL 0x0001 +#define BIND_GLOBAL 0x0002 +#define BIND_WEAK 0x0004 +#define BIND_ANY (BIND_LOCAL|BIND_GLOBAL|BIND_WEAK) +#define TYPE_NOTYPE 0x0100 +#define TYPE_OBJECT 0x0200 +#define TYPE_FUNC 0x0400 +#define TYPE_SECTION 0x0800 +#define TYPE_FILE 0x1000 +#define TYPE_ANY (TYPE_NOTYPE|TYPE_OBJECT|TYPE_FUNC|TYPE_SECTION|\ + TYPE_FILE) + +typedef enum { + REG_PC, + REG_SP, + REG_RVAL1, + REG_RVAL2 +} proc_reg_t; + +#define SIG2STR_MAX 8 + +typedef struct lwpstatus { + int pr_why; +#define PR_REQUESTED 1 +#define PR_FAULTED 2 +#define PR_SYSENTRY 3 +#define PR_SYSEXIT 4 + int pr_what; +#define FLTBPT -1 +} lwpstatus_t; + /* Function prototype definitions. */ __BEGIN_DECLS -const prmap_t *proc_addr2map(struct proc_handle *, uintptr_t); -const prmap_t *proc_name2map(struct proc_handle *, const char *); +prmap_t *proc_addr2map(struct proc_handle *, uintptr_t); +prmap_t *proc_name2map(struct proc_handle *, const char *); char *proc_objname(struct proc_handle *, uintptr_t, char *, size_t); +prmap_t *proc_obj2map(struct proc_handle *, const char *); +int proc_iter_objs(struct proc_handle *, proc_map_f *, void *); +int proc_iter_symbyaddr(struct proc_handle *, const char *, int, + int, proc_sym_f *, void *); int proc_addr2sym(struct proc_handle *, uintptr_t, char *, size_t, GElf_Sym *); int proc_attach(pid_t pid, int flags, struct proc_handle **pphdl); int proc_continue(struct proc_handle *); int proc_clearflags(struct proc_handle *, int); int proc_create(const char *, char * const *, proc_child_func *, void *, struct proc_handle **); -int proc_detach(struct proc_handle *); +int proc_detach(struct proc_handle *, int); int proc_getflags(struct proc_handle *); int proc_name2sym(struct proc_handle *, const char *, const char *, GElf_Sym *); int proc_setflags(struct proc_handle *, int); int proc_state(struct proc_handle *); -int proc_wait(struct proc_handle *); pid_t proc_getpid(struct proc_handle *); +int proc_wstatus(struct proc_handle *); +int proc_getwstat(struct proc_handle *); +char * proc_signame(int, char *, size_t); +int proc_read(struct proc_handle *, void *, size_t, size_t); +const lwpstatus_t * + proc_getlwpstatus(struct proc_handle *); void proc_free(struct proc_handle *); +rd_agent_t *proc_rdagent(struct proc_handle *); +void proc_updatesyms(struct proc_handle *); +int proc_bkptset(struct proc_handle *, uintptr_t, unsigned long *); +int proc_bkptdel(struct proc_handle *, uintptr_t, unsigned long); +void proc_bkptregadj(unsigned long *); +int proc_bkptexec(struct proc_handle *, unsigned long); +int proc_regget(struct proc_handle *, proc_reg_t, unsigned long *); +int proc_regset(struct proc_handle *, proc_reg_t, unsigned long); __END_DECLS diff --git a/lib/libproc/proc_bkpt.c b/lib/libproc/proc_bkpt.c new file mode 100644 index 000000000000..c4264717fb65 --- /dev/null +++ b/lib/libproc/proc_bkpt.c @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Rui Paulo under sponsorship from the + * FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/ptrace.h> +#include <sys/wait.h> +#include <machine/_inttypes.h> + +#include <assert.h> +#include <err.h> +#include <stdio.h> +#include <errno.h> +#include "_libproc.h" + +#if defined(__i386__) || defined(__amd64__) +#define BREAKPOINT_INSTR 0xcc /* int 0x3 */ +#define BREAKPOINT_INSTR_SZ 1 +#else +#error "Add support for your architecture" +#endif + +int +proc_bkptset(struct proc_handle *phdl, uintptr_t address, + unsigned long *saved) +{ + struct ptrace_io_desc piod; + unsigned long paddr, caddr; + + *saved = 0; + if (phdl->status == PS_DEAD || phdl->status == PS_UNDEAD || + phdl->status == PS_IDLE) { + errno = ENOENT; + return (-1); + } + + /* + * Read the original instruction. + */ + caddr = address; + paddr = 0; + piod.piod_op = PIOD_READ_I; + piod.piod_offs = (void *)caddr; + piod.piod_addr = &paddr; + piod.piod_len = BREAKPOINT_INSTR_SZ; + if (ptrace(PT_IO, proc_getpid(phdl), (caddr_t)&piod, 0) < 0) { + DPRINTF("ERROR: couldn't read instruction at address 0x%" PRIuPTR, + address); + return (-1); + } + *saved = paddr; + /* + * Write a breakpoint instruction to that address. + */ + caddr = address; + paddr = BREAKPOINT_INSTR; + piod.piod_op = PIOD_WRITE_I; + piod.piod_offs = (void *)caddr; + piod.piod_addr = &paddr; + piod.piod_len = BREAKPOINT_INSTR_SZ; + if (ptrace(PT_IO, proc_getpid(phdl), (caddr_t)&piod, 0) < 0) { + warn("ERROR: couldn't write instruction at address 0x%" PRIuPTR, + address); + return (-1); + } + + return (0); +} + +int +proc_bkptdel(struct proc_handle *phdl, uintptr_t address, + unsigned long saved) +{ + struct ptrace_io_desc piod; + unsigned long paddr, caddr; + + if (phdl->status == PS_DEAD || phdl->status == PS_UNDEAD || + phdl->status == PS_IDLE) { + errno = ENOENT; + return (-1); + } + DPRINTF("removing breakpoint at 0x%lx\n", address); + /* + * Overwrite the breakpoint instruction that we setup previously. + */ + caddr = address; + paddr = saved; + piod.piod_op = PIOD_WRITE_I; + piod.piod_offs = (void *)caddr; + piod.piod_addr = &paddr; + piod.piod_len = BREAKPOINT_INSTR_SZ; + if (ptrace(PT_IO, proc_getpid(phdl), (caddr_t)&piod, 0) < 0) { + DPRINTF("ERROR: couldn't write instruction at address 0x%" PRIuPTR, + address); + return (-1); + } + + return (0); +} + +/* + * Decrement pc so that we delete the breakpoint at the correct + * address, i.e. at the BREAKPOINT_INSTR address. + */ +void +proc_bkptregadj(unsigned long *pc) +{ + *pc = *pc - BREAKPOINT_INSTR_SZ; +} + +/* + * Step over the breakpoint. + */ +int +proc_bkptexec(struct proc_handle *phdl, unsigned long saved) +{ + unsigned long pc; + unsigned long samesaved; + int status; + + if (proc_regget(phdl, REG_PC, &pc) < 0) { + warn("ERROR: couldn't get PC register"); + return (-1); + } + proc_bkptregadj(&pc); + if (proc_bkptdel(phdl, pc, saved) < 0) { + warn("ERROR: couldn't delete breakpoint"); + return (-1); + } + /* + * Go back in time and step over the new instruction just + * set up by proc_bkptdel(). + */ + proc_regset(phdl, REG_PC, pc); + if (ptrace(PT_STEP, proc_getpid(phdl), (caddr_t)1, 0) < 0) { + warn("ERROR: ptrace step failed"); + return (-1); + } + proc_wstatus(phdl); + status = proc_getwstat(phdl); + if (!WIFSTOPPED(status)) { + warn("ERROR: don't know why process stopped"); + return (-1); + } + /* + * Restore the breakpoint. The saved instruction should be + * the same as the one that we were passed in. + */ + if (proc_bkptset(phdl, pc, &samesaved) < 0) { + warn("ERROR: couldn't restore breakpoint"); + return (-1); + } + assert(samesaved == saved); + + return (0); +} diff --git a/lib/libproc/proc_create.c b/lib/libproc/proc_create.c index 1649b471ba06..b30a77b60f4c 100644 --- a/lib/libproc/proc_create.c +++ b/lib/libproc/proc_create.c @@ -27,6 +27,7 @@ */ #include "_libproc.h" +#include <stdio.h> #include <err.h> #include <errno.h> #include <fcntl.h> @@ -40,11 +41,10 @@ int proc_attach(pid_t pid, int flags, struct proc_handle **pphdl) { struct proc_handle *phdl; - struct kevent kev; int error = 0; int status; - if (pid == 0 || pphdl == NULL) + if (pid == 0 || pid == getpid()) return (EINVAL); /* @@ -58,26 +58,24 @@ proc_attach(pid_t pid, int flags, struct proc_handle **pphdl) phdl->pid = pid; phdl->flags = flags; phdl->status = PS_RUN; + elf_version(EV_CURRENT); - EV_SET(&kev, pid, EVFILT_PROC, EV_ADD | EV_ONESHOT, NOTE_EXIT, - 0, NULL); - - if ((phdl->kq = kqueue()) == -1) - err(1, "ERROR: cannot create kernel evet queue"); - - if (kevent(phdl->kq, &kev, 1, NULL, 0, NULL) < 0) - err(2, "ERROR: cannot monitor child process %d", pid); - - if (ptrace(PT_ATTACH, phdl->pid, NULL, 0) != 0) + if (ptrace(PT_ATTACH, phdl->pid, 0, 0) != 0) { error = errno; + DPRINTF("ERROR: cannot ptrace child process %d", pid); + goto out; + } /* Wait for the child process to stop. */ - else if (waitpid(pid, &status, WUNTRACED) == -1) - err(3, "ERROR: child process %d didn't stop as expected", pid); + if (waitpid(pid, &status, WUNTRACED) == -1) { + error = errno; + DPRINTF("ERROR: child process %d didn't stop as expected", pid); + goto out; + } /* Check for an unexpected status. */ - else if (WIFSTOPPED(status) == 0) - err(4, "ERROR: child process %d status 0x%x", pid, status); + if (WIFSTOPPED(status) == 0) + DPRINTF("ERROR: child process %d status 0x%x", pid, status); else phdl->status = PS_STOP; @@ -85,6 +83,7 @@ proc_attach(pid_t pid, int flags, struct proc_handle **pphdl) proc_free(phdl); else *pphdl = phdl; +out: return (error); } @@ -94,7 +93,6 @@ proc_create(const char *file, char * const *argv, proc_child_func *pcf, void *child_arg, struct proc_handle **pphdl) { struct proc_handle *phdl; - struct kevent kev; int error = 0; int status; pid_t pid; @@ -106,6 +104,8 @@ proc_create(const char *file, char * const *argv, proc_child_func *pcf, if ((phdl = malloc(sizeof(struct proc_handle))) == NULL) return (ENOMEM); + elf_version(EV_CURRENT); + /* Fork a new process. */ if ((pid = vfork()) == -1) error = errno; @@ -128,31 +128,26 @@ proc_create(const char *file, char * const *argv, proc_child_func *pcf, phdl->pid = pid; phdl->status = PS_IDLE; - EV_SET(&kev, pid, EVFILT_PROC, EV_ADD | EV_ONESHOT, NOTE_EXIT, - 0, NULL); - - if ((phdl->kq = kqueue()) == -1) - err(1, "ERROR: cannot create kernel evet queue"); - - if (kevent(phdl->kq, &kev, 1, NULL, 0, NULL) < 0) - err(2, "ERROR: cannot monitor child process %d", pid); - /* Wait for the child process to stop. */ - if (waitpid(pid, &status, WUNTRACED) == -1) - err(3, "ERROR: child process %d didn't stop as expected", pid); + if (waitpid(pid, &status, WUNTRACED) == -1) { + error = errno; + DPRINTF("ERROR: child process %d didn't stop as expected", pid); + goto bad; + } /* Check for an unexpected status. */ - if (WIFSTOPPED(status) == 0) - err(4, "ERROR: child process %d status 0x%x", pid, status); - else + if (WIFSTOPPED(status) == 0) { + error = errno; + DPRINTF("ERROR: child process %d status 0x%x", pid, status); + goto bad; + } else phdl->status = PS_STOP; } - +bad: if (error) proc_free(phdl); else *pphdl = phdl; - return (error); } diff --git a/lib/libproc/proc_regs.c b/lib/libproc/proc_regs.c new file mode 100644 index 000000000000..3450e98acf74 --- /dev/null +++ b/lib/libproc/proc_regs.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Rui Paulo under sponsorship from the + * FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/ptrace.h> + +#include <err.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include "_libproc.h" + +int +proc_regget(struct proc_handle *phdl, proc_reg_t reg, unsigned long *regvalue) +{ + struct reg regs; + + if (phdl->status == PS_DEAD || phdl->status == PS_UNDEAD || + phdl->status == PS_IDLE) { + errno = ENOENT; + return (-1); + } + memset(®s, 0, sizeof(regs)); + if (ptrace(PT_GETREGS, proc_getpid(phdl), (caddr_t)®s, 0) < 0) + return (-1); + switch (reg) { + case REG_PC: +#if defined(__amd64__) + *regvalue = regs.r_rip; +#elif defined(__i386__) + *regvalue = regs.r_eip; +#endif + break; + case REG_SP: +#if defined(__amd64__) + *regvalue = regs.r_rsp; +#elif defined(__i386__) + *regvalue = regs.r_esp; +#endif + break; + default: + warn("ERROR: no support for reg number %d", reg); + return (-1); + } + + return (0); +} + +int +proc_regset(struct proc_handle *phdl, proc_reg_t reg, unsigned long regvalue) +{ + struct reg regs; + + if (phdl->status == PS_DEAD || phdl->status == PS_UNDEAD || + phdl->status == PS_IDLE) { + errno = ENOENT; + return (-1); + } + if (ptrace(PT_GETREGS, proc_getpid(phdl), (caddr_t)®s, 0) < 0) + return (-1); + switch (reg) { + case REG_PC: +#if defined(__amd64__) + regs.r_rip = regvalue; +#elif defined(__i386__) + regs.r_eip = regvalue; +#endif + break; + case REG_SP: +#if defined(__amd64__) + regs.r_rsp = regvalue; +#elif defined(__i386__) + regs.r_esp = regvalue; +#endif + break; + default: + warn("ERROR: no support for reg number %d", reg); + return (-1); + } + if (ptrace(PT_SETREGS, proc_getpid(phdl), (caddr_t)®s, 0) < 0) + return (-1); + + return (0); +} diff --git a/lib/libproc/proc_rtld.c b/lib/libproc/proc_rtld.c new file mode 100644 index 000000000000..2a9ed39965b0 --- /dev/null +++ b/lib/libproc/proc_rtld.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Rui Paulo under sponsorship from the + * FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <rtld_db.h> +#include "libproc.h" +#include "_libproc.h" + +static int +map_iter(const rd_loadobj_t *lop, void *arg) +{ + struct proc_handle *phdl = arg; + + if (phdl->nobjs >= phdl->rdobjsz) { + phdl->rdobjsz *= 2; + phdl->rdobjs = realloc(phdl->rdobjs, phdl->rdobjsz); + if (phdl->rdobjs == NULL) + return (-1); + } + memcpy(&phdl->rdobjs[phdl->nobjs++], lop, sizeof(*lop)); + + return (0); +} + +rd_agent_t * +proc_rdagent(struct proc_handle *phdl) +{ + if (phdl->rdap == NULL && phdl->status != PS_UNDEAD && + phdl->status != PS_IDLE) { + if ((phdl->rdap = rd_new(phdl)) != NULL) { + phdl->rdobjs = malloc(sizeof(*phdl->rdobjs) * 64); + phdl->rdobjsz = 64; + if (phdl->rdobjs == NULL) + return (phdl->rdap); + rd_loadobj_iter(phdl->rdap, map_iter, phdl); + } + } + + return (phdl->rdap); +} + +void +proc_updatesyms(struct proc_handle *phdl) +{ + + memset(phdl->rdobjs, 0, sizeof(*phdl->rdobjs) * phdl->rdobjsz); + phdl->nobjs = 0; + rd_loadobj_iter(phdl->rdap, map_iter, phdl); +} diff --git a/lib/libproc/proc_sym.c b/lib/libproc/proc_sym.c index c17c515b7230..ffbc51f37a3f 100644 --- a/lib/libproc/proc_sym.c +++ b/lib/libproc/proc_sym.c @@ -1,7 +1,11 @@ /*- + * Copyright (c) 2010 The FreeBSD Foundation * Copyright (c) 2008 John Birrell (jb@freebsd.org) * All rights reserved. * + * Portions of this software were developed by Rui Paulo under sponsorship + * from the FreeBSD Foundation. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -26,43 +30,535 @@ * $FreeBSD$ */ -#include "_libproc.h" +#include <sys/types.h> +#include <sys/user.h> + +#include <assert.h> +#include <err.h> #include <stdio.h> +#include <libgen.h> +#include <string.h> +#include <stdlib.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> +#include <libutil.h> + +#include "_libproc.h" + +static void proc_rdl2prmap(rd_loadobj_t *, prmap_t *); + +static void +proc_rdl2prmap(rd_loadobj_t *rdl, prmap_t *map) +{ + map->pr_vaddr = rdl->rdl_saddr; + map->pr_size = rdl->rdl_eaddr - rdl->rdl_saddr; + map->pr_offset = rdl->rdl_offset; + map->pr_mflags = 0; + if (rdl->rdl_prot & RD_RDL_R) + map->pr_mflags |= MA_READ; + if (rdl->rdl_prot & RD_RDL_W) + map->pr_mflags |= MA_WRITE; + if (rdl->rdl_prot & RD_RDL_X) + map->pr_mflags |= MA_EXEC; + strlcpy(map->pr_mapname, rdl->rdl_path, + sizeof(map->pr_mapname)); +} char * proc_objname(struct proc_handle *p, uintptr_t addr, char *objname, size_t objnamesz) { -printf("%s(%d): Not implemented. p %p addr 0x%lx objname %p objnamesz %zd\n",__func__,__LINE__,p,(u_long) addr,objname,objnamesz); + size_t i; + rd_loadobj_t *rdl; + + for (i = 0; i < p->nobjs; i++) { + rdl = &p->rdobjs[i]; + if (addr >= rdl->rdl_saddr && addr <= rdl->rdl_eaddr) { + strlcpy(objname, rdl->rdl_path, objnamesz); + return (objname); + } + } return (NULL); } -const prmap_t * +prmap_t * +proc_obj2map(struct proc_handle *p, const char *objname) +{ + size_t i; + prmap_t *map; + rd_loadobj_t *rdl; + char *path; + + for (i = 0; i < p->nobjs; i++) { + rdl = &p->rdobjs[i]; + path = basename(rdl->rdl_path); + if (strcmp(path, objname) == 0) { + if ((map = malloc(sizeof(*map))) == NULL) + return (NULL); + proc_rdl2prmap(rdl, map); + return (map); + } + } + return (NULL); +} + +int +proc_iter_objs(struct proc_handle *p, proc_map_f *func, void *cd) +{ + size_t i; + rd_loadobj_t *rdl; + prmap_t map; + char path[MAXPATHLEN]; + char last[MAXPATHLEN]; + + if (p->nobjs == 0) + return (-1); + memset(last, 0, sizeof(last)); + for (i = 0; i < p->nobjs; i++) { + rdl = &p->rdobjs[i]; + proc_rdl2prmap(rdl, &map); + basename_r(rdl->rdl_path, path); + /* + * We shouldn't call the callback twice with the same object. + * To do that we are assuming the fact that if there are + * repeated object names (i.e. different mappings for the + * same object) they occur next to each other. + */ + if (strcmp(path, last) == 0) + continue; + (*func)(cd, &map, path); + strlcpy(last, path, sizeof(last)); + } + + return (0); +} + +prmap_t * proc_addr2map(struct proc_handle *p, uintptr_t addr) { -printf("%s(%d): Not implemented. p %p addr 0x%lx\n",__func__,__LINE__,p,(u_long) addr); + size_t i; + int cnt, lastvn = 0; + prmap_t *map; + rd_loadobj_t *rdl; + struct kinfo_vmentry *kves, *kve; + + /* + * If we don't have a cache of listed objects, we need to query + * it ourselves. + */ + if (p->nobjs == 0) { + if ((kves = kinfo_getvmmap(p->pid, &cnt)) == NULL) + return (NULL); + for (i = 0; i < (size_t)cnt; i++) { + kve = kves + i; + if (kve->kve_type == KVME_TYPE_VNODE) + lastvn = i; + if (addr >= kve->kve_start && addr <= kve->kve_end) { + if ((map = malloc(sizeof(*map))) == NULL) { + free(kves); + return (NULL); + } + map->pr_vaddr = kve->kve_start; + map->pr_size = kve->kve_end - kve->kve_start; + map->pr_offset = kve->kve_offset; + map->pr_mflags = 0; + if (kve->kve_protection & KVME_PROT_READ) + map->pr_mflags |= MA_READ; + if (kve->kve_protection & KVME_PROT_WRITE) + map->pr_mflags |= MA_WRITE; + if (kve->kve_protection & KVME_PROT_EXEC) + map->pr_mflags |= MA_EXEC; + if (kve->kve_flags & KVME_FLAG_COW) + map->pr_mflags |= MA_COW; + if (kve->kve_flags & KVME_FLAG_NEEDS_COPY) + map->pr_mflags |= MA_NEEDS_COPY; + if (kve->kve_flags & KVME_FLAG_NOCOREDUMP) + map->pr_mflags |= MA_NOCOREDUMP; + strlcpy(map->pr_mapname, kves[lastvn].kve_path, + sizeof(map->pr_mapname)); + free(kves); + return (map); + } + } + free(kves); + return (NULL); + } + + for (i = 0; i < p->nobjs; i++) { + rdl = &p->rdobjs[i]; + if (addr >= rdl->rdl_saddr && addr <= rdl->rdl_eaddr) { + if ((map = malloc(sizeof(*map))) == NULL) + return (NULL); + proc_rdl2prmap(rdl, map); + return (map); + } + } return (NULL); } int proc_addr2sym(struct proc_handle *p, uintptr_t addr, char *name, - size_t namesz, GElf_Sym *sym) + size_t namesz, GElf_Sym *symcopy) { -printf("%s(%d): Not implemented. p %p addr 0x%lx name %p namesz %zd sym %p\n",__func__,__LINE__,p,(u_long) addr,name,namesz,sym); - return (0); + Elf *e; + Elf_Scn *scn, *dynsymscn = NULL, *symtabscn = NULL; + Elf_Data *data; + GElf_Shdr shdr; + GElf_Sym sym; + GElf_Ehdr ehdr; + int fd, error = -1; + size_t i; + uint64_t rsym; + prmap_t *map; + char *s; + unsigned long symtabstridx = 0, dynsymstridx = 0; + + if ((map = proc_addr2map(p, addr)) == NULL) + return (-1); + if (!map->pr_mapname || (fd = open(map->pr_mapname, O_RDONLY, 0)) < 0) { + warn("ERROR: open %s failed", map->pr_mapname); + goto err0; + } + if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { + warn("ERROR: elf_begin() failed"); + goto err1; + } + if (gelf_getehdr(e, &ehdr) == NULL) { + warn("ERROR: gelf_getehdr() failed"); + goto err2; + } + /* + * Find the index of the STRTAB and SYMTAB sections to locate + * symbol names. + */ + scn = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + gelf_getshdr(scn, &shdr); + switch (shdr.sh_type) { + case SHT_SYMTAB: + symtabscn = scn; + symtabstridx = shdr.sh_link; + break; + case SHT_DYNSYM: + dynsymscn = scn; + dynsymstridx = shdr.sh_link; + break; + default: + break; + } + } + /* + * Iterate over the Dynamic Symbols table to find the symbol. + * Then look up the string name in STRTAB (.dynstr) + */ + if ((data = elf_getdata(dynsymscn, NULL)) == NULL) { + DPRINTF("ERROR: elf_getdata() failed"); + goto err2; + } + i = 0; + while (gelf_getsym(data, i++, &sym) != NULL) { + /* + * Calculate the address mapped to the virtual memory + * by rtld. + */ + rsym = map->pr_vaddr + sym.st_value; + if (addr >= rsym && addr <= (rsym + sym.st_size)) { + s = elf_strptr(e, dynsymstridx, sym.st_name); + if (s) { + strlcpy(name, s, namesz); + memcpy(symcopy, &sym, sizeof(sym)); + /* + * DTrace expects the st_value to contain + * only the address relative to the start of + * the function. + */ + symcopy->st_value = rsym; + error = 0; + goto out; + } + } + } + /* + * Iterate over the Symbols Table to find the symbol. + * Then look up the string name in STRTAB (.dynstr) + */ + if (symtabscn == NULL) + goto err2; + if ((data = elf_getdata(symtabscn, NULL)) == NULL) { + DPRINTF("ERROR: elf_getdata() failed"); + goto err2; + } + i = 0; + while (gelf_getsym(data, i++, &sym) != NULL) { + /* + * Calculate the address mapped to the virtual memory + * by rtld. + */ + if (ehdr.e_type != ET_EXEC) + rsym = map->pr_vaddr + sym.st_value; + else + rsym = sym.st_value; + if (addr >= rsym && addr <= (rsym + sym.st_size)) { + s = elf_strptr(e, symtabstridx, sym.st_name); + if (s) { + strlcpy(name, s, namesz); + memcpy(symcopy, &sym, sizeof(sym)); + /* + * DTrace expects the st_value to contain + * only the address relative to the start of + * the function. + */ + symcopy->st_value = rsym; + error = 0; + goto out; + } + } + } +out: +err2: + elf_end(e); +err1: + close(fd); +err0: + free(map); + return (error); } -const prmap_t * +prmap_t * proc_name2map(struct proc_handle *p, const char *name) { -printf("%s(%d): Not implemented. p %p name %p\n",__func__,__LINE__,p,name); + size_t i; + int cnt; + prmap_t *map; + char tmppath[MAXPATHLEN]; + struct kinfo_vmentry *kves, *kve; + rd_loadobj_t *rdl; + + /* + * If we haven't iterated over the list of loaded objects, + * librtld_db isn't yet initialized and it's very likely + * that librtld_db called us. We need to do the heavy + * lifting here to find the symbol librtld_db is looking for. + */ + if (p->nobjs == 0) { + if ((kves = kinfo_getvmmap(proc_getpid(p), &cnt)) == NULL) + return (NULL); + for (i = 0; i < (size_t)cnt; i++) { + kve = kves + i; + basename_r(kve->kve_path, tmppath); + if (strcmp(tmppath, name) == 0) { + map = proc_addr2map(p, kve->kve_start); + free(kves); + return (map); + } + } + free(kves); + return (NULL); + } + if (name == NULL || strcmp(name, "a.out") == 0) { + map = proc_addr2map(p, p->rdobjs[0].rdl_saddr); + return (map); + } + for (i = 0; i < p->nobjs; i++) { + rdl = &p->rdobjs[i]; + basename_r(rdl->rdl_path, tmppath); + if (strcmp(tmppath, name) == 0) { + if ((map = malloc(sizeof(*map))) == NULL) + return (NULL); + proc_rdl2prmap(rdl, map); + return (map); + } + } + return (NULL); } int proc_name2sym(struct proc_handle *p, const char *object, const char *symbol, - GElf_Sym *sym) + GElf_Sym *symcopy) { -printf("%s(%d): Not implemented. p %p object %p symbol %p sym %p\n",__func__,__LINE__,p,object,symbol,sym); - return (0); + Elf *e; + Elf_Scn *scn, *dynsymscn = NULL, *symtabscn = NULL; + Elf_Data *data; + GElf_Shdr shdr; + GElf_Sym sym; + GElf_Ehdr ehdr; + int fd, error = -1; + size_t i; + prmap_t *map; + char *s; + unsigned long symtabstridx = 0, dynsymstridx = 0; + + if ((map = proc_name2map(p, object)) == NULL) { + DPRINTF("ERROR: couldn't find object %s", object); + goto err0; + } + if ((fd = open(map->pr_mapname, O_RDONLY, 0)) < 0) { + DPRINTF("ERROR: open %s failed", map->pr_mapname); + goto err0; + } + if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { + warn("ERROR: elf_begin() failed"); + goto err1; + } + if (gelf_getehdr(e, &ehdr) == NULL) { + warn("ERROR: gelf_getehdr() failed"); + goto err2; + } + /* + * Find the index of the STRTAB and SYMTAB sections to locate + * symbol names. + */ + scn = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + gelf_getshdr(scn, &shdr); + switch (shdr.sh_type) { + case SHT_SYMTAB: + symtabscn = scn; + symtabstridx = shdr.sh_link; + break; + case SHT_DYNSYM: + dynsymscn = scn; + dynsymstridx = shdr.sh_link; + break; + default: + break; + } + } + /* + * Iterate over the Dynamic Symbols table to find the symbol. + * Then look up the string name in STRTAB (.dynstr) + */ + if ((data = elf_getdata(dynsymscn, NULL)) == NULL) { + DPRINTF("ERROR: elf_getdata() failed"); + goto err2; + } + i = 0; + while (gelf_getsym(data, i++, &sym) != NULL) { + s = elf_strptr(e, dynsymstridx, sym.st_name); + if (s && strcmp(s, symbol) == 0) { + memcpy(symcopy, &sym, sizeof(sym)); + symcopy->st_value = map->pr_vaddr + sym.st_value; + error = 0; + goto out; + } + } + /* + * Iterate over the Symbols Table to find the symbol. + * Then look up the string name in STRTAB (.dynstr) + */ + if (symtabscn == NULL) + goto err2; + if ((data = elf_getdata(symtabscn, NULL)) == NULL) { + DPRINTF("ERROR: elf_getdata() failed"); + goto err2; + } + i = 0; + while (gelf_getsym(data, i++, &sym) != NULL) { + s = elf_strptr(e, symtabstridx, sym.st_name); + if (s && strcmp(s, symbol) == 0) { + memcpy(symcopy, &sym, sizeof(sym)); + error = 0; + goto out; + } + } +out: +err2: + elf_end(e); +err1: + close(fd); +err0: + free(map); + + return (error); +} + + +int +proc_iter_symbyaddr(struct proc_handle *p, const char *object, int which, + int mask, proc_sym_f *func, void *cd) +{ + Elf *e; + int i, fd; + prmap_t *map; + Elf_Scn *scn, *foundscn = NULL; + Elf_Data *data; + GElf_Shdr shdr; + GElf_Sym sym; + unsigned long stridx = -1; + char *s; + int error = -1; + + if ((map = proc_name2map(p, object)) == NULL) + return (-1); + if ((fd = open(map->pr_mapname, O_RDONLY)) < 0) { + warn("ERROR: open %s failed", map->pr_mapname); + goto err0; + } + if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { + warn("ERROR: elf_begin() failed"); + goto err1; + } + /* + * Find the section we are looking for. + */ + scn = NULL; + while ((scn = elf_nextscn(e, scn)) != NULL) { + gelf_getshdr(scn, &shdr); + if (which == PR_SYMTAB && + shdr.sh_type == SHT_SYMTAB) { + foundscn = scn; + break; + } else if (which == PR_DYNSYM && + shdr.sh_type == SHT_DYNSYM) { + foundscn = scn; + break; + } + } + if (!foundscn) + return (-1); + stridx = shdr.sh_link; + if ((data = elf_getdata(foundscn, NULL)) == NULL) { + DPRINTF("ERROR: elf_getdata() failed"); + goto err2; + } + i = 0; + while (gelf_getsym(data, i++, &sym) != NULL) { + if (GELF_ST_BIND(sym.st_info) == STB_LOCAL && + (mask & BIND_LOCAL) == 0) + continue; + if (GELF_ST_BIND(sym.st_info) == STB_GLOBAL && + (mask & BIND_GLOBAL) == 0) + continue; + if (GELF_ST_BIND(sym.st_info) == STB_WEAK && + (mask & BIND_WEAK) == 0) + continue; + if (GELF_ST_TYPE(sym.st_info) == STT_NOTYPE && + (mask & TYPE_NOTYPE) == 0) + continue; + if (GELF_ST_TYPE(sym.st_info) == STT_OBJECT && + (mask & TYPE_OBJECT) == 0) + continue; + if (GELF_ST_TYPE(sym.st_info) == STT_FUNC && + (mask & TYPE_FUNC) == 0) + continue; + if (GELF_ST_TYPE(sym.st_info) == STT_SECTION && + (mask & TYPE_SECTION) == 0) + continue; + if (GELF_ST_TYPE(sym.st_info) == STT_FILE && + (mask & TYPE_FILE) == 0) + continue; + s = elf_strptr(e, stridx, sym.st_name); + sym.st_value += map->pr_vaddr; + (*func)(cd, &sym, s); + } + error = 0; +err2: + elf_end(e); +err1: + close(fd); +err0: + free(map); + return (error); } diff --git a/lib/libproc/proc_util.c b/lib/libproc/proc_util.c index 0e7020efff83..089095e9ed50 100644 --- a/lib/libproc/proc_util.c +++ b/lib/libproc/proc_util.c @@ -1,6 +1,10 @@ /*- + * Copyright (c) 2010 The FreeBSD Foundation * Copyright (c) 2008 John Birrell (jb@freebsd.org) * All rights reserved. + * + * Portions of this software were developed by Rui Paulo under sponsorship + * from the FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,16 +30,21 @@ * $FreeBSD$ */ -#include "_libproc.h" -#include <errno.h> -#include <unistd.h> +#include <sys/types.h> #include <sys/ptrace.h> #include <sys/wait.h> +#include <err.h> +#include <errno.h> +#include <unistd.h> #include <stdio.h> +#include <signal.h> +#include <string.h> +#include "_libproc.h" int proc_clearflags(struct proc_handle *phdl, int mask) { + if (phdl == NULL) return (EINVAL); @@ -44,14 +53,18 @@ proc_clearflags(struct proc_handle *phdl, int mask) return (0); } +/* + * NB: we return -1 as the Solaris libproc Psetrun() function. + */ int proc_continue(struct proc_handle *phdl) { + if (phdl == NULL) - return (EINVAL); + return (-1); if (ptrace(PT_CONTINUE, phdl->pid, (caddr_t)(uintptr_t) 1, 0) != 0) - return (errno); + return (-1); phdl->status = PS_RUN; @@ -59,13 +72,25 @@ proc_continue(struct proc_handle *phdl) } int -proc_detach(struct proc_handle *phdl) +proc_detach(struct proc_handle *phdl, int reason) { + int status; + if (phdl == NULL) return (EINVAL); - - if (ptrace(PT_DETACH, phdl->pid, 0, 0) != 0) - return (errno); + if (reason == PRELEASE_KILL) { + kill(phdl->pid, SIGKILL); + return (0); + } + if (ptrace(PT_DETACH, phdl->pid, 0, 0) != 0 && errno == ESRCH) + return (0); + if (errno == EBUSY) { + kill(phdl->pid, SIGSTOP); + waitpid(phdl->pid, &status, WUNTRACED); + ptrace(PT_DETACH, phdl->pid, 0, 0); + kill(phdl->pid, SIGCONT); + return (0); + } return (0); } @@ -73,6 +98,7 @@ proc_detach(struct proc_handle *phdl) int proc_getflags(struct proc_handle *phdl) { + if (phdl == NULL) return (-1); @@ -82,6 +108,7 @@ proc_getflags(struct proc_handle *phdl) int proc_setflags(struct proc_handle *phdl, int mask) { + if (phdl == NULL) return (EINVAL); @@ -93,41 +120,105 @@ proc_setflags(struct proc_handle *phdl, int mask) int proc_state(struct proc_handle *phdl) { + if (phdl == NULL) return (-1); return (phdl->status); } -int -proc_wait(struct proc_handle *phdl) +pid_t +proc_getpid(struct proc_handle *phdl) { - int status = 0; - struct kevent kev; if (phdl == NULL) - return (EINVAL); + return (-1); - if (kevent(phdl->kq, NULL, 0, &kev, 1, NULL) <= 0) - return (0); + return (phdl->pid); +} - switch (kev.filter) { - /* Child has exited */ - case EVFILT_PROC: /* target has exited */ - phdl->status = PS_UNDEAD; - break; - default: - break; +int +proc_wstatus(struct proc_handle *phdl) +{ + int status; + + if (phdl == NULL) + return (-1); + if (waitpid(phdl->pid, &status, WUNTRACED) < 0) { + if (errno != EINTR) + warn("waitpid"); + return (-1); } + if (WIFSTOPPED(status)) + phdl->status = PS_STOP; + if (WIFEXITED(status) || WIFSIGNALED(status)) + phdl->status = PS_UNDEAD; + phdl->wstat = status; - return (status); + return (phdl->status); } -pid_t -proc_getpid(struct proc_handle *phdl) +int +proc_getwstat(struct proc_handle *phdl) { + if (phdl == NULL) return (-1); - return (phdl->pid); + return (phdl->wstat); +} + +char * +proc_signame(int sig, char *name, size_t namesz) +{ + + strlcpy(name, strsignal(sig), namesz); + + return (name); +} + +int +proc_read(struct proc_handle *phdl, void *buf, size_t size, size_t addr) +{ + struct ptrace_io_desc piod; + + if (phdl == NULL) + return (-1); + piod.piod_op = PIOD_READ_D; + piod.piod_len = size; + piod.piod_addr = (void *)buf; + piod.piod_offs = (void *)addr; + + if (ptrace(PT_IO, phdl->pid, (caddr_t)&piod, 0) < 0) + return (-1); + return (piod.piod_len); +} + +const lwpstatus_t * +proc_getlwpstatus(struct proc_handle *phdl) +{ + struct ptrace_lwpinfo lwpinfo; + lwpstatus_t *psp = &phdl->lwps; + siginfo_t *siginfo; + + if (phdl == NULL) + return (NULL); + if (ptrace(PT_LWPINFO, phdl->pid, (caddr_t)&lwpinfo, + sizeof(lwpinfo)) < 0) + return (NULL); + siginfo = &lwpinfo.pl_siginfo; + if (lwpinfo.pl_event == PL_EVENT_SIGNAL && + (lwpinfo.pl_flags & PL_FLAG_SI) && + siginfo->si_signo == SIGTRAP && + (siginfo->si_code == TRAP_BRKPT || + siginfo->si_code == TRAP_TRACE)) { + psp->pr_why = PR_FAULTED; + psp->pr_what = FLTBPT; + } else if (lwpinfo.pl_flags & PL_FLAG_SCE) { + psp->pr_why = PR_SYSENTRY; + } else if (lwpinfo.pl_flags & PL_FLAG_SCX) { + psp->pr_why = PR_SYSEXIT; + } + + return (psp); } diff --git a/lib/libproc/test/Makefile b/lib/libproc/test/Makefile new file mode 100644 index 000000000000..e4d33f82ce44 --- /dev/null +++ b/lib/libproc/test/Makefile @@ -0,0 +1,5 @@ +# $FreeBSD$ + +SUBDIR= t1-bkpt t2-name2map t3-name2sym + +.include <bsd.subdir.mk> diff --git a/lib/libproc/test/t1-bkpt/Makefile b/lib/libproc/test/t1-bkpt/Makefile new file mode 100644 index 000000000000..fd93fdd98ee8 --- /dev/null +++ b/lib/libproc/test/t1-bkpt/Makefile @@ -0,0 +1,12 @@ +# $FreeBSD$ + +PROG= t1-bkpt + +SRCS= t1-bkpt.c + +LDADD= -lproc -lelf -lrtld_db -lutil +DPADD= ${LIBPROC} ${LIBELF} + +WITHOUT_MAN= + +.include <bsd.prog.mk> diff --git a/lib/libproc/test/t1-bkpt/t1-bkpt.c b/lib/libproc/test/t1-bkpt/t1-bkpt.c new file mode 100644 index 000000000000..6b4e2fa67a9b --- /dev/null +++ b/lib/libproc/test/t1-bkpt/t1-bkpt.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Rui Paulo under sponsorship from the + * FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ +#include <sys/types.h> +#include <sys/wait.h> + +#include <assert.h> +#include <stdio.h> +#include <string.h> +#include <libproc.h> + +int +t1_bkpt_t() +{ + printf("TEST OK\n"); +} + +int +t1_bkpt_d() +{ + struct proc_handle *phdl; + char *targv[] = { "t1-bkpt-t", NULL}; + unsigned long saved; + + proc_create("./t1-bkpt", targv, NULL, NULL, &phdl); + proc_bkptset(phdl, (uintptr_t)t1_bkpt_t, &saved); + proc_continue(phdl); + assert(WIFSTOPPED(proc_wstatus(phdl))); + proc_bkptexec(phdl, saved); + proc_continue(phdl); + proc_wait(phdl); + proc_free(phdl); +} + + +int +main(int argc, char **argv) +{ + if (!strcmp(argv[0], "t1-bkpt-t")) + t1_bkpt_t(); + else + t1_bkpt_d(); +} + diff --git a/lib/libproc/test/t2-name2map/Makefile b/lib/libproc/test/t2-name2map/Makefile new file mode 100644 index 000000000000..3dca51c26c9e --- /dev/null +++ b/lib/libproc/test/t2-name2map/Makefile @@ -0,0 +1,12 @@ +# $FreeBSD$ + +PROG= t2-name2map + +SRCS= t2-name2map.c + +LDADD= -lproc -lelf -lrtld_db -lutil +DPADD= ${LIBPROC} ${LIBELF} + +WITHOUT_MAN= + +.include <bsd.prog.mk> diff --git a/lib/libproc/test/t2-name2map/t2-name2map.c b/lib/libproc/test/t2-name2map/t2-name2map.c new file mode 100644 index 000000000000..825963d3f504 --- /dev/null +++ b/lib/libproc/test/t2-name2map/t2-name2map.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Rui Paulo under sponsorship from the + * FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <sys/types.h> +#include <assert.h> +#include <stdio.h> +#include <libproc.h> + +int +main(int argc, char *argv[]) +{ + prmap_t *map = NULL; + struct proc_handle *phdl; + + proc_create("./t2-name2map", argv, NULL, NULL, &phdl); + map = proc_name2map(phdl, "ld-elf.so.1"); + assert(map); +} diff --git a/lib/libproc/test/t3-name2sym/Makefile b/lib/libproc/test/t3-name2sym/Makefile new file mode 100644 index 000000000000..187f9c1c2641 --- /dev/null +++ b/lib/libproc/test/t3-name2sym/Makefile @@ -0,0 +1,12 @@ +# $FreeBSD$ + +PROG= t3-name2sym + +SRCS= t3-name2sym.c + +LDADD= -lproc -lelf -lrtld_db -lutil +DPADD= ${LIBPROC} ${LIBELF} + +WITHOUT_MAN= + +.include <bsd.prog.mk> diff --git a/lib/libproc/test/t3-name2sym/t3-name2sym.c b/lib/libproc/test/t3-name2sym/t3-name2sym.c new file mode 100644 index 000000000000..6d90a48af71f --- /dev/null +++ b/lib/libproc/test/t3-name2sym/t3-name2sym.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2010 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Rui Paulo under sponsorship from the + * FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ +#include <sys/types.h> +#include <assert.h> +#include <stdio.h> +#include <libproc.h> +#include <gelf.h> + +int +main(int argc, char *argv[]) +{ + prmap_t *map = NULL; + struct proc_handle *phdl; + GElf_Sym sym; + + proc_create("./t3-name2sym", argv, NULL, NULL, &phdl); + memset(&sym, 0, sizeof(sym)); + assert(proc_name2sym(phdl, "ld-elf.so.1", "r_debug_state", &sym) == 0); + printf("0x%lx\n", sym.st_value); + assert(proc_name2sym(phdl, "t3-name2sym", "main", &sym) == 0); + printf("0x%lx\n", sym.st_value); +} diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h index 82b97a373682..1e20f5665408 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h @@ -1322,15 +1322,24 @@ typedef struct { * helpers and should no longer be used. No other ioctls are valid on the * helper minor node. */ +#if defined(sun) #define DTRACEHIOC (('d' << 24) | ('t' << 16) | ('h' << 8)) #define DTRACEHIOC_ADD (DTRACEHIOC | 1) /* add helper */ #define DTRACEHIOC_REMOVE (DTRACEHIOC | 2) /* remove helper */ #define DTRACEHIOC_ADDDOF (DTRACEHIOC | 3) /* add helper DOF */ +#else +#define DTRACEHIOC_ADD _IOWR('z', 1, dof_hdr_t)/* add helper */ +#define DTRACEHIOC_REMOVE _IOW('z', 2, int) /* remove helper */ +#define DTRACEHIOC_ADDDOF _IOWR('z', 3, dof_helper_t)/* add helper DOF */ +#endif typedef struct dof_helper { char dofhp_mod[DTRACE_MODNAMELEN]; /* executable or library name */ uint64_t dofhp_addr; /* base address of object */ uint64_t dofhp_dof; /* address of helper DOF */ +#if !defined(sun) + int gen; +#endif } dof_helper_t; #define DTRACEMNR_DTRACE "dtrace" /* node for DTrace ops */ @@ -2219,10 +2228,11 @@ extern void dtrace_vtime_enable(void); extern void dtrace_vtime_disable(void); struct regs; +struct reg; #if defined(sun) -extern int (*dtrace_pid_probe_ptr)(struct regs *); -extern int (*dtrace_return_probe_ptr)(struct regs *); +extern int (*dtrace_pid_probe_ptr)(struct reg *); +extern int (*dtrace_return_probe_ptr)(struct reg *); extern void (*dtrace_fasttrap_fork_ptr)(proc_t *, proc_t *); extern void (*dtrace_fasttrap_exec_ptr)(proc_t *); extern void (*dtrace_fasttrap_exit_ptr)(proc_t *); |
