From 936e6e30dc8c5d7cfeb8b9b9c2fbe75cbbec1eb9 Mon Sep 17 00:00:00 2001 From: rpaulo Date: Mon, 8 Nov 2010 12:54:55 +0000 Subject: [PATCH] MFC r210688 r210689 r210694 r211184 r212831 r210682 r210683 r210690 r209539 r210199 r210237 r210692 r210695 r210767 r210775 r210776 r211545 r211554 r211562 r212092 r212358 r212414 r212462 r212495 r210693 r211547 r211550 r211554 r211561 r211577 r210691 r210697 r211563 r211564 r211841 r211842 r211562 r212649 r211187 r211555: Userland DTrace MFC. This only includes the userland side of userland DTrace. git-svn-id: svn://svn.freebsd.org/base/stable/8@214983 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- cddl/contrib/dtracetoolkit/dtruss | 467 ++++++++ cddl/contrib/opensolaris/cmd/dtrace/dtrace.c | 24 +- .../cmd/dtrace/test/cmd/baddof/baddof.c | 6 +- .../cmd/dtrace/test/cmd/chkargs/chkargs.c | 17 +- .../cmd/dtrace/test/cmd/scripts/dstyle.pl | 5 +- .../cmd/dtrace/test/cmd/scripts/dtest.pl | 29 +- .../aggs/err.D_AGG_SCALAR.stddevtoofew.d | 41 + .../common/aggs/err.D_PROTO_LEN.stddevnoarg.d | 41 + .../aggs/err.D_PROTO_LEN.stddevtoomany.d | 41 + .../test/tst/common/aggs/tst.clearstddev.d | 57 + .../tst/common/aggs/tst.clearstddev.d.out | 2 + .../test/tst/common/aggs/tst.multiaggs1.d | 14 +- .../test/tst/common/aggs/tst.multiaggs2.d | 9 +- .../test/tst/common/aggs/tst.multiaggs2.d.out | 1 + .../test/tst/common/aggs/tst.multiaggs3.d | 12 +- .../test/tst/common/aggs/tst.multiaggs3.d.out | 1 + .../dtrace/test/tst/common/aggs/tst.stddev.d | 10 +- .../test/tst/common/aggs/tst.stddev.d.out | 2 +- .../dtrace/test/tst/common/aggs/tst.subr.d | 1 - .../tst/common/assocs/tst.orthogonality.d | 4 +- .../cpc/err.D_PDESC_ZERO.lowfrequency.d | 45 + .../cpc/err.D_PDESC_ZERO.malformedoverflow.d | 40 + .../cpc/err.D_PDESC_ZERO.nonexistentevent.d | 40 + .../tst/common/cpc/err.cpcvscpustatpart1.ksh | 78 ++ .../tst/common/cpc/err.cpcvscpustatpart2.ksh | 70 ++ .../common/cpc/err.cputrackfailtostart.ksh | 77 ++ .../tst/common/cpc/err.cputrackterminates.ksh | 70 ++ .../tst/common/cpc/err.toomanyenablings.d | 55 + .../test/tst/common/cpc/tst.allcpus.ksh | 107 ++ .../test/tst/common/cpc/tst.genericevent.d | 48 + .../test/tst/common/cpc/tst.platformevent.ksh | 81 ++ .../common/dtraceUtil/tst.AddSearchPath.d.ksh | 2 +- .../dtraceUtil/tst.DestructWithModule.d.ksh | 2 +- .../dtraceUtil/tst.ELFGenerationOut.d.ksh | 2 +- .../dtraceUtil/tst.ELFGenerationWithO.d.ksh | 2 +- .../tst.PreprocessorStatement.d.ksh | 1 - .../common/funcs/err.D_PROTO_LEN.motoofew.d | 2 +- .../common/funcs/err.D_PROTO_LEN.motoomany.d | 2 +- .../common/funcs/err.D_PROTO_LEN.mtatoofew.d | 2 +- .../common/funcs/err.D_PROTO_LEN.mtatoomany.d | 2 +- .../dtrace/test/tst/common/funcs/tst.index.d | 2 +- .../test/tst/common/ip/get.ipv4remote.pl | 104 ++ .../test/tst/common/ip/get.ipv6remote.pl | 88 ++ .../test/tst/common/ip/tst.ipv4localicmp.ksh | 70 ++ .../tst/common/ip/tst.ipv4localicmp.ksh.out | 6 + .../test/tst/common/ip/tst.ipv4localtcp.ksh | 125 ++ .../tst/common/ip/tst.ipv4localtcp.ksh.out | 7 + .../test/tst/common/ip/tst.ipv4localudp.ksh | 93 ++ .../tst/common/ip/tst.ipv4localudp.ksh.out | 6 + .../test/tst/common/ip/tst.ipv4remoteicmp.ksh | 81 ++ .../tst/common/ip/tst.ipv4remoteicmp.ksh.out | 3 + .../test/tst/common/ip/tst.ipv4remotetcp.ksh | 128 +++ .../tst/common/ip/tst.ipv4remotetcp.ksh.out | 7 + .../test/tst/common/ip/tst.ipv4remoteudp.ksh | 88 ++ .../tst/common/ip/tst.ipv4remoteudp.ksh.out | 5 + .../test/tst/common/ip/tst.ipv6localicmp.ksh | 82 ++ .../tst/common/ip/tst.ipv6localicmp.ksh.out | 6 + .../test/tst/common/ip/tst.ipv6remoteicmp.ksh | 88 ++ .../tst/common/ip/tst.ipv6remoteicmp.ksh.out | 3 + .../test/tst/common/ip/tst.localtcpstate.ksh | 182 +++ .../tst/common/ip/tst.localtcpstate.ksh.out | 18 + .../test/tst/common/ip/tst.remotetcpstate.ksh | 172 +++ .../tst/common/ip/tst.remotetcpstate.ksh.out | 15 + .../java_api/src/TestFunctionLookup.java | 6 +- .../common/java_api/src/TestGetAggregate.java | 252 ++++ .../java_api/tst.FunctionLookup.ksh.out | 2 +- .../tst/common/java_api/tst.GetAggregate.ksh | 36 + .../test/tst/common/misc/tst.include.ksh | 2 +- .../test/tst/common/misc/tst.macroglob.ksh | 41 + .../tst/common/misc/tst.macroglob.ksh.out | 15 + .../test/tst/common/misc/tst.schrock.ksh | 2 +- .../common/pid/err.D_PDESC_ZERO.badlib.exe | 29 + .../common/pid/err.D_PROC_CREATEFAIL.many.exe | 29 + .../common/pid/err.D_PROC_FUNC.badfunc.exe | 29 + .../tst/common/pid/err.D_PROC_LIB.libdash.exe | 29 + .../common/pid/err.D_PROC_NAME.alldash.exe | 29 + .../common/pid/err.D_PROC_NAME.badname.exe | 29 + .../common/pid/err.D_PROC_NAME.globdash.exe | 29 + .../tst/common/pid/err.D_PROC_OFF.toobig.exe | 29 + .../test/tst/common/pid/tst.coverage.exe | 29 + .../test/tst/common/pid/tst.emptystack.exe | 29 + .../cmd/dtrace/test/tst/common/pid/tst.fork.c | 2 +- .../cmd/dtrace/test/tst/common/pid/tst.gcc.c | 3 +- .../test/tst/common/pid/tst.killonerror.ksh | 41 + .../test/tst/common/pid/tst.probemod.ksh | 6 +- .../test/tst/common/pid/tst.provregex1.ksh | 2 +- .../test/tst/common/pid/tst.provregex2.ksh | 2 +- .../test/tst/common/pid/tst.provregex3.ksh | 2 +- .../test/tst/common/pid/tst.provregex4.ksh | 2 +- .../tst/common/plockstat/tst.available.exe | 29 + .../test/tst/common/plockstat/tst.libmap.exe | 29 + .../test/tst/common/printa/tst.basics.d | 8 +- .../test/tst/common/printa/tst.basics.d.out | 1 + .../tst/common/printa/tst.largeusersym.ksh | 83 ++ .../tst/common/printa/tst.walltimestamp.ksh | 2 +- .../test/tst/common/printf/tst.printT.ksh | 2 +- .../test/tst/common/printf/tst.printY.ksh | 2 +- .../dtrace/test/tst/common/printf/tst.str.d | 6 +- .../test/tst/common/printf/tst.str.d.out | 2 +- .../dtrace/test/tst/common/printf/tst.sym.d | 2 +- .../test/tst/common/printf/tst.sym.d.out | 2 +- .../dtrace/test/tst/common/proc/tst.exec.ksh | 2 +- .../tst/common/proc/tst.execfail.ENOENT.ksh | 2 +- .../test/tst/common/proc/tst.execfail.ksh | 2 +- .../dtrace/test/tst/common/proc/tst.sigwait.d | 4 +- .../scripting/tst.D_MACRO_UNUSED.overflow.ksh | 6 +- .../tst/common/scripting/tst.arguments.ksh | 4 +- .../test/tst/common/scripting/tst.egid.ksh | 8 +- .../test/tst/common/scripting/tst.euid.ksh | 2 +- .../test/tst/common/scripting/tst.gid.ksh | 2 +- .../test/tst/common/scripting/tst.ppid.ksh | 2 +- .../test/tst/common/scripting/tst.projid.ksh | 2 +- .../test/tst/common/scripting/tst.sid.ksh | 2 +- .../tst/common/scripting/tst.stringmacro.ksh | 2 +- .../test/tst/common/scripting/tst.taskid.ksh | 2 +- .../test/tst/common/scripting/tst.uid.ksh | 2 +- .../dtrace/test/tst/common/sdt/tst.sdtargs.c | 51 + .../dtrace/test/tst/common/sdt/tst.sdtargs.d | 67 ++ .../err.D_AGG_SPEC.SpeculateWithStddev.d | 65 ++ .../test/tst/common/sysevent/tst.post_chan.c | 6 +- .../cmd/dtrace/test/tst/common/usdt/Makefile | 13 + .../cmd/dtrace/test/tst/common/usdt/main.c | 11 + .../cmd/dtrace/test/tst/common/usdt/prov.d | 3 + .../cmd/dtrace/test/tst/common/usdt/prov.h | 46 + .../test/tst/common/usdt/tst.badguess.ksh | 2 +- .../test/tst/common/usdt/tst.corruptenv.ksh | 107 ++ .../test/tst/common/usdt/tst.dlclose1.ksh | 4 +- .../test/tst/common/usdt/tst.dlclose2.ksh | 4 +- .../test/tst/common/usdt/tst.dlclose3.ksh | 4 +- .../test/tst/common/usdt/tst.eliminate.ksh | 2 +- .../test/tst/common/usdt/tst.enabled.ksh | 2 +- .../test/tst/common/usdt/tst.enabled2.ksh | 113 ++ .../test/tst/common/usdt/tst.enabled2.ksh.out | 3 + .../test/tst/common/usdt/tst.entryreturn.ksh | 2 +- .../dtrace/test/tst/common/usdt/tst.fork.ksh | 2 +- .../test/tst/common/usdt/tst.guess32.ksh | 2 +- .../test/tst/common/usdt/tst.guess64.ksh | 2 +- .../test/tst/common/usdt/tst.header.ksh | 2 +- .../test/tst/common/usdt/tst.include.ksh | 2 +- .../test/tst/common/usdt/tst.linkpriv.ksh | 2 +- .../test/tst/common/usdt/tst.linkunpriv.ksh | 2 +- .../test/tst/common/usdt/tst.multiple.ksh | 2 +- .../test/tst/common/usdt/tst.nodtrace.ksh | 2 +- .../test/tst/common/usdt/tst.onlyenabled.ksh | 2 +- .../test/tst/common/usdt/tst.reeval.ksh | 2 +- .../test/tst/common/usdt/tst.static.ksh | 2 +- .../test/tst/common/usdt/tst.static2.ksh | 2 +- .../dtrace/test/tst/common/usdt/tst.user.ksh | 2 +- .../test/tst/common/vars/tst.ucaller.ksh | 2 +- .../test/tst/i386/funcs/tst.badcopyin.d | 9 +- .../dtrace/test/tst/i86xpv/xdt/tst.basic.ksh | 77 ++ .../test/tst/i86xpv/xdt/tst.hvmenable.ksh | 64 ++ .../test/tst/i86xpv/xdt/tst.memenable.ksh | 65 ++ .../test/tst/i86xpv/xdt/tst.schedargs.ksh | 121 ++ .../test/tst/i86xpv/xdt/tst.schedenable.ksh | 74 ++ .../sparc/pid/err.D_PROC_ALIGN.misaligned.exe | 29 + .../test/tst/sparc/usdt/tst.tailcall.ksh | 4 +- .../opensolaris/cmd/plockstat/plockstat.c | 1021 +++++++++++++++++ cddl/contrib/opensolaris/common/avl/avl.c | 71 +- .../opensolaris/lib/libdtrace/common/drti.c | 181 ++- .../lib/libdtrace/common/dt_aggregate.c | 9 +- .../opensolaris/lib/libdtrace/common/dt_cc.c | 13 +- .../lib/libdtrace/common/dt_consume.c | 33 +- .../opensolaris/lib/libdtrace/common/dt_dof.c | 7 +- .../lib/libdtrace/common/dt_error.c | 7 +- .../lib/libdtrace/common/dt_impl.h | 25 +- .../opensolaris/lib/libdtrace/common/dt_lex.l | 9 +- .../lib/libdtrace/common/dt_link.c | 205 +++- .../lib/libdtrace/common/dt_module.c | 33 +- .../lib/libdtrace/common/dt_open.c | 25 +- .../opensolaris/lib/libdtrace/common/dt_pid.c | 96 +- .../lib/libdtrace/common/dt_printf.c | 85 +- .../lib/libdtrace/common/dt_proc.c | 179 ++- .../lib/libdtrace/common/dt_proc.h | 2 - .../lib/libdtrace/common/dt_program.c | 18 +- .../lib/libdtrace/common/dt_string.c | 15 +- .../lib/libdtrace/common/dt_subr.c | 36 +- .../opensolaris/lib/libdtrace/common/dtrace.h | 3 + .../lib/libdtrace/common/mkerrno.sh | 40 + .../lib/libdtrace/common/mksignal.sh | 40 + .../lib/libdtrace/i386/dt_isadep.c | 532 +++++++++ .../opensolaris/lib/libdtrace/i386/regs.d.in | 117 ++ .../lib/libdtrace/i386/regs.sed.in | 82 ++ .../lib/libdtrace/sparc/dt_isadep.c | 338 ++++++ .../opensolaris/lib/libdtrace/sparc/regs.d | 120 ++ .../opensolaris/lib/libgen/common/gmatch.c | 31 +- cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c | 27 +- .../opensolaris/tools/ctf/cvt/ctfmerge.c | 30 +- .../opensolaris/tools/ctf/cvt/ctfmerge.h | 9 +- .../opensolaris/tools/ctf/cvt/st_parse.c | 34 +- .../contrib/opensolaris/tools/ctf/cvt/tdata.c | 9 +- cddl/lib/Makefile | 9 +- cddl/lib/drti/Makefile | 3 +- cddl/lib/libdtrace/Makefile | 16 +- cddl/lib/libdtrace/libproc_compat.h | 62 + cddl/lib/libdtrace/regs_x86.d | 121 ++ cddl/usr.bin/ctfconvert/Makefile | 3 - cddl/usr.bin/ctfconvert/ctfconvert.1 | 85 ++ cddl/usr.bin/ctfdump/Makefile | 3 - cddl/usr.bin/ctfdump/ctfdump.1 | 83 ++ cddl/usr.bin/ctfmerge/Makefile | 3 - cddl/usr.bin/ctfmerge/ctfmerge.1 | 120 ++ cddl/usr.sbin/Makefile | 11 +- cddl/usr.sbin/dtrace/Makefile | 13 +- cddl/usr.sbin/dtruss/Makefile | 8 + cddl/usr.sbin/dtruss/dtruss.1 | 89 ++ cddl/usr.sbin/lockstat/Makefile | 14 +- cddl/usr.sbin/plockstat/Makefile | 26 + cddl/usr.sbin/plockstat/plockstat.1 | 95 ++ lib/libproc/Makefile | 4 +- lib/libproc/_libproc.h | 12 + lib/libproc/libproc.h | 84 +- lib/libproc/proc_bkpt.c | 184 +++ lib/libproc/proc_create.c | 61 +- lib/libproc/proc_regs.c | 113 ++ lib/libproc/proc_rtld.c | 80 ++ lib/libproc/proc_sym.c | 520 ++++++++- lib/libproc/proc_util.c | 145 ++- lib/libproc/test/Makefile | 5 + lib/libproc/test/t1-bkpt/Makefile | 12 + lib/libproc/test/t1-bkpt/t1-bkpt.c | 71 ++ lib/libproc/test/t2-name2map/Makefile | 12 + lib/libproc/test/t2-name2map/t2-name2map.c | 46 + lib/libproc/test/t3-name2sym/Makefile | 12 + lib/libproc/test/t3-name2sym/t3-name2sym.c | 50 + .../opensolaris/uts/common/sys/dtrace.h | 14 +- 226 files changed, 9814 insertions(+), 644 deletions(-) create mode 100755 cddl/contrib/dtracetoolkit/dtruss mode change 100644 => 100755 cddl/contrib/opensolaris/cmd/dtrace/test/cmd/scripts/dstyle.pl mode change 100644 => 100755 cddl/contrib/opensolaris/cmd/dtrace/test/cmd/scripts/dtest.pl create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_AGG_SCALAR.stddevtoofew.d create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.stddevnoarg.d create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/err.D_PROTO_LEN.stddevtoomany.d create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearstddev.d create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/aggs/tst.clearstddev.d.out create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.D_PDESC_ZERO.lowfrequency.d create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.D_PDESC_ZERO.malformedoverflow.d create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.D_PDESC_ZERO.nonexistentevent.d create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cpcvscpustatpart1.ksh create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cpcvscpustatpart2.ksh create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cputrackfailtostart.ksh create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.cputrackterminates.ksh create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/err.toomanyenablings.d create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/tst.allcpus.ksh create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/tst.genericevent.d create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/cpc/tst.platformevent.ksh create mode 100755 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv4remote.pl create mode 100755 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/get.ipv6remote.pl create mode 100755 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localicmp.ksh create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localicmp.ksh.out create mode 100755 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh.out create mode 100755 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh.out create mode 100755 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteicmp.ksh create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteicmp.ksh.out create mode 100755 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh.out create mode 100755 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh.out create mode 100755 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6localicmp.ksh create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6localicmp.ksh.out create mode 100755 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6remoteicmp.ksh create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.ipv6remoteicmp.ksh.out create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh.out create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh.out create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/src/TestGetAggregate.java create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/java_api/tst.GetAggregate.ksh create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.macroglob.ksh create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/misc/tst.macroglob.ksh.out create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PDESC_ZERO.badlib.exe create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_CREATEFAIL.many.exe create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_FUNC.badfunc.exe create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_LIB.libdash.exe create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.alldash.exe create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.badname.exe create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_NAME.globdash.exe create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/err.D_PROC_OFF.toobig.exe create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.coverage.exe create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.emptystack.exe create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/pid/tst.killonerror.ksh create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/plockstat/tst.available.exe create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/plockstat/tst.libmap.exe create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/printa/tst.largeusersym.ksh create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.c create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.d create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/speculation/err.D_AGG_SPEC.SpeculateWithStddev.d create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/Makefile create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/main.c create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/prov.d create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/prov.h create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.corruptenv.ksh create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled2.ksh create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.enabled2.ksh.out create mode 100755 cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.basic.ksh create mode 100755 cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.hvmenable.ksh create mode 100755 cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.memenable.ksh create mode 100755 cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.schedargs.ksh create mode 100755 cddl/contrib/opensolaris/cmd/dtrace/test/tst/i86xpv/xdt/tst.schedenable.ksh create mode 100644 cddl/contrib/opensolaris/cmd/dtrace/test/tst/sparc/pid/err.D_PROC_ALIGN.misaligned.exe create mode 100644 cddl/contrib/opensolaris/cmd/plockstat/plockstat.c create mode 100755 cddl/contrib/opensolaris/lib/libdtrace/common/mkerrno.sh create mode 100755 cddl/contrib/opensolaris/lib/libdtrace/common/mksignal.sh create mode 100644 cddl/contrib/opensolaris/lib/libdtrace/i386/dt_isadep.c create mode 100644 cddl/contrib/opensolaris/lib/libdtrace/i386/regs.d.in create mode 100644 cddl/contrib/opensolaris/lib/libdtrace/i386/regs.sed.in create mode 100644 cddl/contrib/opensolaris/lib/libdtrace/sparc/dt_isadep.c create mode 100644 cddl/contrib/opensolaris/lib/libdtrace/sparc/regs.d create mode 100644 cddl/lib/libdtrace/libproc_compat.h create mode 100644 cddl/lib/libdtrace/regs_x86.d create mode 100644 cddl/usr.bin/ctfconvert/ctfconvert.1 create mode 100644 cddl/usr.bin/ctfdump/ctfdump.1 create mode 100644 cddl/usr.bin/ctfmerge/ctfmerge.1 create mode 100644 cddl/usr.sbin/dtruss/Makefile create mode 100644 cddl/usr.sbin/dtruss/dtruss.1 create mode 100644 cddl/usr.sbin/plockstat/Makefile create mode 100644 cddl/usr.sbin/plockstat/plockstat.1 create mode 100644 lib/libproc/proc_bkpt.c create mode 100644 lib/libproc/proc_regs.c create mode 100644 lib/libproc/proc_rtld.c create mode 100644 lib/libproc/test/Makefile create mode 100644 lib/libproc/test/t1-bkpt/Makefile create mode 100644 lib/libproc/test/t1-bkpt/t1-bkpt.c create mode 100644 lib/libproc/test/t2-name2map/Makefile create mode 100644 lib/libproc/test/t2-name2map/t2-name2map.c create mode 100644 lib/libproc/test/t3-name2sym/Makefile create mode 100644 lib/libproc/test/t3-name2sym/t3-name2sym.c diff --git a/cddl/contrib/dtracetoolkit/dtruss b/cddl/contrib/dtracetoolkit/dtruss new file mode 100755 index 000000000..f4b5e45a3 --- /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 2580e6323..63721abc7 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 679ec53d8..1c14c6592 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 #include #include @@ -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 36042e3f7..a7e0222fd 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 #include #include @@ -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 old mode 100644 new mode 100755 index cb47c7cbf..3c3e180a0 --- 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 old mode 100644 new mode 100755 index e8d9032fc..7b47580dd --- 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 000000000..262040f1b --- /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 000000000..2952cf50c --- /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 000000000..c42e9628c --- /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 000000000..af3ecd56a --- /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 000000000..8d23188fd --- /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 80cffd4c9..c65fb529e 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 21c05b8e8..b34d73fa8 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 2e84e08ea..579f78dd9 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 0685c0dac..21d2fa9e2 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 b0c49a33d..ab976601b 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 11e99d390..041b82070 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 cec607408..0c02852e4 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 5ca1f1ef9..d508596a9 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 #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 f474a5720..3a7d6a2c6 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 000000000..1015a251c --- /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 000000000..f9b780942 --- /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 000000000..73f9575fb --- /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 000000000..767d493a7 --- /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 <' + 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 000000000..584469c3f --- /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 <' + 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 000000000..f62b83d57 --- /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 <' + 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 000000000..58d1e798f --- /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 < 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 000000000..a50bd71ae --- /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 000000000..7f026c9eb --- /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 < 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 000000000..7ebf844e9 --- /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 000000000..96d1ab8c6 --- /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: " + 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 () { + 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 2f49f733e..b36f1e4c1 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 923be51c6..8ab32fdb4 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 b68fc1387..a4f4670c0 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 ec38b5028..503dd50e0 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 182466f4f..e4d093e4f 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 < 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 e878713ab..cf4dd5e0e 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 d3b9ed486..6cc4be03f 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 98bc5c931..61d967a5b 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 e4f259a7e..f2c3178e3 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 547730a14..1ec96978a 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 000000000..128263eae --- /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 () { + next if /^lo/; + + # "UP" is always printed first (see print_flags() in ifconfig.c): + $up = 1 if /^[a-z].*) { + 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 000000000..837ca3c79 --- /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 () { + next if /^lo/; + + # "UP" is always printed first (see print_flags() in ifconfig.c): + $up = 1 if /^[a-z].*) { + 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 000000000..0f2b64a2d --- /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: " + exit 2 +fi + +dtrace=$1 +local=127.0.0.1 + +$dtrace -c "/sbin/ping $local 3" -qs /dev/stdin <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 000000000..41d6e0c8a --- /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 000000000..c18dc7625 --- /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: " + 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 <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 000000000..2a85b98b6 --- /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 000000000..6d08e24a9 --- /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: " + exit 2 +fi + +dtrace=$1 +local=127.0.0.1 + +$dtrace -c "/sbin/ping -U $local" -qs /dev/stdin <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 000000000..bca55327e --- /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 000000000..87553ea71 --- /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: " + 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 <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 000000000..b5915f8db --- /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 000000000..e513ace0b --- /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: " + 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 <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 000000000..2a85b98b6 --- /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 000000000..cc7a32c55 --- /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: " + 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 <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 000000000..bdbbe1fd6 --- /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 000000000..f63d1ed76 --- /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: " + 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 <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 000000000..529d251fa --- /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 000000000..c859e6bfe --- /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: " + 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 <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 000000000..1ddcd07b3 --- /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 000000000..5e0c74740 --- /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: " + 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 <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 000000000..ea1c27e50 --- /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 000000000..4bf4362b6 --- /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: " + 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 <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 000000000..27388fba6 --- /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 3488903c1..2bc43ea6f 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 000000000..e02df8582 --- /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 included = new HashSet (); + 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 firstValues = new HashMap (); + Set cleared = new HashSet (); + + 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 400064d8e..d42e9b59b 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 000000000..2fdd5a9ea --- /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 ec328021b..30a2ce417 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 000000000..a5114f491 --- /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 000000000..8a9ac6d96 --- /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 494f6f8e6..197bd8dd5 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 < /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 000000000..a8bc8cb35 --- /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 d5e90dbc9..8c2772396 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 b97fa9d1a..69df4723d 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 #include +#include 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 000000000..587878c3f --- /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 2565b503d..326fd1ab9 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 892ff3e24..7b0824eed 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 8d83bddd2..8951cb381 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 c9ac6b1dd..49e362b33 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 278ec1281..865b9bbee 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 000000000..221e8b1d7 --- /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 000000000..221e8b1d7 --- /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 e7de2d389..f53538708 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 a3d46a982..ddad2134d 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 000000000..7d8bd39af --- /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 < 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 bb0d5a0f6..69bf46b53 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 <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 5dbce13e0..995eb0562 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 3b2dbb39a..7fb3faaed 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 fd6baffdc..bb8281902 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 0f4e14552..cc1e6dd9f 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 deb644a50..6ec078abf 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 9e1955f29..afee24f83 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 7112b2578..1b6b9b3e0 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 83955db14..332b8e70d 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 4a74ee428..bbd9a5364 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 da60ea1d6..62bc817af 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 d1e122c13..477ebc029 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 6903cb1cd..724bd5fda 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 54392d23d..88b450d38 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 2630f2f94..fabf0eda7 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 000000000..e2e9505fb --- /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 +#ifndef __FreeBSD__ +#include +#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 000000000..0523de095 --- /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 000000000..22953c2a5 --- /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 8394716af..4a452a7ad 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 #include @@ -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 000000000..77fe870aa --- /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 000000000..9dc0a0e63 --- /dev/null +++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/main.c @@ -0,0 +1,11 @@ +#include +#include +#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 000000000..53e5ef398 --- /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 000000000..e29654edb --- /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 + +#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 291fe83fa..91b6cf06f 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 000000000..68dbb0345 --- /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: ' + 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 < prov.d < main.c < +#include +#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 0a6666628..1c155febb 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 c83d8bfa8..107707ede 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 72f24ce5e..a750b59e1 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 687e435e3..96b05d5cd 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 ba62be75a..d0ac18648 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 000000000..d40036d8c --- /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 < test.c < +#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 <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 d5b8c24aa..f14c8afc8 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 000000000..3a5ce6f0d --- /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 <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 000000000..3719c2026 --- /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 <' + 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 <' + 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 < 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 000000000..54c3352ea --- /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 < +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 = ""; + + 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 7403e8130..dd39c12d2 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 c983c5b59..7a14dd38d 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 #include #include @@ -37,6 +34,8 @@ #include #include #include +#include +#include /* * 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 ac32f769a..f6c9622c6 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 #else #include +#include #endif #include @@ -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 8bd09151d..5250641b5 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 776fd17c0..911478ee0 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 #include #include @@ -36,6 +34,9 @@ #include #endif #include +#if !defined(sun) +#include +#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 f35a386c5..6ed9480ec 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 #if defined(sun) #include @@ -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 263f70c85..a28505c12 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 #include #include @@ -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 a712d2495..bfdaecd0b 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 #include #if !defined(sun) @@ -42,6 +40,9 @@ #include #include #include +#if defined(sun) +#include +#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 48975274d..90feceaa5 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 #include @@ -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 aa78658b5..ca355eacd 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 #else #include +#include +#include +#include #endif #include #include @@ -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 d33fb95e4..497faa995 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 #if defined(sun) #include @@ -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 483082268..962da1a88 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 #if defined(sun) #include @@ -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 5640b4af0..b145818db 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 #include #include @@ -42,6 +40,9 @@ #include #include #include +#if !defined(sun) +#include +#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 8e45a9135..2619818b5 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 #else @@ -41,6 +38,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include @@ -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)); } @@ -505,6 +507,58 @@ pfprint_time822(dtrace_hdl_t *dtp, FILE *fp, const char *format, return (dt_printf(dtp, fp, format, buf)); } +/*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, @@ -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 }, @@ -1236,6 +1292,20 @@ pfprint_average(dtrace_hdl_t *dtp, FILE *fp, const char *format, data[0] ? data[1] / normal / data[0] : 0)); } +/*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, @@ -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 f420a0c2b..664a1225b 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 #include -#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 +#include +#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 b469f55b8..d1fc76523 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 e4fa8011f..b110df396 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 #include #include @@ -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 \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 02fa50720..3a5315eef 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 #include #include #include #include +#include /* * 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 12f186ae5..f4eadbc4f 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 #endif @@ -42,6 +40,7 @@ #include #else #include +#include #endif #include #include @@ -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 00b32eebf..13c27765b 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h @@ -34,6 +34,9 @@ #include #include #include +#if !defined(sun) +#include +#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 000000000..50b7f1c1b --- /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 000000000..1bffa6468 --- /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 000000000..ad1c0324d --- /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 +#include +#include +#include +#include + +#include +#include + +#include + +#if !defined(sun) +#define PR_MODEL_ILP32 1 +#define PR_MODEL_LP64 2 +#include +#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 */ + if (size == 3 && text[i] == DT_RET16) + goto is_ret; + + /* two-byte ret */ + 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 000000000..3328f3351 --- /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 000000000..2b2080fc9 --- /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 + +#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 000000000..ed05275e7 --- /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 +#include +#include +#include +#include + +#include +#include + +#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 000000000..7c4bc0fac --- /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 cfd66e862..fe4a3825a 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 @@ -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 d95dd1db1..e3ec1e1bf 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 546dcdfc9..fa4fbebb4 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 38560eab6..ce40803d5 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 53643204c..1dca82a0d 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 4a0cc7960..1ccd6cde5 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 5e995f4b6..52e97d74b 100644 --- a/cddl/lib/Makefile +++ b/cddl/lib/Makefile @@ -2,10 +2,10 @@ .include -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 diff --git a/cddl/lib/drti/Makefile b/cddl/lib/drti/Makefile index 4be57a54b..faa016951 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 diff --git a/cddl/lib/libdtrace/Makefile b/cddl/lib/libdtrace/Makefile index 071d9504c..86ec23a0d 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 000000000..a561157c0 --- /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 000000000..7dce19717 --- /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 57a08dd04..ff9432265 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 diff --git a/cddl/usr.bin/ctfconvert/ctfconvert.1 b/cddl/usr.bin/ctfconvert/ctfconvert.1 new file mode 100644 index 000000000..584463266 --- /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 9a65c15ef..5231d9499 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 diff --git a/cddl/usr.bin/ctfdump/ctfdump.1 b/cddl/usr.bin/ctfdump/ctfdump.1 new file mode 100644 index 000000000..d64a88a60 --- /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 051fa0b43..35b1d0607 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 diff --git a/cddl/usr.bin/ctfmerge/ctfmerge.1 b/cddl/usr.bin/ctfmerge/ctfmerge.1 new file mode 100644 index 000000000..47151d6a1 --- /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 f7c32f38f..49db06b61 100644 --- a/cddl/usr.sbin/Makefile +++ b/cddl/usr.sbin/Makefile @@ -2,8 +2,9 @@ .include -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 diff --git a/cddl/usr.sbin/dtrace/Makefile b/cddl/usr.sbin/dtrace/Makefile index 44116fcbc..9e8e34835 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 diff --git a/cddl/usr.sbin/dtruss/Makefile b/cddl/usr.sbin/dtruss/Makefile new file mode 100644 index 000000000..39161ec0f --- /dev/null +++ b/cddl/usr.sbin/dtruss/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../../cddl/contrib/dtracetoolkit + +SCRIPTS=dtruss +MAN=dtruss.1 + +.include diff --git a/cddl/usr.sbin/dtruss/dtruss.1 b/cddl/usr.sbin/dtruss/dtruss.1 new file mode 100644 index 000000000..d408e81bd --- /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 9c135f912..98732934f 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 000000000..059295898 --- /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 diff --git a/cddl/usr.sbin/plockstat/plockstat.1 b/cddl/usr.sbin/plockstat/plockstat.1 new file mode 100644 index 000000000..ca97f39a6 --- /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 d6d29b3ea..1bf19c4f7 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 536227e29..aee1ac1f6 100644 --- a/lib/libproc/_libproc.h +++ b/lib/libproc/_libproc.h @@ -31,6 +31,7 @@ #include #include #include +#include #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 eccf37d84..d80e88c46 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 +#include +#include 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 000000000..c4264717f --- /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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include +#include +#include +#include +#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 1649b471b..b30a77b60 100644 --- a/lib/libproc/proc_create.c +++ b/lib/libproc/proc_create.c @@ -27,6 +27,7 @@ */ #include "_libproc.h" +#include #include #include #include @@ -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 000000000..3450e98ac --- /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 +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include +#include +#include +#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 000000000..2a9ed3996 --- /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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#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 c17c515b7..ffbc51f37 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 +#include + +#include +#include #include +#include +#include +#include +#include +#include +#include +#include + +#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 0e7020eff..089095e9e 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 -#include +#include #include #include +#include +#include +#include #include +#include +#include +#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 000000000..e4d33f82c --- /dev/null +++ b/lib/libproc/test/Makefile @@ -0,0 +1,5 @@ +# $FreeBSD$ + +SUBDIR= t1-bkpt t2-name2map t3-name2sym + +.include diff --git a/lib/libproc/test/t1-bkpt/Makefile b/lib/libproc/test/t1-bkpt/Makefile new file mode 100644 index 000000000..fd93fdd98 --- /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 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 000000000..6b4e2fa67 --- /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 +#include + +#include +#include +#include +#include + +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 000000000..3dca51c26 --- /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 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 000000000..825963d3f --- /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 +#include +#include +#include + +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 000000000..187f9c1c2 --- /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 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 000000000..6d90a48af --- /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 +#include +#include +#include +#include + +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 82b97a373..1e20f5665 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 *); -- 2.45.0