From 0889c9860f5d07fc87db6bfc287b9a3ddc764aa1 Mon Sep 17 00:00:00 2001 From: Patrik Nyblom Date: Thu, 8 Mar 2012 16:05:16 +0100 Subject: Move dtrace erlang code and NIF into runtime_tools Also make dyntrace NIF's load in on_load instead of init/0 --- lib/Makefile | 2 +- lib/dtrace/Makefile | 36 --- lib/dtrace/c_src/Makefile | 4 - lib/dtrace/c_src/Makefile.in | 151 ----------- lib/dtrace/c_src/dtrace.c | 168 ------------- lib/dtrace/c_src/dtrace_user.d | 53 ---- lib/dtrace/ebin/.placeholder | 0 lib/dtrace/examples/dist.d | 62 ----- lib/dtrace/examples/dist.systemtap | 76 ------ lib/dtrace/examples/driver1.d | 114 --------- lib/dtrace/examples/driver1.systemtap | 125 --------- lib/dtrace/examples/efile_drv.d | 104 -------- lib/dtrace/examples/efile_drv.systemtap | 112 --------- lib/dtrace/examples/function-calls.d | 51 ---- lib/dtrace/examples/function-calls.systemtap | 61 ----- lib/dtrace/examples/garbage-collection.d | 39 --- lib/dtrace/examples/garbage-collection.systemtap | 49 ---- lib/dtrace/examples/memory1.d | 41 --- lib/dtrace/examples/memory1.systemtap | 51 ---- lib/dtrace/examples/messages.d | 94 ------- lib/dtrace/examples/messages.systemtap | 87 ------- lib/dtrace/examples/port1.d | 142 ----------- lib/dtrace/examples/port1.systemtap | 152 ----------- lib/dtrace/examples/process-scheduling.d | 35 --- lib/dtrace/examples/process-scheduling.systemtap | 45 ---- lib/dtrace/examples/spawn-exit.d | 41 --- lib/dtrace/examples/spawn-exit.systemtap | 51 ---- lib/dtrace/examples/user-probe.d | 36 --- lib/dtrace/examples/user-probe.systemtap | 46 ---- lib/dtrace/src/Makefile | 102 -------- lib/dtrace/src/dtrace.app.src | 27 -- lib/dtrace/src/dtrace.appup.src | 19 -- lib/dtrace/src/dtrace.erl | 247 ------------------ lib/dtrace/vsn.mk | 1 - lib/runtime_tools/c_src/Makefile.in | 79 +++++- lib/runtime_tools/c_src/dtrace_user.d | 53 ++++ lib/runtime_tools/c_src/dyntrace.c | 172 +++++++++++++ lib/runtime_tools/examples/dist.d | 62 +++++ lib/runtime_tools/examples/dist.systemtap | 76 ++++++ lib/runtime_tools/examples/driver1.d | 114 +++++++++ lib/runtime_tools/examples/driver1.systemtap | 125 +++++++++ lib/runtime_tools/examples/efile_drv.d | 104 ++++++++ lib/runtime_tools/examples/efile_drv.systemtap | 112 +++++++++ lib/runtime_tools/examples/function-calls.d | 51 ++++ .../examples/function-calls.systemtap | 61 +++++ lib/runtime_tools/examples/garbage-collection.d | 39 +++ .../examples/garbage-collection.systemtap | 49 ++++ lib/runtime_tools/examples/memory1.d | 41 +++ lib/runtime_tools/examples/memory1.systemtap | 51 ++++ lib/runtime_tools/examples/messages.d | 94 +++++++ lib/runtime_tools/examples/messages.systemtap | 87 +++++++ lib/runtime_tools/examples/port1.d | 142 +++++++++++ lib/runtime_tools/examples/port1.systemtap | 152 +++++++++++ lib/runtime_tools/examples/process-scheduling.d | 35 +++ .../examples/process-scheduling.systemtap | 45 ++++ lib/runtime_tools/examples/spawn-exit.d | 41 +++ lib/runtime_tools/examples/spawn-exit.systemtap | 51 ++++ lib/runtime_tools/examples/user-probe.d | 36 +++ lib/runtime_tools/examples/user-probe.systemtap | 46 ++++ lib/runtime_tools/src/Makefile | 10 +- lib/runtime_tools/src/dyntrace.erl | 279 +++++++++++++++++++++ lib/runtime_tools/src/runtime_tools.app.src | 2 +- 62 files changed, 2202 insertions(+), 2431 deletions(-) delete mode 100644 lib/dtrace/Makefile delete mode 100644 lib/dtrace/c_src/Makefile delete mode 100644 lib/dtrace/c_src/Makefile.in delete mode 100644 lib/dtrace/c_src/dtrace.c delete mode 100644 lib/dtrace/c_src/dtrace_user.d delete mode 100644 lib/dtrace/ebin/.placeholder delete mode 100644 lib/dtrace/examples/dist.d delete mode 100644 lib/dtrace/examples/dist.systemtap delete mode 100644 lib/dtrace/examples/driver1.d delete mode 100644 lib/dtrace/examples/driver1.systemtap delete mode 100644 lib/dtrace/examples/efile_drv.d delete mode 100644 lib/dtrace/examples/efile_drv.systemtap delete mode 100644 lib/dtrace/examples/function-calls.d delete mode 100644 lib/dtrace/examples/function-calls.systemtap delete mode 100644 lib/dtrace/examples/garbage-collection.d delete mode 100644 lib/dtrace/examples/garbage-collection.systemtap delete mode 100644 lib/dtrace/examples/memory1.d delete mode 100644 lib/dtrace/examples/memory1.systemtap delete mode 100644 lib/dtrace/examples/messages.d delete mode 100644 lib/dtrace/examples/messages.systemtap delete mode 100644 lib/dtrace/examples/port1.d delete mode 100644 lib/dtrace/examples/port1.systemtap delete mode 100644 lib/dtrace/examples/process-scheduling.d delete mode 100644 lib/dtrace/examples/process-scheduling.systemtap delete mode 100644 lib/dtrace/examples/spawn-exit.d delete mode 100644 lib/dtrace/examples/spawn-exit.systemtap delete mode 100644 lib/dtrace/examples/user-probe.d delete mode 100644 lib/dtrace/examples/user-probe.systemtap delete mode 100644 lib/dtrace/src/Makefile delete mode 100644 lib/dtrace/src/dtrace.app.src delete mode 100644 lib/dtrace/src/dtrace.appup.src delete mode 100644 lib/dtrace/src/dtrace.erl delete mode 100644 lib/dtrace/vsn.mk create mode 100644 lib/runtime_tools/c_src/dtrace_user.d create mode 100644 lib/runtime_tools/c_src/dyntrace.c create mode 100644 lib/runtime_tools/examples/dist.d create mode 100644 lib/runtime_tools/examples/dist.systemtap create mode 100644 lib/runtime_tools/examples/driver1.d create mode 100644 lib/runtime_tools/examples/driver1.systemtap create mode 100644 lib/runtime_tools/examples/efile_drv.d create mode 100644 lib/runtime_tools/examples/efile_drv.systemtap create mode 100644 lib/runtime_tools/examples/function-calls.d create mode 100644 lib/runtime_tools/examples/function-calls.systemtap create mode 100644 lib/runtime_tools/examples/garbage-collection.d create mode 100644 lib/runtime_tools/examples/garbage-collection.systemtap create mode 100644 lib/runtime_tools/examples/memory1.d create mode 100644 lib/runtime_tools/examples/memory1.systemtap create mode 100644 lib/runtime_tools/examples/messages.d create mode 100644 lib/runtime_tools/examples/messages.systemtap create mode 100644 lib/runtime_tools/examples/port1.d create mode 100644 lib/runtime_tools/examples/port1.systemtap create mode 100644 lib/runtime_tools/examples/process-scheduling.d create mode 100644 lib/runtime_tools/examples/process-scheduling.systemtap create mode 100644 lib/runtime_tools/examples/spawn-exit.d create mode 100644 lib/runtime_tools/examples/spawn-exit.systemtap create mode 100644 lib/runtime_tools/examples/user-probe.d create mode 100644 lib/runtime_tools/examples/user-probe.systemtap create mode 100644 lib/runtime_tools/src/dyntrace.erl (limited to 'lib') diff --git a/lib/Makefile b/lib/Makefile index 96ce2d1315..aa4e074830 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -31,7 +31,7 @@ ifdef BUILD_ALL cosTransactions cosEvent cosTime cosNotification \ cosProperty cosFileTransfer cosEventDomain et megaco webtool \ xmerl edoc eunit ssh inviso typer erl_docgen \ - percept dialyzer dtrace hipe + percept dialyzer hipe EXTRA_FILE := $(wildcard EXTRA-APPLICATIONS) EXTRA_APPLICATIONS := $(if $(EXTRA_FILE),$(shell cat $(EXTRA_FILE))) endif diff --git a/lib/dtrace/Makefile b/lib/dtrace/Makefile deleted file mode 100644 index 29d463aab1..0000000000 --- a/lib/dtrace/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -# -# %CopyrightBegin% -# -# Copyright Ericsson AB 2002-2009. All Rights Reserved. -# -# The contents of this file are subject to the Erlang Public License, -# Version 1.1, (the "License"); you may not use this file except in -# compliance with the License. You should have received a copy of the -# Erlang Public License along with this software. If not, it can be -# retrieved online at http://www.erlang.org/. -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -# the License for the specific language governing rights and limitations -# under the License. -# -# %CopyrightEnd% -# -include $(ERL_TOP)/make/target.mk -include $(ERL_TOP)/make/$(TARGET)/otp.mk - -# -# Macros -# - -SUB_DIRECTORIES = src c_src - -include vsn.mk -VSN = $(DTRACE_VSN) - -SPECIAL_TARGETS = - -# -# Default Subdir Targets -# -include $(ERL_TOP)/make/otp_subdir.mk diff --git a/lib/dtrace/c_src/Makefile b/lib/dtrace/c_src/Makefile deleted file mode 100644 index a65491d45d..0000000000 --- a/lib/dtrace/c_src/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -# -# Invoke with GNU make -# -include $(ERL_TOP)/make/run_make.mk diff --git a/lib/dtrace/c_src/Makefile.in b/lib/dtrace/c_src/Makefile.in deleted file mode 100644 index 4d5f59a63d..0000000000 --- a/lib/dtrace/c_src/Makefile.in +++ /dev/null @@ -1,151 +0,0 @@ -# -# %CopyrightBegin% -# -# Copyright Scott Lystig Fritchie 2011. All Rights Reserved. -# -# The contents of this file are subject to the Erlang Public License, -# Version 1.1, (the "License"); you may not use this file except in -# compliance with the License. You should have received a copy of the -# Erlang Public License along with this software. If not, it can be -# retrieved online at http://www.erlang.org/. -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -# the License for the specific language governing rights and limitations -# under the License. -# -# %CopyrightEnd% -# -include $(ERL_TOP)/make/target.mk -include $(ERL_TOP)/make/$(TARGET)/otp.mk -include $(ERL_TOP)/make/$(TARGET)/otp_ded.mk - -# ---------------------------------------------------- -# Items from top-level configure -# ---------------------------------------------------- -DTRACE_ENABLED=@DTRACE_ENABLED@ -DTRACE_ENABLED_2STEP=@DTRACE_ENABLED_2STEP@ - -# ---------------------------------------------------- -# Application version -# ---------------------------------------------------- -include ../vsn.mk -VSN=$(DTRACE_VSN) - -# ---------------------------------------------------- -# The following variables differ between systems. -# Set by configure. -# ---------------------------------------------------- -CC = $(DED_CC) -LD = $(DED_LD) -SHELL = /bin/sh -LIBS = $(DED_LIBS) -LDFLAGS += $(DED_LDFLAGS) -CFLAGS = $(DED_CFLAGS) - -DTRACE_LIBNAME = dtrace - - -INCLUDES = $(DED_INCLUDES) - -ifeq ($(TYPE),debug) -TYPEMARKER = .debug -TYPE_FLAGS = $(subst -O3,,$(subst -O2,,$(CFLAGS))) -DDEBUG -else -ifeq ($(TYPE),valgrind) -TYPEMARKER = .valgrind -TYPE_FLAGS = $(subst -O3,,$(subst -O2,,$(CFLAGS))) -DVALGRIND -else -TYPEMARKER = -TYPE_FLAGS = $(CFLAGS) -endif -endif - -ALL_CFLAGS = $(TYPE_FLAGS) $(INCLUDES) -I$(OBJDIR) \ - -I$(ERL_TOP)/erts/emulator/$(TARGET) - -# ---------------------------------------------------- -# Release directory specification -# ---------------------------------------------------- -RELSYSDIR = $(RELEASE_PATH)/lib/dtrace-$(VSN) - -# ---------------------------------------------------- -# Misc Macros -# ---------------------------------------------------- -before_DTrace_OBJS = $(OBJDIR)/dtrace$(TYPEMARKER).o -## NIF_MAKEFILE = $(PRIVDIR)/Makefile - -# Higher-level makefiles says that we can only compile on UNIX flavors -NIF_LIB = $(LIBDIR)/dtrace$(TYPEMARKER).@DED_EXT@ - -ifeq ($(HOST_OS),) -HOST_OS := $(shell $(ERL_TOP)/erts/autoconf/config.guess) -endif - -# ---------------------------------------------------- -# Targets -# ---------------------------------------------------- - -debug opt valgrind: $(OBJDIR) $(LIBDIR) $(NIF_LIB) - -ifdef DTRACE_ENABLED -DTRACE_USER_HEADER=$(OBJDIR)/dtrace_user.h -$(OBJDIR)/dtrace_user.h: ./dtrace_user.d - dtrace -h -C $(INCLUDES) \ - -s ./dtrace_user.d \ - -o ./dtrace_user.tmp - sed -e '/^#define[ ]*ERLANG_[A-Z0-9_]*(.*)/y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/' ./dtrace_user.tmp > $@ - rm ./dtrace_user.tmp -else -DTRACE_USER_HEADER= -endif - -DTRACE_OBJS = -ifdef DTRACE_ENABLED_2STEP -DTRACE_OBJS += $(OBJDIR)/dtrace_user.o -$(OBJDIR)/dtrace_user.o: $(before_DTrace_OBJS) $(OBJDIR)/dtrace_user.h - dtrace -G -C \ - -s ./dtrace_user.d \ - -o $@ $(before_DTrace_OBJS) -endif - -OBJS = $(before_DTrace_OBJS) $(DTRACE_OBJS) - -$(OBJDIR): - -@mkdir -p $(OBJDIR) - -$(LIBDIR): - -@mkdir -p $(LIBDIR) - -$(OBJDIR)/%$(TYPEMARKER).o: %.c $(DTRACE_USER_HEADER) - $(INSTALL_DIR) $(OBJDIR) - $(CC) -c -o $@ $(ALL_CFLAGS) $< - -$(NIF_LIB): $(OBJS) - $(INSTALL_DIR) $(LIBDIR) - $(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS) - -clean: - rm -f $(LIBDIR)/dtrace.@DED_EXT@ - rm -f $(LIBDIR)/dtrace.debug.@DED_EXT@ - rm -f $(LIBDIR)/dtrace.valgrind.@DED_EXT@ - rm -f $(OBJDIR)/dtrace.o - rm -f $(OBJDIR)/dtrace.debug.o - rm -f $(OBJDIR)/dtrace.valgrind.o - rm -f core *~ - -docs: - -# ---------------------------------------------------- -# Release Target -# ---------------------------------------------------- -include $(ERL_TOP)/make/otp_release_targets.mk - -release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/priv/obj - $(INSTALL_DIR) $(RELSYSDIR)/priv/lib - # $(INSTALL_DATA) $(NIF_MAKEFILE) $(RELSYSDIR)/priv/obj - $(INSTALL_PROGRAM) $(OBJS) $(RELSYSDIR)/priv/obj - $(INSTALL_PROGRAM) $(NIF_LIB) $(RELSYSDIR)/priv/lib - -release_docs_spec: diff --git a/lib/dtrace/c_src/dtrace.c b/lib/dtrace/c_src/dtrace.c deleted file mode 100644 index 90bb39a4b8..0000000000 --- a/lib/dtrace/c_src/dtrace.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Scott Lystig Fritchie 2011. All Rights Reserved. - * - * The contents of this file are subject to the Erlang Public License, - * Version 1.1, (the "License"); you may not use this file except in - * compliance with the License. You should have received a copy of the - * Erlang Public License along with this software. If not, it can be - * retrieved online at http://www.erlang.org/. - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * %CopyrightEnd% - */ - -/* - * Purpose: Dynamically loadable NIF library for DTrace - */ - - -#include "erl_nif.h" -#include "config.h" -#include "sys.h" -#include "dtrace-wrapper.h" -#ifdef HAVE_DTRACE -#include "dtrace_user.h" -#endif - -void dtrace_nifenv_str(ErlNifEnv *env, char *process_buf); -void get_string_maybe(ErlNifEnv *env, const ERL_NIF_TERM term, char **ptr, char *buf, int bufsiz); - -#ifdef VALGRIND - # include -#endif - -#ifdef __GNUC__ - # define INLINE __inline__ -#else - # define INLINE -#endif - -#define MESSAGE_BUFSIZ 1024 - -/* NIF interface declarations */ -static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info); - -/* The NIFs: */ -static ERL_NIF_TERM available(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); -static ERL_NIF_TERM user_trace_s1(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); -static ERL_NIF_TERM user_trace_i4s4(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); - -static ErlNifFunc nif_funcs[] = { - {"available", 0, available}, - {"user_trace_s1", 1, user_trace_s1}, - {"user_trace_i4s4", 9, user_trace_i4s4} -}; - -ERL_NIF_INIT(dtrace, nif_funcs, load, NULL, NULL, NULL) - -static ERL_NIF_TERM atom_true; -static ERL_NIF_TERM atom_false; -static ERL_NIF_TERM atom_error; -static ERL_NIF_TERM atom_not_available; -static ERL_NIF_TERM atom_badarg; -static ERL_NIF_TERM atom_ok; - -static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) -{ - atom_true = enif_make_atom(env,"true"); - atom_false = enif_make_atom(env,"false"); - atom_error = enif_make_atom(env,"error"); - atom_not_available = enif_make_atom(env,"not_available"); - atom_badarg = enif_make_atom(env,"badarg"); - atom_ok = enif_make_atom(env,"ok"); - - return 0; -} - -static ERL_NIF_TERM available(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{ -#ifdef HAVE_DTRACE - return atom_true; -#else - return atom_false; -#endif -} - -static ERL_NIF_TERM user_trace_s1(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{ -#ifdef HAVE_DTRACE - ErlNifBinary message_bin; - DTRACE_CHARBUF(messagebuf, MESSAGE_BUFSIZ + 1); - - if (DTRACE_ENABLED(user_trace_s1)) { - if (!enif_inspect_iolist_as_binary(env, argv[0], &message_bin) || - message_bin.size > MESSAGE_BUFSIZ) { - return atom_badarg; - } - memcpy(messagebuf, (char *) message_bin.data, message_bin.size); - messagebuf[message_bin.size] = '\0'; - DTRACE1(user_trace_s1, messagebuf); - return atom_true; - } else { - return atom_false; - } -#else - return atom_error; -#endif -} - -void -get_string_maybe(ErlNifEnv *env, - const ERL_NIF_TERM term, char **ptr, char *buf, int bufsiz) -{ - ErlNifBinary str_bin; - - if (!enif_inspect_iolist_as_binary(env, term, &str_bin) || - str_bin.size > bufsiz) { - *ptr = NULL; - } else { - memcpy(buf, (char *) str_bin.data, str_bin.size); - buf[str_bin.size] = '\0'; - *ptr = buf; - } -} - -static ERL_NIF_TERM user_trace_i4s4(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{ -#ifdef HAVE_DTRACE - DTRACE_CHARBUF(procbuf, 32 + 1); - DTRACE_CHARBUF(user_tagbuf, MESSAGE_BUFSIZ + 1); - char *utbuf = NULL; - ErlNifSInt64 i1, i2, i3, i4; - DTRACE_CHARBUF(messagebuf1, MESSAGE_BUFSIZ + 1); - DTRACE_CHARBUF(messagebuf2, MESSAGE_BUFSIZ + 1); - DTRACE_CHARBUF(messagebuf3, MESSAGE_BUFSIZ + 1); - DTRACE_CHARBUF(messagebuf4, MESSAGE_BUFSIZ + 1); - char *mbuf1 = NULL, *mbuf2 = NULL, *mbuf3 = NULL, *mbuf4 = NULL; - - if (DTRACE_ENABLED(user_trace_i4s4)) { - dtrace_nifenv_str(env, procbuf); - get_string_maybe(env, argv[0], &utbuf, user_tagbuf, MESSAGE_BUFSIZ); - if (! enif_get_int64(env, argv[1], &i1)) - i1 = 0; - if (! enif_get_int64(env, argv[2], &i2)) - i2 = 0; - if (! enif_get_int64(env, argv[3], &i3)) - i3 = 0; - if (! enif_get_int64(env, argv[4], &i4)) - i4 = 0; - get_string_maybe(env, argv[5], &mbuf1, messagebuf1, MESSAGE_BUFSIZ); - get_string_maybe(env, argv[6], &mbuf2, messagebuf2, MESSAGE_BUFSIZ); - get_string_maybe(env, argv[7], &mbuf3, messagebuf3, MESSAGE_BUFSIZ); - get_string_maybe(env, argv[8], &mbuf4, messagebuf4, MESSAGE_BUFSIZ); - DTRACE10(user_trace_i4s4, procbuf, utbuf, - i1, i2, i3, i4, mbuf1, mbuf2, mbuf3, mbuf4); - return atom_true; - } else { - return atom_false; - } -#else - return atom_error; -#endif -} diff --git a/lib/dtrace/c_src/dtrace_user.d b/lib/dtrace/c_src/dtrace_user.d deleted file mode 100644 index 45d3ef3b66..0000000000 --- a/lib/dtrace/c_src/dtrace_user.d +++ /dev/null @@ -1,53 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Scott Lystig Fritchie 2011. - * All Rights Reserved. - * - * The contents of this file are subject to the Erlang Public License, - * Version 1.1, (the "License"); you may not use this file except in - * compliance with the License. You should have received a copy of the - * Erlang Public License along with this software. If not, it can be - * retrieved online at http://www.erlang.org/. - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * %CopyrightEnd% - */ - -provider erlang { - /** - * Send a single string to a probe. - * - * @param NUL-terminated string - */ - probe user_trace__s1(char* message); - - /** - * Multi-purpose probe: up to 4 NUL-terminated strings and 4 - * 64-bit integer arguments. - * - * @param proc, the PID (string form) of the sending process - * @param user_tag, the user tag of the sender - * @param i1, integer - * @param i2, integer - * @param i3, integer - * @param i4, integer - * @param s1, string/iolist. D's arg6 is NULL if not given by Erlang - * @param s2, string/iolist. D's arg7 is NULL if not given by Erlang - * @param s3, string/iolist. D's arg8 is NULL if not given by Erlang - * @param s4, string/iolist. D's arg9 is NULL if not given by Erlang - */ - probe user_trace__i4s4(char *proc, char *user_tag, - int i1, int i2, int i3, int i4, - char *s1, char *s2, char *s3, char *s4); -}; - -#pragma D attributes Evolving/Evolving/Common provider erlang provider -#pragma D attributes Private/Private/Common provider erlang module -#pragma D attributes Private/Private/Common provider erlang function -#pragma D attributes Evolving/Evolving/Common provider erlang name -#pragma D attributes Evolving/Evolving/Common provider erlang args diff --git a/lib/dtrace/ebin/.placeholder b/lib/dtrace/ebin/.placeholder deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/lib/dtrace/examples/dist.d b/lib/dtrace/examples/dist.d deleted file mode 100644 index 550e10d363..0000000000 --- a/lib/dtrace/examples/dist.d +++ /dev/null @@ -1,62 +0,0 @@ -/* example usage: dtrace -q -s /path/to/dist.d */ -/* - * %CopyrightBegin% - * - * Copyright Scott Lystig Fritchie 2011. All Rights Reserved. - * - * The contents of this file are subject to the Erlang Public License, - * Version 1.1, (the "License"); you may not use this file except in - * compliance with the License. You should have received a copy of the - * Erlang Public License along with this software. If not, it can be - * retrieved online at http://www.erlang.org/. - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * %CopyrightEnd% - */ - -erlang*:::dist-monitor -{ - printf("monitor: pid %d, who %s, what %s, node %s, type %s, reason %s\n", - pid, - copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), copyinstr(arg3), - copyinstr(arg4)); -} - -erlang*:::dist-port_busy -{ - printf("dist port_busy: node %s, port %s, remote_node %s, blocked pid %s\n", - copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), copyinstr(arg3)); - /* - * For variable use advice, see: - * http://dtrace.org/blogs/brendan/2011/11/25/dtrace-variable-types/ - * - * Howevever, it's quite possible for the blocked events to span - * threads, so we'll use globals. - */ - blocked_procs[copyinstr(arg3)] = timestamp; -} - -erlang*:::dist-output -{ - printf("dist output: node %s, port %s, remote_node %s bytes %d\n", - copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), arg3); -} - -erlang*:::dist-outputv -{ - printf("port outputv: node %s, port %s, remote_node %s bytes %d\n", - copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), arg3); -} - -erlang*:::process-scheduled -/blocked_procs[copyinstr(arg0)]/ -{ - pidstr = copyinstr(arg0); - printf("blocked pid %s scheduled now, waited %d microseconds\n", - pidstr, (timestamp - blocked_procs[pidstr]) / 1000); - blocked_procs[pidstr] = 0; -} diff --git a/lib/dtrace/examples/dist.systemtap b/lib/dtrace/examples/dist.systemtap deleted file mode 100644 index af27b2cab6..0000000000 --- a/lib/dtrace/examples/dist.systemtap +++ /dev/null @@ -1,76 +0,0 @@ -/* example usage: stap /path/to/dist.systemtap -x */ -/* - * %CopyrightBegin% - * - * Copyright Scott Lystig Fritchie and Andreas Schultz, 2011. All Rights Reserved. - * - * The contents of this file are subject to the Erlang Public License, - * Version 1.1, (the "License"); you may not use this file except in - * compliance with the License. You should have received a copy of the - * Erlang Public License along with this software. If not, it can be - * retrieved online at http://www.erlang.org/. - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * %CopyrightEnd% - */ -/* - * Note: This file assumes that you're using the non-SMP-enabled Erlang - * virtual machine, "beam". The SMP-enabled VM is called "beam.smp". - * Note that other variations of the virtual machine also have - * different names, e.g. the debug build of the SMP-enabled VM - * is "beam.debug.smp". - * - * To use a different virtual machine, replace each instance of - * "beam" with "beam.smp" or the VM name appropriate to your - * environment. - */ - -probe process("beam").mark("dist-monitor") -{ - printf("monitor: pid %d, who %s, what %s, node %s, type %s, reason %s\n", - pid(), - user_string($arg1), user_string($arg2), user_string($arg3), user_string($arg4), - user_string($arg5)); -} - -probe process("beam").mark("dist-port_busy") -{ - printf("dist port_busy: node %s, port %s, remote_node %s, blocked pid %s\n", - user_string($arg1), user_string($arg2), user_string($arg3), user_string($arg4)); - blocked_procs[user_string($arg4)] = timestamp; -} - -probe process("beam").mark("dist-port_busy") -{ - printf("dist port_busy: node %s, port %s, remote_node %s, blocked pid %s\n", - user_string($arg1), user_string($arg2), user_string($arg3), user_string($arg4)); - blocked_procs[user_string($arg4)] = timestamp; -} - -probe process("beam").mark("dist-output") -{ - printf("dist output: node %s, port %s, remote_node %s bytes %d\n", - user_string($arg1), user_string($arg2), user_string($arg3), $arg4); -} - -probe process("beam").mark("dist-outputv") -{ - printf("port outputv: node %s, port %s, remote_node %s bytes %d\n", - user_string($arg1), user_string($arg2), user_string($arg3), $arg4); -} - -probe process("beam").mark("process-scheduled") -{ - pidstr = user_string($arg1); - if (pidstr in blocked_procs) { - printf("blocked pid %s scheduled now, waited %d microseconds\n", - pidstr, (timestamp - blocked_procs[pidstr]) / 1000); - delete blocked_procs[pidstr]; - } -} - -global blocked_procs; diff --git a/lib/dtrace/examples/driver1.d b/lib/dtrace/examples/driver1.d deleted file mode 100644 index 9f53ffeb2a..0000000000 --- a/lib/dtrace/examples/driver1.d +++ /dev/null @@ -1,114 +0,0 @@ -/* example usage: dtrace -q -s /path/to/driver1.d */ -/* - * %CopyrightBegin% - * - * Copyright Scott Lystig Fritchie 2011. All Rights Reserved. - * - * The contents of this file are subject to the Erlang Public License, - * Version 1.1, (the "License"); you may not use this file except in - * compliance with the License. You should have received a copy of the - * Erlang Public License along with this software. If not, it can be - * retrieved online at http://www.erlang.org/. - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * %CopyrightEnd% - */ - -erlang*:::driver-init -{ - printf("driver init name %s major %d minor %d flags %d\n", - copyinstr(arg0), arg1, arg2, arg3); -} - -erlang*:::driver-start -{ - printf("driver start pid %s driver name %s port %s\n", - copyinstr(arg0), copyinstr(arg1), copyinstr(arg2)); -} - -erlang*:::driver-stop -{ - printf("driver stop pid %s driver name %s port %s\n", - copyinstr(arg0), copyinstr(arg1), copyinstr(arg2)); -} - -erlang*:::driver-finish -{ - printf("driver finish driver name %s port %s\n", - copyinstr(arg0), copyinstr(arg1)); -} - -erlang*:::driver-flush -{ - printf("driver flush pid %s port %s port name %s\n", - copyinstr(arg0), copyinstr(arg1), copyinstr(arg2)); -} - -erlang*:::driver-output -{ - printf("driver output pid %s port %s port name %s bytes %d\n", - copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), arg3); -} - -erlang*:::driver-outputv -{ - printf("driver outputv pid %s port %s port name %s bytes %d\n", - copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), arg3); -} - -erlang*:::driver-control -{ - printf("driver control pid %s port %s port name %s command %d bytes %d\n", - copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), arg3, arg4); -} - -erlang*:::driver-call -{ - printf("driver call pid %s port %s port name %s command %d bytes %d\n", - copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), arg3, arg4); -} - -erlang*:::driver-event -{ - printf("driver event pid %s port %s port name %s\n", - copyinstr(arg0), copyinstr(arg1), copyinstr(arg2)); -} - -erlang*:::driver-ready_input -{ - printf("driver ready_input pid %s port %s port name %s\n", - copyinstr(arg0), copyinstr(arg1), copyinstr(arg2)); -} - -erlang*:::driver-ready_output -{ - printf("driver ready_output pid %s port %s port name %s\n", - copyinstr(arg0), copyinstr(arg1), copyinstr(arg2)); -} - -erlang*:::driver-timeout -{ - printf("driver timeout pid %s port %s port name %s\n", - copyinstr(arg0), copyinstr(arg1), copyinstr(arg2)); -} - -erlang*:::driver-ready_async -{ - printf("driver ready_async pid %s port %s port name %s\n", - copyinstr(arg0), copyinstr(arg1), copyinstr(arg2)); -} - -erlang*:::driver-process_exit -{ - printf("driver process_exit pid %s port %s port name %s\n", - copyinstr(arg0), copyinstr(arg1), copyinstr(arg2)); -} - -erlang*:::driver-stop_select -{ - printf("driver stop_select driver name %s\n", copyinstr(arg0)); -} diff --git a/lib/dtrace/examples/driver1.systemtap b/lib/dtrace/examples/driver1.systemtap deleted file mode 100644 index 8b99e465b7..0000000000 --- a/lib/dtrace/examples/driver1.systemtap +++ /dev/null @@ -1,125 +0,0 @@ -/* example usage: stap /path/to/driver1.systemtap -x */ -/* - * %CopyrightBegin% - * - * Copyright Scott Lystig Fritchie and Andreas Schultz, 2011. All Rights Reserved. - * - * The contents of this file are subject to the Erlang Public License, - * Version 1.1, (the "License"); you may not use this file except in - * compliance with the License. You should have received a copy of the - * Erlang Public License along with this software. If not, it can be - * retrieved online at http://www.erlang.org/. - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * %CopyrightEnd% - */ -/* - * Note: This file assumes that you're using the non-SMP-enabled Erlang - * virtual machine, "beam". The SMP-enabled VM is called "beam.smp". - * Note that other variations of the virtual machine also have - * different names, e.g. the debug build of the SMP-enabled VM - * is "beam.debug.smp". - * - * To use a different virtual machine, replace each instance of - * "beam" with "beam.smp" or the VM name appropriate to your - * environment. - */ - -probe process("beam").mark("driver-init") -{ - printf("driver init name %s major %d minor %d flags %d\n", - user_string($arg1), $arg2, $arg3, $arg4); -} - -probe process("beam").mark("driver-start") -{ - printf("driver start pid %s driver name %s port %s\n", - user_string($arg1), user_string($arg2), user_string($arg3)); -} - -probe process("beam").mark("driver-stop") -{ - printf("driver stop pid %s driver name %s port %s\n", - user_string($arg1), user_string($arg2), user_string($arg3)); -} - -probe process("beam").mark("driver-finish") -{ - printf("driver finish driver name %s\n", - user_string($arg1)); -} - -probe process("beam").mark("driver-flush") -{ - printf("driver flush pid %s port %s port name %s\n", - user_string($arg1), user_string($arg2), user_string($arg3)); -} - -probe process("beam").mark("driver-output") -{ - printf("driver output pid %s port %s port name %s bytes %d\n", - user_string($arg1), user_string($arg2), user_string($arg3), $arg4); -} - -probe process("beam").mark("driver-outputv") -{ - printf("driver outputv pid %s port %s port name %s bytes %d\n", - user_string($arg1), user_string($arg2), user_string($arg3), $arg4); -} - -probe process("beam").mark("driver-control") -{ - printf("driver control pid %s port %s port name %s command %d bytes %d\n", - user_string($arg1), user_string($arg2), user_string($arg3), $arg4, $arg5); -} - -probe process("beam").mark("driver-call") -{ - printf("driver call pid %s port %s port name %s command %d bytes %d\n", - user_string($arg1), user_string($arg2), user_string($arg3), $arg4, $arg5); -} - -probe process("beam").mark("driver-event") -{ - printf("driver event pid %s port %s port name %s\n", - user_string($arg1), user_string($arg2), user_string($arg3)); -} - -probe process("beam").mark("driver-ready_input") -{ - printf("driver ready_input pid %s port %s port name %s\n", - user_string($arg1), user_string($arg2), user_string($arg3)); -} - -probe process("beam").mark("driver-ready_output") -{ - printf("driver ready_output pid %s port %s port name %s\n", - user_string($arg1), user_string($arg2), user_string($arg3)); -} - -probe process("beam").mark("driver-timeout") -{ - printf("driver timeout pid %s port %s port name %s\n", - user_string($arg1), user_string($arg2), user_string($arg3)); -} - -probe process("beam").mark("driver-ready_async") -{ - printf("driver ready_async pid %s port %s port name %s\n", - user_string($arg1), user_string($arg2), user_string($arg3)); -} - -probe process("beam").mark("driver-process_exit") -{ - printf("driver process_exit pid %s port %s port name %s\n", - user_string($arg1), user_string($arg2), user_string($arg3)); -} - -probe process("beam").mark("driver-stop_select") -{ - printf("driver stop_select driver name %s\n", user_string($arg1)); -} diff --git a/lib/dtrace/examples/efile_drv.d b/lib/dtrace/examples/efile_drv.d deleted file mode 100644 index 085995ce58..0000000000 --- a/lib/dtrace/examples/efile_drv.d +++ /dev/null @@ -1,104 +0,0 @@ -/* example usage: dtrace -q -s /path/to/efile_drv.d */ -/* - * %CopyrightBegin% - * - * Copyright Scott Lystig Fritchie 2011. All Rights Reserved. - * - * The contents of this file are subject to the Erlang Public License, - * Version 1.1, (the "License"); you may not use this file except in - * compliance with the License. You should have received a copy of the - * Erlang Public License along with this software. If not, it can be - * retrieved online at http://www.erlang.org/. - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * %CopyrightEnd% - */ - -BEGIN -{ - op_map[1] = "OPEN"; - op_map[2] = "READ"; - op_map[3] = "LSEEK"; - op_map[4] = "WRITE"; - op_map[5] = "FSTAT"; - op_map[6] = "PWD"; - op_map[7] = "READDIR"; - op_map[8] = "CHDIR"; - op_map[9] = "FSYNC"; - op_map[10] = "MKDIR"; - op_map[11] = "DELETE"; - op_map[12] = "RENAME"; - op_map[13] = "RMDIR"; - op_map[14] = "TRUNCATE"; - op_map[15] = "READ_FILE"; - op_map[16] = "WRITE_INFO"; - op_map[19] = "LSTAT"; - op_map[20] = "READLINK"; - op_map[21] = "LINK"; - op_map[22] = "SYMLINK"; - op_map[23] = "CLOSE"; - op_map[24] = "PWRITEV"; - op_map[25] = "PREADV"; - op_map[26] = "SETOPT"; - op_map[27] = "IPREAD"; - op_map[28] = "ALTNAME"; - op_map[29] = "READ_LINE"; - op_map[30] = "FDATASYNC"; - op_map[31] = "FADVISE"; -} - -erlang*:::aio_pool-add -{ - printf("async I/O pool port %s queue len %d\n", copyinstr(arg0), arg1); -} - -erlang*:::aio_pool-get -{ - printf("async I/O pool port %s queue len %d\n", copyinstr(arg0), arg1); -} - -erlang*:::efile_drv-entry -{ - printf("efile_drv enter tag={%d,%d} %s%s | %s (%d) | args: %s %s , %d %d (port %s)\n", - arg0, arg1, - arg2 == NULL ? "" : "user tag ", - arg2 == NULL ? "" : copyinstr(arg2), - op_map[arg3], arg3, - arg4 == NULL ? "" : copyinstr(arg4), - arg5 == NULL ? "" : copyinstr(arg5), arg6, arg7, - /* NOTE: port name in args[10] is experimental */ - (args[10] == NULL) ? - "?" : copyinstr((user_addr_t) args[10])); -} - -erlang*:::efile_drv-int* -{ - printf("async I/O worker tag={%d,%d} | %s (%d) | %s\n", - arg0, arg1, op_map[arg2], arg2, probename); -} - -/* efile_drv-return error case */ -erlang*:::efile_drv-return -/arg4 == 0/ -{ - printf("efile_drv return tag={%d,%d} %s%s | %s (%d) | errno %d\n", - arg0, arg1, - arg2 == NULL ? "" : "user tag ", - arg2 == NULL ? "" : copyinstr(arg2), - op_map[arg3], arg3, - arg5); -} - -/* efile_drv-return success case */ -erlang*:::efile_drv-return -/arg4 != 0/ -{ - printf("efile_drv return tag={%d,%d} %s | %s (%d) ok\n", - arg0, arg1, - arg2 == NULL ? "" : copyinstr(arg2), - op_map[arg3], arg3); -} diff --git a/lib/dtrace/examples/efile_drv.systemtap b/lib/dtrace/examples/efile_drv.systemtap deleted file mode 100644 index 5a47b3e22b..0000000000 --- a/lib/dtrace/examples/efile_drv.systemtap +++ /dev/null @@ -1,112 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Scott Lystig Fritchie and Andreas Schultz, 2011. All Rights Reserved. - * - * The contents of this file are subject to the Erlang Public License, - * Version 1.1, (the "License"); you may not use this file except in - * compliance with the License. You should have received a copy of the - * Erlang Public License along with this software. If not, it can be - * retrieved online at http://www.erlang.org/. - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * %CopyrightEnd% - */ -/* - * Note: This file assumes that you're using the non-SMP-enabled Erlang - * virtual machine, "beam". The SMP-enabled VM is called "beam.smp". - * Note that other variations of the virtual machine also have - * different names, e.g. the debug build of the SMP-enabled VM - * is "beam.debug.smp". - * - * To use a different virtual machine, replace each instance of - * "beam" with "beam.smp" or the VM name appropriate to your - * environment. - */ - -probe begin -{ - op_map[1] = "OPEN"; - op_map[2] = "READ"; - op_map[3] = "LSEEK"; - op_map[4] = "WRITE"; - op_map[5] = "FSTAT"; - op_map[6] = "PWD"; - op_map[7] = "READDIR"; - op_map[8] = "CHDIR"; - op_map[9] = "FSYNC"; - op_map[10] = "MKDIR"; - op_map[11] = "DELETE"; - op_map[12] = "RENAME"; - op_map[13] = "RMDIR"; - op_map[14] = "TRUNCATE"; - op_map[15] = "READ_FILE"; - op_map[16] = "WRITE_INFO"; - op_map[19] = "LSTAT"; - op_map[20] = "READLINK"; - op_map[21] = "LINK"; - op_map[22] = "SYMLINK"; - op_map[23] = "CLOSE"; - op_map[24] = "PWRITEV"; - op_map[25] = "PREADV"; - op_map[26] = "SETOPT"; - op_map[27] = "IPREAD"; - op_map[28] = "ALTNAME"; - op_map[29] = "READ_LINE"; - op_map[30] = "FDATASYNC"; - op_map[31] = "FADVISE"; -} - -probe process("beam").mark("aio_pool-add") -{ - printf("async I/O pool port %s queue len %d\n", user_string($arg1), $arg2); -} - -probe process("beam").mark("aio_pool-get") -{ - printf("async I/O pool port %s queue len %d\n", user_string($arg1), $arg2); -} - -probe process("beam").mark("efile_drv-entry") -{ - printf("efile_drv enter tag={%d,%d} %s%s | %s (%d) | args: %s %s , %d %d (port %s)\n", - $arg1, $arg2, - $arg3 == NULL ? "" : "user tag ", - $arg3 == NULL ? "" : user_string($arg3), - op_map[$arg4], $arg4, - $arg5 == NULL ? "" : user_string($arg5), - $arg6 == NULL ? "" : user_string($arg6), $arg7, $arg8, - /* NOTE: port name in $arg[11] is experimental */ - user_string($arg11)) -} - -probe process("beam").mark("efile_drv-int*") -{ - printf("async I/O worker tag={%d,%d} | %s (%d) | %s\n", - $arg1, $arg2, op_map[$arg3], $arg3, probefunc()); -} - -probe process("beam").mark("efile_drv-return") -{ - if ($arg5 == 0) { - /* efile_drv-return error case */ - printf("efile_drv return tag={%d,%d} %s%s | %s (%d) | errno %d\n", - $arg1, $arg2, - $arg3 == NULL ? "" : "user tag ", - $arg3 == NULL ? "" : user_string($arg3), - op_map[$arg4], $arg4, - $arg6); - } else { - /* efile_drv-return success case */ - printf("efile_drv return tag={%d,%d} %s | %s (%d) ok\n", - $arg1, $arg2, - $arg3 == NULL ? "" : user_string($arg3), - op_map[$arg4], $arg4); - } -} - -global op_map; diff --git a/lib/dtrace/examples/function-calls.d b/lib/dtrace/examples/function-calls.d deleted file mode 100644 index 238c5211ac..0000000000 --- a/lib/dtrace/examples/function-calls.d +++ /dev/null @@ -1,51 +0,0 @@ -/* example usage: dtrace -q -s /path/to/function-calls.d */ -/* - * %CopyrightBegin% - * - * Copyright Scott Lystig Fritchie 2011. All Rights Reserved. - * - * The contents of this file are subject to the Erlang Public License, - * Version 1.1, (the "License"); you may not use this file except in - * compliance with the License. You should have received a copy of the - * Erlang Public License along with this software. If not, it can be - * retrieved online at http://www.erlang.org/. - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * %CopyrightEnd% - */ - -erlang*:::function-entry -{ - printf("pid %s enter %s depth %d\n", - copyinstr(arg0), copyinstr(arg1), arg2); -} - -erlang*:::function-return -{ - printf("pid %s return %s depth %d\n", - copyinstr(arg0), copyinstr(arg1), arg2); -} - -erlang*:::bif-entry -{ - printf("pid %s BIF entry mfa %s\n", copyinstr(arg0), copyinstr(arg1)); -} - -erlang*:::bif-return -{ - printf("pid %s BIF return mfa %s\n", copyinstr(arg0), copyinstr(arg1)); -} - -erlang*:::nif-entry -{ - printf("pid %s NIF entry mfa %s\n", copyinstr(arg0), copyinstr(arg1)); -} - -erlang*:::nif-return -{ - printf("pid %s NIF return mfa %s\n", copyinstr(arg0), copyinstr(arg1)); -} diff --git a/lib/dtrace/examples/function-calls.systemtap b/lib/dtrace/examples/function-calls.systemtap deleted file mode 100644 index 8fc4375135..0000000000 --- a/lib/dtrace/examples/function-calls.systemtap +++ /dev/null @@ -1,61 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Scott Lystig Fritchie and Andreas Schultz, 2011. All Rights Reserved. - * - * The contents of this file are subject to the Erlang Public License, - * Version 1.1, (the "License"); you may not use this file except in - * compliance with the License. You should have received a copy of the - * Erlang Public License along with this software. If not, it can be - * retrieved online at http://www.erlang.org/. - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * %CopyrightEnd% - */ -/* - * Note: This file assumes that you're using the non-SMP-enabled Erlang - * virtual machine, "beam". The SMP-enabled VM is called "beam.smp". - * Note that other variations of the virtual machine also have - * different names, e.g. the debug build of the SMP-enabled VM - * is "beam.debug.smp". - * - * To use a different virtual machine, replace each instance of - * "beam" with "beam.smp" or the VM name appropriate to your - * environment. - */ - -probe process("beam").mark("function-entry") -{ - printf("pid %s enter %s depth %d\n", - user_string($arg1), user_string($arg2), $arg3); -} - -probe process("beam").mark("function-return") -{ - printf("pid %s return %s depth %d\n", - user_string($arg1), user_string($arg2), $arg3); -} - -probe process("beam").mark("bif-entry") -{ - printf("pid %s BIF entry mfa %s\n", user_string($arg1), user_string($arg2)); -} - -probe process("beam").mark("bif-return") -{ - printf("pid %s BIF return mfa %s\n", user_string($arg1), user_string($arg2)); -} - -probe process("beam").mark("nif-entry") -{ - printf("pid %s NIF entry mfa %s\n", user_string($arg1), user_string($arg2)); -} - -probe process("beam").mark("nif-return") -{ - printf("pid %s NIF return mfa %s\n", user_string($arg1), user_string($arg2)); -} diff --git a/lib/dtrace/examples/garbage-collection.d b/lib/dtrace/examples/garbage-collection.d deleted file mode 100644 index f234e7d4db..0000000000 --- a/lib/dtrace/examples/garbage-collection.d +++ /dev/null @@ -1,39 +0,0 @@ -/* example usage: dtrace -q -s /path/to/garbage-collection.d */ -/* - * %CopyrightBegin% - * - * Copyright Scott Lystig Fritchie 2011. All Rights Reserved. - * - * The contents of this file are subject to the Erlang Public License, - * Version 1.1, (the "License"); you may not use this file except in - * compliance with the License. You should have received a copy of the - * Erlang Public License along with this software. If not, it can be - * retrieved online at http://www.erlang.org/. - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * %CopyrightEnd% - */ - -erlang*:::gc_major-start -{ - printf("GC major start pid %s need %d words\n", copyinstr(arg0), arg1); -} - -erlang*:::gc_minor-start -{ - printf("GC minor start pid %s need %d words\n", copyinstr(arg0), arg1); -} - -erlang*:::gc_major-end -{ - printf("GC major end pid %s reclaimed %d words\n", copyinstr(arg0), arg1); -} - -erlang*:::gc_minor-start -{ - printf("GC minor end pid %s reclaimed %d words\n", copyinstr(arg0), arg1); -} diff --git a/lib/dtrace/examples/garbage-collection.systemtap b/lib/dtrace/examples/garbage-collection.systemtap deleted file mode 100644 index 64d69c6fbd..0000000000 --- a/lib/dtrace/examples/garbage-collection.systemtap +++ /dev/null @@ -1,49 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Scott Lystig Fritchie and Andreas Schultz, 2011. All Rights Reserved. - * - * The contents of this file are subject to the Erlang Public License, - * Version 1.1, (the "License"); you may not use this file except in - * compliance with the License. You should have received a copy of the - * Erlang Public License along with this software. If not, it can be - * retrieved online at http://www.erlang.org/. - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * %CopyrightEnd% - */ -/* - * Note: This file assumes that you're using the non-SMP-enabled Erlang - * virtual machine, "beam". The SMP-enabled VM is called "beam.smp". - * Note that other variations of the virtual machine also have - * different names, e.g. the debug build of the SMP-enabled VM - * is "beam.debug.smp". - * - * To use a different virtual machine, replace each instance of - * "beam" with "beam.smp" or the VM name appropriate to your - * environment. - */ - -probe process("beam").mark("gc_major-start") -{ - printf("GC major start pid %s need %d words\n", user_string($arg1), $arg2); -} - -probe process("beam").mark("gc_minor-start") -{ - printf("GC minor start pid %s need %d words\n", user_string($arg1), $arg2); -} - -probe process("beam").mark("gc_major-end") -{ - printf("GC major end pid %s reclaimed %d words\n", user_string($arg1), $arg2); -} - -probe process("beam").mark("gc_minor-start") -{ - printf("GC minor end pid %s reclaimed %d words\n", user_string($arg1), $arg2); -} diff --git a/lib/dtrace/examples/memory1.d b/lib/dtrace/examples/memory1.d deleted file mode 100644 index c2e16e0779..0000000000 --- a/lib/dtrace/examples/memory1.d +++ /dev/null @@ -1,41 +0,0 @@ -/* example usage: dtrace -q -s /path/to/memory1.d */ -/* - * %CopyrightBegin% - * - * Copyright Scott Lystig Fritchie 2011. All Rights Reserved. - * - * The contents of this file are subject to the Erlang Public License, - * Version 1.1, (the "License"); you may not use this file except in - * compliance with the License. You should have received a copy of the - * Erlang Public License along with this software. If not, it can be - * retrieved online at http://www.erlang.org/. - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * %CopyrightEnd% - */ - -erlang*:::copy-struct -{ - printf("copy_struct %d bytes\n", arg0); -} - -erlang*:::copy-object -{ - printf("copy_object pid %s %d bytes\n", copyinstr(arg0), arg1); -} - -erlang*:::process-heap_grow -{ - printf("proc heap grow pid %s %d -> %d bytes\n", copyinstr(arg0), - arg1, arg2); -} - -erlang*:::process-heap_shrink -{ - printf("proc heap shrink pid %s %d -> %d bytes\n", copyinstr(arg0), - arg1, arg2); -} diff --git a/lib/dtrace/examples/memory1.systemtap b/lib/dtrace/examples/memory1.systemtap deleted file mode 100644 index 9723f2d02d..0000000000 --- a/lib/dtrace/examples/memory1.systemtap +++ /dev/null @@ -1,51 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Scott Lystig Fritchie and Andreas Schultz, 2011. All Rights Reserved. - * - * The contents of this file are subject to the Erlang Public License, - * Version 1.1, (the "License"); you may not use this file except in - * compliance with the License. You should have received a copy of the - * Erlang Public License along with this software. If not, it can be - * retrieved online at http://www.erlang.org/. - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * %CopyrightEnd% - */ -/* - * Note: This file assumes that you're using the non-SMP-enabled Erlang - * virtual machine, "beam". The SMP-enabled VM is called "beam.smp". - * Note that other variations of the virtual machine also have - * different names, e.g. the debug build of the SMP-enabled VM - * is "beam.debug.smp". - * - * To use a different virtual machine, replace each instance of - * "beam" with "beam.smp" or the VM name appropriate to your - * environment. - */ - -probe process("beam").mark("copy-struct") -{ - printf("copy_struct %d bytes\n", $arg1); -} - -probe process("beam").mark("copy-object") -{ - printf("copy_object pid %s %d bytes\n", user_string($arg1), $arg2); -} - -probe process("beam").mark("process-heap_grow") -{ - printf("proc heap grow pid %s %d -> %d bytes\n", user_string($arg1), - $arg2, $arg3); -} - -probe process("beam").mark("process-heap_shrink") -{ - printf("proc heap shrink pid %s %d -> %d bytes\n", user_string($arg1), - $arg2, $arg3); -} diff --git a/lib/dtrace/examples/messages.d b/lib/dtrace/examples/messages.d deleted file mode 100644 index 6361f3a220..0000000000 --- a/lib/dtrace/examples/messages.d +++ /dev/null @@ -1,94 +0,0 @@ -/* example usage: dtrace -q -s /path/to/messages.d */ -/* - * %CopyrightBegin% - * - * Copyright Scott Lystig Fritchie 2011. All Rights Reserved. - * - * The contents of this file are subject to the Erlang Public License, - * Version 1.1, (the "License"); you may not use this file except in - * compliance with the License. You should have received a copy of the - * Erlang Public License along with this software. If not, it can be - * retrieved online at http://www.erlang.org/. - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * %CopyrightEnd% - */ - -BEGIN -{ - printf("\n"); - printf("NOTE: message-queue message size 4294967295 means an external\n"); - printf(" message that the code isn't smart enough to determine\n"); - printf(" the actual size.\n"); - printf("\n"); -} - -erlang*:::message-send -/arg3 == 0 && arg4 == 0 && arg5 == 0/ -{ - printf("send: %s -> %s: %d words\n", - copyinstr(arg0), copyinstr(arg1), arg2); -} - -erlang*:::message-send -/arg3 != 0 || arg4 != 0 || arg5 != 0/ -{ - printf("send: %s label %d token {%d,%d} -> %s: %d words\n", - copyinstr(arg0), - arg3, arg4, arg5, - copyinstr(arg1), arg2); -} - -/* - * TODO: - * Weird, on my OS X box, beam says arg6 = 0 but this script says 4294967296. - */ - -erlang*:::message-send-remote -/arg4 == 0 && arg5 == 0 && (arg6 == 0 || arg6 >= 4294967296)/ -{ - printf("send : %s -> %s %s: %d words\n", - copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), arg3); -} - -erlang*:::message-send-remote -/arg4 != 0 || arg5 != 0 || arg6 < 4294967296/ -{ - printf("send : %s label %d token {%d,%d} -> %s %s: %d words\n", - copyinstr(arg0), - arg4, arg5, arg6, - copyinstr(arg1), copyinstr(arg2), arg3); -} - -erlang*:::message-queued -/arg3 == 0 && arg4 == 0 && arg5 == 0/ -{ - printf("queued: %s: %d words, queue len %d\n", copyinstr(arg0), arg1, arg2); -} - -erlang*:::message-queued -/arg3 != 0 || arg4 != 0 || arg5 != 0/ -{ - printf("queued: %s label %d token {%d,%d}: %d words, queue len %d\n", - copyinstr(arg0), arg3, arg4, arg5, - arg1, arg2); -} - -erlang*:::message-receive -/arg3 == 0 && arg4 == 0 && arg5 == 0/ -{ - printf("receive: %s: %d words, queue len %d\n", - copyinstr(arg0), arg1, arg2); -} - -erlang*:::message-receive -/arg3 != 0 || arg4 != 0 || arg5 != 0/ -{ - printf("receive: %s label %d token {%d,%d}: %d words, queue len %d\n", - copyinstr(arg0), arg3, arg4, arg5, - arg1, arg2); -} diff --git a/lib/dtrace/examples/messages.systemtap b/lib/dtrace/examples/messages.systemtap deleted file mode 100644 index ff8f4076b1..0000000000 --- a/lib/dtrace/examples/messages.systemtap +++ /dev/null @@ -1,87 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Scott Lystig Fritchie and Andreas Schultz, 2011. All Rights Reserved. - * - * The contents of this file are subject to the Erlang Public License, - * Version 1.1, (the "License"); you may not use this file except in - * compliance with the License. You should have received a copy of the - * Erlang Public License along with this software. If not, it can be - * retrieved online at http://www.erlang.org/. - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * %CopyrightEnd% - */ -/* - * Note: This file assumes that you're using the non-SMP-enabled Erlang - * virtual machine, "beam". The SMP-enabled VM is called "beam.smp". - * Note that other variations of the virtual machine also have - * different names, e.g. the debug build of the SMP-enabled VM - * is "beam.debug.smp". - * - * To use a different virtual machine, replace each instance of - * "beam" with "beam.smp" or the VM name appropriate to your - * environment. - */ - -probe begin -{ - printf("\n"); - printf("NOTE: message-queue message size 4294967295 means an external\n"); - printf(" message that the code isn't smart enough to determine\n"); - printf(" the actual size.\n"); - printf("\n"); -} - -probe process("beam").mark("message-send") -{ - if ($arg4 == 0 && $arg5 == 0 && $arg6 == 0) { - printf("send: %s -> %s: %d words\n", - user_string($arg1), user_string($arg2), $arg3); - } else { - printf("send: %s label %d token {%d,%d} -> %s: %d words\n", - user_string($arg1), - $arg4, $arg5, $arg6, - user_string($arg2), $arg3); - } -} - -probe process("beam").mark("message-send-remote") -{ - if ($arg5 == 0 && $arg6 == 0 && $arg7 == 0) { - printf("send : %s -> %s %s: %d words\n", - user_string($arg1), user_string($arg2), user_string($arg3), $arg4); - } else { - printf("send : %s label %d token {%d,%d} -> %s %s: %d words\n", - user_string($arg1), - $arg5, $arg6, $arg7, - user_string($arg2), user_string($arg3), $arg4); - } -} - -probe process("beam").mark("message-queued") -{ - if ($arg4 == 0 && $arg5 == 0 && $arg6 == 0) { - printf("queued: %s: %d words, queue len %d\n", user_string($arg1), $arg2, $arg3); - } else { - printf("queued: %s label %d token {%d,%d}: %d words, queue len %d\n", - user_string($arg1), $arg4, $arg5, $arg6, - $arg2, $arg3); - } -} - -probe process("beam").mark("message-receive") -{ - if ($arg4 == 0 && $arg5 == 0 && $arg6 == 0) { - printf("receive: %s: %d words, queue len %d\n", - user_string($arg1), $arg2, $arg3); - } else { - printf("receive: %s label %d token {%d,%d}: %d words, queue len %d\n", - user_string($arg1), $arg4, $arg5, $arg6, - $arg2, $arg3); - } -} diff --git a/lib/dtrace/examples/port1.d b/lib/dtrace/examples/port1.d deleted file mode 100644 index 204abbd3b8..0000000000 --- a/lib/dtrace/examples/port1.d +++ /dev/null @@ -1,142 +0,0 @@ -/* example usage: dtrace -q -s /path/to/port1.d */ -/* - * %CopyrightBegin% - * - * Copyright Scott Lystig Fritchie 2011. All Rights Reserved. - * - * The contents of this file are subject to the Erlang Public License, - * Version 1.1, (the "License"); you may not use this file except in - * compliance with the License. You should have received a copy of the - * Erlang Public License along with this software. If not, it can be - * retrieved online at http://www.erlang.org/. - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * %CopyrightEnd% - */ - -BEGIN -{ - driver_map["tcp_inet", 1] = "OPEN"; - driver_map["tcp_inet", 2] = "CLOSE"; - driver_map["tcp_inet", 3] = "CONNECT"; - driver_map["tcp_inet", 4] = "PEER"; - driver_map["tcp_inet", 5] = "NAME"; - driver_map["tcp_inet", 6] = "BIND"; - driver_map["tcp_inet", 7] = "SETOPTS"; - driver_map["tcp_inet", 8] = "GETOPTS"; - driver_map["tcp_inet", 11] = "GETSTAT"; - driver_map["tcp_inet", 12] = "GETHOSTNAME"; - driver_map["tcp_inet", 13] = "FDOPEN"; - driver_map["tcp_inet", 14] = "GETFD"; - driver_map["tcp_inet", 15] = "GETTYPE"; - driver_map["tcp_inet", 16] = "GETSTATUS"; - driver_map["tcp_inet", 17] = "GETSERVBYNAME"; - driver_map["tcp_inet", 18] = "GETSERVBYPORT"; - driver_map["tcp_inet", 19] = "SETNAME"; - driver_map["tcp_inet", 20] = "SETPEER"; - driver_map["tcp_inet", 21] = "GETIFLIST"; - driver_map["tcp_inet", 22] = "IFGET"; - driver_map["tcp_inet", 23] = "IFSET"; - driver_map["tcp_inet", 24] = "SUBSCRIBE"; - driver_map["tcp_inet", 25] = "GETIFADDRS"; - driver_map["tcp_inet", 40] = "ACCEPT"; - driver_map["tcp_inet", 41] = "LISTEN"; - driver_map["tcp_inet", 42] = "RECV"; - driver_map["tcp_inet", 43] = "UNRECV"; - driver_map["tcp_inet", 44] = "SHUTDOWN"; - driver_map["tcp_inet", 60] = "RECV"; - driver_map["tcp_inet", 61] = "LISTEN"; - driver_map["tcp_inet", 62] = "BINDX"; - /* No looping constructs, so repeat for udp_inet */ - driver_map["udp_inet", 1] = "OPEN"; - driver_map["udp_inet", 2] = "CLOSE"; - driver_map["udp_inet", 3] = "CONNECT"; - driver_map["udp_inet", 4] = "PEER"; - driver_map["udp_inet", 5] = "NAME"; - driver_map["udp_inet", 6] = "BIND"; - driver_map["udp_inet", 7] = "SETOPTS"; - driver_map["udp_inet", 8] = "GETOPTS"; - driver_map["udp_inet", 11] = "GETSTAT"; - driver_map["udp_inet", 12] = "GETHOSTNAME"; - driver_map["udp_inet", 13] = "FDOPEN"; - driver_map["udp_inet", 14] = "GETFD"; - driver_map["udp_inet", 15] = "GETTYPE"; - driver_map["udp_inet", 16] = "GETSTATUS"; - driver_map["udp_inet", 17] = "GETSERVBYNAME"; - driver_map["udp_inet", 18] = "GETSERVBYPORT"; - driver_map["udp_inet", 19] = "SETNAME"; - driver_map["udp_inet", 20] = "SETPEER"; - driver_map["udp_inet", 21] = "GETIFLIST"; - driver_map["udp_inet", 22] = "IFGET"; - driver_map["udp_inet", 23] = "IFSET"; - driver_map["udp_inet", 24] = "SUBSCRIBE"; - driver_map["udp_inet", 25] = "GETIFADDRS"; - driver_map["udp_inet", 40] = "ACCEPT"; - driver_map["udp_inet", 41] = "LISTEN"; - driver_map["udp_inet", 42] = "RECV"; - driver_map["udp_inet", 43] = "UNRECV"; - driver_map["udp_inet", 44] = "SHUTDOWN"; - driver_map["udp_inet", 60] = "RECV"; - driver_map["udp_inet", 61] = "LISTEN"; - driver_map["udp_inet", 62] = "BINDX"; -} - -erlang*:::port-open -{ - printf("port open pid %s port name %s port %s\n", - copyinstr(arg0), copyinstr(arg1), copyinstr(arg2)); -} - -erlang*:::port-command -{ - printf("port command pid %s port %s port name %s command type %s\n", - copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), copyinstr(arg3)); -} - -erlang*:::port-control -{ - /* http://dtrace.org/blogs/brendan/2011/11/25/dtrace-variable-types/ */ - this->cmd = driver_map[copyinstr(arg2), arg3]; - this->cmd_str = (this->cmd == 0) ? "unknown" : this->cmd; - printf("port control pid %s port %s port name %s command %d %s\n", - copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), arg3, - this->cmd_str); -} - -/* port-exit is fired as a result of port_close() or exit signal */ - -erlang*:::port-exit -{ - printf("port exit pid %s port %s port name %s reason %s\n", - copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), copyinstr(arg3)); -} - -erlang*:::port-connect -{ - printf("port connect pid %s port %s port name %s new pid %s\n", - copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), copyinstr(arg3)); -} - -erlang*:::port-busy -{ - printf("port busy %s\n", copyinstr(arg0)); -} - -erlang*:::port-not_busy -{ - printf("port not busy %s\n", copyinstr(arg0)); -} - -erlang*:::aio_pool-add -{ - printf("async I/O pool add thread %d queue len %d\n", arg0, arg1); -} - -erlang*:::aio_pool-get -{ - printf("async I/O pool get thread %d queue len %d\n", arg0, arg1); -} diff --git a/lib/dtrace/examples/port1.systemtap b/lib/dtrace/examples/port1.systemtap deleted file mode 100644 index a63d9b670c..0000000000 --- a/lib/dtrace/examples/port1.systemtap +++ /dev/null @@ -1,152 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Scott Lystig Fritchie and Andreas Schultz, 2011. All Rights Reserved. - * - * The contents of this file are subject to the Erlang Public License, - * Version 1.1, (the "License"); you may not use this file except in - * compliance with the License. You should have received a copy of the - * Erlang Public License along with this software. If not, it can be - * retrieved online at http://www.erlang.org/. - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * %CopyrightEnd% - */ -/* - * Note: This file assumes that you're using the non-SMP-enabled Erlang - * virtual machine, "beam". The SMP-enabled VM is called "beam.smp". - * Note that other variations of the virtual machine also have - * different names, e.g. the debug build of the SMP-enabled VM - * is "beam.debug.smp". - * - * To use a different virtual machine, replace each instance of - * "beam" with "beam.smp" or the VM name appropriate to your - * environment. - */ - -probe begin -{ - driver_map["tcp_inet", 1] = "OPEN"; - driver_map["tcp_inet", 2] = "CLOSE"; - driver_map["tcp_inet", 3] = "CONNECT"; - driver_map["tcp_inet", 4] = "PEER"; - driver_map["tcp_inet", 5] = "NAME"; - driver_map["tcp_inet", 6] = "BIND"; - driver_map["tcp_inet", 7] = "SETOPTS"; - driver_map["tcp_inet", 8] = "GETOPTS"; - driver_map["tcp_inet", 11] = "GETSTAT"; - driver_map["tcp_inet", 12] = "GETHOSTNAME"; - driver_map["tcp_inet", 13] = "FDOPEN"; - driver_map["tcp_inet", 14] = "GETFD"; - driver_map["tcp_inet", 15] = "GETTYPE"; - driver_map["tcp_inet", 16] = "GETSTATUS"; - driver_map["tcp_inet", 17] = "GETSERVBYNAME"; - driver_map["tcp_inet", 18] = "GETSERVBYPORT"; - driver_map["tcp_inet", 19] = "SETNAME"; - driver_map["tcp_inet", 20] = "SETPEER"; - driver_map["tcp_inet", 21] = "GETIFLIST"; - driver_map["tcp_inet", 22] = "IFGET"; - driver_map["tcp_inet", 23] = "IFSET"; - driver_map["tcp_inet", 24] = "SUBSCRIBE"; - driver_map["tcp_inet", 25] = "GETIFADDRS"; - driver_map["tcp_inet", 40] = "ACCEPT"; - driver_map["tcp_inet", 41] = "LISTEN"; - driver_map["tcp_inet", 42] = "RECV"; - driver_map["tcp_inet", 43] = "UNRECV"; - driver_map["tcp_inet", 44] = "SHUTDOWN"; - driver_map["tcp_inet", 60] = "RECV"; - driver_map["tcp_inet", 61] = "LISTEN"; - driver_map["tcp_inet", 62] = "BINDX"; - /* No looping constructs, so repeat for udp_inet */ - driver_map["udp_inet", 1] = "OPEN"; - driver_map["udp_inet", 2] = "CLOSE"; - driver_map["udp_inet", 3] = "CONNECT"; - driver_map["udp_inet", 4] = "PEER"; - driver_map["udp_inet", 5] = "NAME"; - driver_map["udp_inet", 6] = "BIND"; - driver_map["udp_inet", 7] = "SETOPTS"; - driver_map["udp_inet", 8] = "GETOPTS"; - driver_map["udp_inet", 11] = "GETSTAT"; - driver_map["udp_inet", 12] = "GETHOSTNAME"; - driver_map["udp_inet", 13] = "FDOPEN"; - driver_map["udp_inet", 14] = "GETFD"; - driver_map["udp_inet", 15] = "GETTYPE"; - driver_map["udp_inet", 16] = "GETSTATUS"; - driver_map["udp_inet", 17] = "GETSERVBYNAME"; - driver_map["udp_inet", 18] = "GETSERVBYPORT"; - driver_map["udp_inet", 19] = "SETNAME"; - driver_map["udp_inet", 20] = "SETPEER"; - driver_map["udp_inet", 21] = "GETIFLIST"; - driver_map["udp_inet", 22] = "IFGET"; - driver_map["udp_inet", 23] = "IFSET"; - driver_map["udp_inet", 24] = "SUBSCRIBE"; - driver_map["udp_inet", 25] = "GETIFADDRS"; - driver_map["udp_inet", 40] = "ACCEPT"; - driver_map["udp_inet", 41] = "LISTEN"; - driver_map["udp_inet", 42] = "RECV"; - driver_map["udp_inet", 43] = "UNRECV"; - driver_map["udp_inet", 44] = "SHUTDOWN"; - driver_map["udp_inet", 60] = "RECV"; - driver_map["udp_inet", 61] = "LISTEN"; - driver_map["udp_inet", 62] = "BINDX"; -} - -probe process("beam").mark("port-open") -{ - printf("port open pid %s port name %s port %s\n", - user_string($arg1), user_string($arg2), user_string($arg3)); -} - -probe process("beam").mark("port-command") -{ - printf("port command pid %s port %s port name %s command type %s\n", - user_string($arg1), user_string($arg2), user_string($arg3), user_string($arg4)); -} - -probe process("beam").mark("port-control") -{ - cmd = driver_map[user_string($arg3), $arg4]; - cmd_str = (cmd == "") ? "unknown" : cmd; - printf("port control pid %s port %s port name %s command %d %s\n", - user_string($arg1), user_string($arg2), user_string($arg3), $arg4, cmd_str); -} - -/* port-exit is fired as a result of port_close() or exit signal */ - -probe process("beam").mark("port-exit") -{ - printf("port exit pid %s port %s port name %s reason %s\n", - user_string($arg1), user_string($arg2), user_string($arg3), user_string($arg4)); -} - -probe process("beam").mark("port-connect") -{ - printf("port connect pid %s port %s port name %s new pid %s\n", - user_string($arg1), user_string($arg2), user_string($arg3), user_string($arg4)); -} - -probe process("beam").mark("port-busy") -{ - printf("port busy %s\n", user_string($arg1)); -} - -probe process("beam").mark("port-not_busy") -{ - printf("port not busy %s\n", user_string($arg1)); -} - -probe process("beam").mark("aio_pool-add") -{ - printf("async I/O pool add thread %d queue len %d\n", $arg1, $arg2); -} - -probe process("beam").mark("aio_pool-get") -{ - printf("async I/O pool get thread %d queue len %d\n", $arg1, $arg2); -} - -global driver_map; \ No newline at end of file diff --git a/lib/dtrace/examples/process-scheduling.d b/lib/dtrace/examples/process-scheduling.d deleted file mode 100644 index 79e9cc598c..0000000000 --- a/lib/dtrace/examples/process-scheduling.d +++ /dev/null @@ -1,35 +0,0 @@ -/* example usage: dtrace -q -s /path/to/process-scheduling.d */ -/* - * %CopyrightBegin% - * - * Copyright Scott Lystig Fritchie 2011. All Rights Reserved. - * - * The contents of this file are subject to the Erlang Public License, - * Version 1.1, (the "License"); you may not use this file except in - * compliance with the License. You should have received a copy of the - * Erlang Public License along with this software. If not, it can be - * retrieved online at http://www.erlang.org/. - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * %CopyrightEnd% - */ - -erlang*:::process-scheduled -{ - printf(" Schedule pid %s mfa %s\n", copyinstr(arg0), copyinstr(arg1)); -} - -erlang*:::process-unscheduled -{ - printf("Unschedule pid %s\n", copyinstr(arg0)); -} - -erlang*:::process-hibernate -{ - printf(" Hibernate pid %s resume mfa %s\n", - copyinstr(arg0), copyinstr(arg1)); -} diff --git a/lib/dtrace/examples/process-scheduling.systemtap b/lib/dtrace/examples/process-scheduling.systemtap deleted file mode 100644 index c8cee60a07..0000000000 --- a/lib/dtrace/examples/process-scheduling.systemtap +++ /dev/null @@ -1,45 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Scott Lystig Fritchie and Andreas Schultz, 2011. All Rights Reserved. - * - * The contents of this file are subject to the Erlang Public License, - * Version 1.1, (the "License"); you may not use this file except in - * compliance with the License. You should have received a copy of the - * Erlang Public License along with this software. If not, it can be - * retrieved online at http://www.erlang.org/. - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * %CopyrightEnd% - */ -/* - * Note: This file assumes that you're using the non-SMP-enabled Erlang - * virtual machine, "beam". The SMP-enabled VM is called "beam.smp". - * Note that other variations of the virtual machine also have - * different names, e.g. the debug build of the SMP-enabled VM - * is "beam.debug.smp". - * - * To use a different virtual machine, replace each instance of - * "beam" with "beam.smp" or the VM name appropriate to your - * environment. - */ - -probe process("beam").mark("process-scheduled") -{ - printf(" Schedule pid %s mfa %s\n", user_string($arg1), user_string($arg2)); -} - -probe process("beam").mark("process-unscheduled") -{ - printf("Unschedule pid %s\n", user_string($arg1)); -} - -probe process("beam").mark("process-hibernate") -{ - printf(" Hibernate pid %s resume mfa %s\n", - user_string($arg1), user_string($arg2)); -} diff --git a/lib/dtrace/examples/spawn-exit.d b/lib/dtrace/examples/spawn-exit.d deleted file mode 100644 index 7310f3343d..0000000000 --- a/lib/dtrace/examples/spawn-exit.d +++ /dev/null @@ -1,41 +0,0 @@ -/* example usage: dtrace -q -s /path/to/spawn-exit.d */ -/* - * %CopyrightBegin% - * - * Copyright Scott Lystig Fritchie 2011. All Rights Reserved. - * - * The contents of this file are subject to the Erlang Public License, - * Version 1.1, (the "License"); you may not use this file except in - * compliance with the License. You should have received a copy of the - * Erlang Public License along with this software. If not, it can be - * retrieved online at http://www.erlang.org/. - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * %CopyrightEnd% - */ - -erlang*:::process-spawn -{ - printf("pid %s mfa %s\n", copyinstr(arg0), copyinstr(arg1)); -} - -erlang*:::process-exit -{ - printf("pid %s reason %s\n", copyinstr(arg0), copyinstr(arg1)); -} - -erlang*:::process-exit_signal -{ - printf("sender %s -> pid %s reason %s\n", - copyinstr(arg0), copyinstr(arg1), copyinstr(arg2)); -} - -erlang*:::process-exit_signal-remote -{ - printf("sender %s -> node %s pid %s reason %s\n", - copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), copyinstr(arg3)); -} diff --git a/lib/dtrace/examples/spawn-exit.systemtap b/lib/dtrace/examples/spawn-exit.systemtap deleted file mode 100644 index 5e3be9fc1b..0000000000 --- a/lib/dtrace/examples/spawn-exit.systemtap +++ /dev/null @@ -1,51 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Scott Lystig Fritchie and Andreas Schultz, 2011. All Rights Reserved. - * - * The contents of this file are subject to the Erlang Public License, - * Version 1.1, (the "License"); you may not use this file except in - * compliance with the License. You should have received a copy of the - * Erlang Public License along with this software. If not, it can be - * retrieved online at http://www.erlang.org/. - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * %CopyrightEnd% - */ -/* - * Note: This file assumes that you're using the non-SMP-enabled Erlang - * virtual machine, "beam". The SMP-enabled VM is called "beam.smp". - * Note that other variations of the virtual machine also have - * different names, e.g. the debug build of the SMP-enabled VM - * is "beam.debug.smp". - * - * To use a different virtual machine, replace each instance of - * "beam" with "beam.smp" or the VM name appropriate to your - * environment. - */ - -probe process("beam").mark("process-spawn") -{ - printf("pid %s mfa %s\n", user_string($arg1), user_string($arg2)); -} - -probe process("beam").mark("process-exit") -{ - printf("pid %s reason %s\n", user_string($arg1), user_string($arg2)); -} - -probe process("beam").mark("process-exit_signal") -{ - printf("sender %s -> pid %s reason %s\n", - user_string($arg1), user_string($arg2), user_string($arg3)); -} - -probe process("beam").mark("process-exit_signal-remote") -{ - printf("sender %s -> node %s pid %s reason %s\n", - user_string($arg1), user_string($arg2), user_string($arg3), user_string($arg4)); -} diff --git a/lib/dtrace/examples/user-probe.d b/lib/dtrace/examples/user-probe.d deleted file mode 100644 index 13baff6a32..0000000000 --- a/lib/dtrace/examples/user-probe.d +++ /dev/null @@ -1,36 +0,0 @@ -/* example usage: dtrace -q -s /path/to/user-probe.d */ -/* - * %CopyrightBegin% - * - * Copyright Scott Lystig Fritchie 2011. All Rights Reserved. - * - * The contents of this file are subject to the Erlang Public License, - * Version 1.1, (the "License"); you may not use this file except in - * compliance with the License. You should have received a copy of the - * Erlang Public License along with this software. If not, it can be - * retrieved online at http://www.erlang.org/. - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * %CopyrightEnd% - */ - -erlang*:::user_trace-s1 -{ - printf("%s\n", copyinstr(arg0)); -} - -erlang*:::user_trace-i4s4 -{ - printf("%s %s %d %d %d %d '%s' '%s' '%s' '%s'\n", - copyinstr(arg0), - arg1 == NULL ? "" : copyinstr(arg1), - arg2, arg3, arg4, arg5, - arg6 == NULL ? "" : copyinstr(arg6), - arg7 == NULL ? "" : copyinstr(arg7), - arg8 == NULL ? "" : copyinstr(arg8), - arg9 == NULL ? "" : copyinstr(arg9)); -} diff --git a/lib/dtrace/examples/user-probe.systemtap b/lib/dtrace/examples/user-probe.systemtap deleted file mode 100644 index 84a45709e8..0000000000 --- a/lib/dtrace/examples/user-probe.systemtap +++ /dev/null @@ -1,46 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Scott Lystig Fritchie and Andreas Schultz, 2011. All Rights Reserved. - * - * The contents of this file are subject to the Erlang Public License, - * Version 1.1, (the "License"); you may not use this file except in - * compliance with the License. You should have received a copy of the - * Erlang Public License along with this software. If not, it can be - * retrieved online at http://www.erlang.org/. - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See - * the License for the specific language governing rights and limitations - * under the License. - * - * %CopyrightEnd% - */ -/* - * Note: This file assumes that you're using the non-SMP-enabled Erlang - * virtual machine, "beam". The SMP-enabled VM is called "beam.smp". - * Note that other variations of the virtual machine also have - * different names, e.g. the debug build of the SMP-enabled VM - * is "beam.debug.smp". - * - * To use a different virtual machine, replace each instance of - * "beam" with "beam.smp" or the VM name appropriate to your - * environment. - */ - -probe process("dyntrace.so").mark("user_trace-s1") -{ - printf("%s\n", user_string($arg1)); -} - -probe process("dyntrace.so").mark("user_trace-i4s4") -{ - printf("%s %s %d %d %d %d '%s' '%s' '%s' '%s'\n", - user_string($arg1), - $arg2 == NULL ? "" : user_string($arg2), - $arg3, $arg4, $arg5, $arg6, - $arg7 == NULL ? "" : user_string($arg7), - $arg8 == NULL ? "" : user_string($arg8), - $arg9 == NULL ? "" : user_string($arg9), - $arg9 == NULL ? "" : user_string($arg9)); -} diff --git a/lib/dtrace/src/Makefile b/lib/dtrace/src/Makefile deleted file mode 100644 index d613402a63..0000000000 --- a/lib/dtrace/src/Makefile +++ /dev/null @@ -1,102 +0,0 @@ -# -# %CopyrightBegin% -# -# Copyright Ericsson AB 2002-2011. All Rights Reserved. -# -# The contents of this file are subject to the Erlang Public License, -# Version 1.1, (the "License"); you may not use this file except in -# compliance with the License. You should have received a copy of the -# Erlang Public License along with this software. If not, it can be -# retrieved online at http://www.erlang.org/. -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -# the License for the specific language governing rights and limitations -# under the License. -# -# %CopyrightEnd% -# -include $(ERL_TOP)/make/target.mk -include $(ERL_TOP)/make/$(TARGET)/otp.mk - -# ---------------------------------------------------- -# Application version -# ---------------------------------------------------- -include ../vsn.mk -VSN=$(DTRACE_VSN) - -# ---------------------------------------------------- -# Release directory specification -# ---------------------------------------------------- -RELSYSDIR = $(RELEASE_PATH)/lib/dtrace-$(VSN) - -# ---------------------------------------------------- -# Common Macros -# ---------------------------------------------------- - -MODULES= \ - dtrace - -HRL_FILES= \ - -INTERNAL_HRL_FILES= \ - -ERL_FILES= $(MODULES:%=%.erl) -EXAMPLE_FILES= \ - ../examples/* - -TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR)) $(APP_TARGET) $(APPUP_TARGET) - -EXECUTABLES= \ - -APP_FILE= dtrace.app - -APP_SRC= $(APP_FILE).src -APP_TARGET= $(EBIN)/$(APP_FILE) - -APPUP_FILE= dtrace.appup - -APPUP_SRC= $(APPUP_FILE).src -APPUP_TARGET= $(EBIN)/$(APPUP_FILE) - -# ---------------------------------------------------- -# FLAGS -# ---------------------------------------------------- -ERL_COMPILE_FLAGS += \ - -I../include \ - -I ../../et/include \ - -I ../../../libraries/et/include - -# ---------------------------------------------------- -# Targets -# ---------------------------------------------------- - -debug opt: $(TARGET_FILES) - -clean: - rm -f $(TARGET_FILES) - rm -f errs core *~ - -$(APP_TARGET): $(APP_SRC) ../vsn.mk - sed -e 's;%VSN%;$(VSN);' $< > $@ - -$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk - sed -e 's;%VSN%;$(VSN);' $< > $@ - -docs: - -# ---------------------------------------------------- -# Release Target -# ---------------------------------------------------- -include $(ERL_TOP)/make/otp_release_targets.mk - -release_spec: opt - $(INSTALL_DIR) $(RELSYSDIR)/src - $(INSTALL_DATA) $(ERL_FILES) $(RELSYSDIR)/src - # $(INSTALL_DATA) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src - $(INSTALL_DIR) $(RELSYSDIR)/examples - $(INSTALL_DATA) $(EXAMPLE_FILES) $(RELSYSDIR)/examples - $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin - -release_docs_spec: diff --git a/lib/dtrace/src/dtrace.app.src b/lib/dtrace/src/dtrace.app.src deleted file mode 100644 index 764e863559..0000000000 --- a/lib/dtrace/src/dtrace.app.src +++ /dev/null @@ -1,27 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2002-2009. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -{application, dtrace, - [{description, "DTRACE version 1"}, - {vsn, "%VSN%"}, - {modules, [ - dtrace - ]}, - {registered, []}, - {applications, [kernel, stdlib]}, - {env, []}]}. diff --git a/lib/dtrace/src/dtrace.appup.src b/lib/dtrace/src/dtrace.appup.src deleted file mode 100644 index f730a2f8df..0000000000 --- a/lib/dtrace/src/dtrace.appup.src +++ /dev/null @@ -1,19 +0,0 @@ -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2002-2009. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -{"%VSN%",[],[]}. diff --git a/lib/dtrace/src/dtrace.erl b/lib/dtrace/src/dtrace.erl deleted file mode 100644 index 71a1a3480e..0000000000 --- a/lib/dtrace/src/dtrace.erl +++ /dev/null @@ -1,247 +0,0 @@ --module(dtrace). - -%%% @doc The DTrace interface module -%%% -%%% This DTrace interface module, with the corresponding NIFs, should -%%% work on any operating system platform where user-space DTrace -%%% probes are supported. -%%% -%%% Use the `dtrace:init()' function to load the NIF shared library and -%%% to initialize library's private state. -%%% -%%% It is recommended that you use the `dtrace:p()' function to add -%%% DTrace probes to your Erlang code. This function can accept up to -%%% four integer arguments and four string arguments; the integer -%%% argument(s) must come before any string argument. For example: -%%% ``` -%%% 1> dtrace:put_tag("GGOOOAAALL!!!!!"). -%%% true -%%% 2> dtrace:init(). -%%% ok -%%% -%%% % % % Enable the DTrace probe using the 'dtrace' command. -%%% -%%% 3> dtrace:p(7, 8, 9, "one", "four"). -%%% true -%%% ''' -%%% -%%% Output from the example D script `user-probe.d' looks like: -%%% ``` -%%% <0.34.0> GGOOOAAALL!!!!! 7 8 9 0 'one' 'four' '' '' -%%% ''' -%%% -%%% If the expected type of variable is not present, e.g. integer when -%%% integer() is expected, or an I/O list when iolist() is expected, -%%% then the driver will ignore the user's input and use a default -%%% value of 0 or NULL, respectively. - --export([init/0, available/0, - user_trace_s1/1, % TODO: unify with pid & tag args like user_trace_i4s4 - p/0, p/1, p/2, p/3, p/4, p/5, p/6, p/7, p/8]). --export([put_utag/1, get_utag/0, get_utag_data/0, spread_utag/1, restore_utag/1]). - --export([scaff/0]). % Development only --export([user_trace_i4s4/9]). % Know what you're doing! - --type probe_arg() :: integer() | iolist(). --type int_p_arg() :: integer() | iolist() | undef. -%% The *_maybe() types use atom() instead of a stricter 'undef' -%% because user_trace_i4s4/9 is exposed to the outside world, and -%% because the driver will allow any atom to be used as a "not -%% present" indication, we'll allow any atom in the types. --type integer_maybe() :: integer() | atom(). --type iolist_maybe() :: iolist() | atom(). - --spec init() -> ok | {error, {term(), term()}}. - -init() -> - PrivDir = code:priv_dir(dtrace), - Lib = filename:join([PrivDir, "lib", "dtrace"]), - erlang:load_nif(Lib, 0). - -%%% -%%% NIF placeholders -%%% - --spec available() -> true | false. - -available() -> - erlang:nif_error(nif_not_loaded). - --spec user_trace_s1(iolist()) -> true | false | error | badarg. - -user_trace_s1(_Message) -> - erlang:nif_error(nif_not_loaded). - --spec user_trace_i4s4(iolist(), - integer_maybe(), integer_maybe(), - integer_maybe(), integer_maybe(), - iolist_maybe(), iolist_maybe(), - iolist_maybe(), iolist_maybe()) -> - true | false | error | badarg. - -user_trace_i4s4(_, _, _, _, _, _, _, _, _) -> - erlang:nif_error(nif_not_loaded). - -%%% -%%% Erlang support functions -%%% - --spec p() -> true | false | error | badarg. - -p() -> - user_trace_int(undef, undef, undef, undef, undef, undef, undef, undef). - --spec p(probe_arg()) -> true | false | error | badarg. - -p(I1) when is_integer(I1) -> - user_trace_int(I1, undef, undef, undef, undef, undef, undef, undef); -p(S1) -> - user_trace_int(undef, undef, undef, undef, S1, undef, undef, undef). - --spec p(probe_arg(), probe_arg()) -> true | false | error | badarg. - -p(I1, I2) when is_integer(I1), is_integer(I2) -> - user_trace_int(I1, I2, undef, undef, undef, undef, undef, undef); -p(I1, S1) when is_integer(I1) -> - user_trace_int(I1, undef, undef, undef, S1, undef, undef, undef); -p(S1, S2) -> - user_trace_int(undef, undef, undef, undef, S1, S2, undef, undef). - --spec p(probe_arg(), probe_arg(), probe_arg()) -> true | false | error | badarg. - -p(I1, I2, I3) when is_integer(I1), is_integer(I2), is_integer(I3) -> - user_trace_int(I1, I2, I3, undef, undef, undef, undef, undef); -p(I1, I2, S1) when is_integer(I1), is_integer(I2) -> - user_trace_int(I1, I2, undef, undef, S1, undef, undef, undef); -p(I1, S1, S2) when is_integer(I1) -> - user_trace_int(I1, undef, undef, undef, S1, S2, undef, undef); -p(S1, S2, S3) -> - user_trace_int(undef, undef, undef, undef, S1, S2, S3, undef). - --spec p(probe_arg(), probe_arg(), probe_arg(), probe_arg()) -> - true | false | error | badarg. - -p(I1, I2, I3, I4) when is_integer(I1), is_integer(I2), is_integer(I3), is_integer(I4) -> - user_trace_int(I1, I2, I3, I4, undef, undef, undef, undef); -p(I1, I2, I3, S1) when is_integer(I1), is_integer(I2), is_integer(I3) -> - user_trace_int(I1, I2, I3, undef, S1, undef, undef, undef); -p(I1, I2, S1, S2) when is_integer(I1), is_integer(I2) -> - user_trace_int(I1, I2, undef, undef, S1, S2, undef, undef); -p(I1, S1, S2, S3) when is_integer(I1) -> - user_trace_int(I1, undef, undef, undef, S1, S2, S3, undef); -p(S1, S2, S3, S4) -> - user_trace_int(undef, undef, undef, undef, S1, S2, S3, S4). - --spec p(probe_arg(), probe_arg(), probe_arg(), probe_arg(), - probe_arg()) -> - true | false | error | badarg. - -p(I1, I2, I3, I4, S1) when is_integer(I1), is_integer(I2), is_integer(I3), is_integer(I4) -> - user_trace_int(I1, I2, I3, I4, S1, undef, undef, undef); -p(I1, I2, I3, S1, S2) when is_integer(I1), is_integer(I2), is_integer(I3) -> - user_trace_int(I1, I2, I3, undef, S1, S2, undef, undef); -p(I1, I2, S1, S2, S3) when is_integer(I1), is_integer(I2) -> - user_trace_int(I1, I2, undef, undef, S1, S2, S3, undef); -p(I1, S1, S2, S3, S4) when is_integer(I1) -> - user_trace_int(I1, undef, undef, undef, S1, S2, S3, S4). - --spec p(probe_arg(), probe_arg(), probe_arg(), probe_arg(), - probe_arg(), probe_arg()) -> - true | false | error | badarg. - -p(I1, I2, I3, I4, S1, S2) when is_integer(I1), is_integer(I2), is_integer(I3), is_integer(I4) -> - user_trace_int(I1, I2, I3, I4, S1, S2, undef, undef); -p(I1, I2, I3, S1, S2, S3) when is_integer(I1), is_integer(I2), is_integer(I3) -> - user_trace_int(I1, I2, I3, undef, S1, S2, S3, undef); -p(I1, I2, S1, S2, S3, S4) when is_integer(I1), is_integer(I2) -> - user_trace_int(I1, I2, undef, undef, S1, S2, S3, S4). - --spec p(probe_arg(), probe_arg(), probe_arg(), probe_arg(), - probe_arg(), probe_arg(), probe_arg()) -> - true | false | error | badarg. - -p(I1, I2, I3, I4, S1, S2, S3) when is_integer(I1), is_integer(I2), is_integer(I3), is_integer(I4) -> - user_trace_int(I1, I2, I3, I4, S1, S2, S3, undef); -p(I1, I2, I3, S1, S2, S3, S4) when is_integer(I1), is_integer(I2), is_integer(I3) -> - user_trace_int(I1, I2, I3, undef, S1, S2, S3, S4). - --spec p(probe_arg(), probe_arg(), probe_arg(), probe_arg(), - probe_arg(), probe_arg(), probe_arg(), probe_arg()) -> - true | false | error | badarg. - -p(I1, I2, I3, I4, S1, S2, S3, S4) when is_integer(I1), is_integer(I2), is_integer(I3), is_integer(I4) -> - user_trace_int(I1, I2, I3, I4, S1, S2, S3, S4). - --spec user_trace_int(int_p_arg(), int_p_arg(), int_p_arg(), int_p_arg(), - int_p_arg(), int_p_arg(), int_p_arg(), int_p_arg()) -> - true | false | error | badarg. - -user_trace_int(I1, I2, I3, I4, S1, S2, S3, S4) -> - UTag = get_utag(), - try - user_trace_i4s4(UTag, I1, I2, I3, I4, S1, S2, S3, S4) - catch - error:nif_not_loaded -> - false - end. - --spec put_utag(undefined | iodata()) -> binary() | undefined. -put_utag(Data) -> - erlang:put_utag(unicode:characters_to_binary(Data)). - --spec get_utag() -> binary() | undefined. -get_utag() -> - erlang:get_utag(). - --spec get_utag_data() -> binary() | undefined. -%% Gets utag if set, otherwise the spread utag data from last incoming message -get_utag_data() -> - erlang:get_utag_data(). - --spec spread_utag(boolean()) -> true | {non_neg_integer(), binary() | []}. -%% Makes the utag behave as a sequential trace token, will spread with messages to be picked up by someone using -%% get_utag_data or get_drv_utag_data. -spread_utag(B) -> - erlang:spread_utag(B). - --spec restore_utag(true | {non_neg_integer(), binary() | []}) -> true. -restore_utag(T) -> - erlang:restore_utag(T). - - -%% Scaffolding to write tedious code: quick brute force and not 100% correct. - -scaff_int_args(N) -> - L = lists:sublist(["I1", "I2", "I3", "I4"], N), - [string:join(L, ", ")]. - -scaff_int_guards(N) -> - L = lists:sublist(["is_integer(I1)", "is_integer(I2)", "is_integer(I3)", - "is_integer(I4)"], N), - lists:flatten(string:join(L, ", ")). - -scaff_char_args(N) -> - L = lists:sublist(["S1", "S2", "S3", "S4"], N), - [string:join(L, ", ")]. - -scaff_fill(N) -> - [string:join(lists:duplicate(N, "undef"), ", ")]. - -scaff() -> - L = [begin - IntArgs = scaff_int_args(N_int), - IntGuards = scaff_int_guards(N_int), - IntFill = scaff_fill(4 - N_int), - CharArgs = scaff_char_args(N_char), - CharFill = scaff_fill(4 - N_char), - InArgs = string:join(IntArgs ++ CharArgs, ", "), - OutArgs = string:join(IntArgs ++ IntFill ++ CharArgs ++ CharFill, - ", "), - {N_int + N_char, - lists:flatten([io_lib:format("p(~s) when ~s ->\n", - [InArgs, IntGuards]), - io_lib:format(" user_trace_int(~s);\n", [OutArgs]) - ])} - end || N_int <- [0,1,2,3,4], N_char <- [0,1,2,3,4]], - [io:format("%%~p\n~s", [N, Str]) || {N, Str} <- lists:sort(L)]. diff --git a/lib/dtrace/vsn.mk b/lib/dtrace/vsn.mk deleted file mode 100644 index 73bf983c00..0000000000 --- a/lib/dtrace/vsn.mk +++ /dev/null @@ -1 +0,0 @@ -DTRACE_VSN = 0.8 diff --git a/lib/runtime_tools/c_src/Makefile.in b/lib/runtime_tools/c_src/Makefile.in index 3d9a7ed69d..120f9b913f 100644 --- a/lib/runtime_tools/c_src/Makefile.in +++ b/lib/runtime_tools/c_src/Makefile.in @@ -20,6 +20,11 @@ include $(ERL_TOP)/make/target.mk include $(ERL_TOP)/make/$(TARGET)/otp.mk include $(ERL_TOP)/make/$(TARGET)/otp_ded.mk +# ---------------------------------------------------- +# Items from top-level configure +# ---------------------------------------------------- +DTRACE_ENABLED=@DTRACE_ENABLED@ +DTRACE_ENABLED_2STEP=@DTRACE_ENABLED_2STEP@ # ---------------------------------------------------- # Application version # ---------------------------------------------------- @@ -38,6 +43,8 @@ SHELL = /bin/sh LIBS = $(DED_LIBS) LDFLAGS += $(DED_LDFLAGS) +DTRACE_LIBNAME = dyntrace + SYSINCLUDE = $(DED_SYS_INCLUDE) ifeq ($(findstring vxworks,$(TARGET)),vxworks) SYSINCLUDE += -I$(ERL_TOP)/erts/etc/vxworks @@ -45,15 +52,20 @@ endif TRACE_DRV_INCLUDES = $(SYSINCLUDE) -ALL_CFLAGS = $(CFLAGS) @DEFS@ $(TYPE_FLAGS) $(TRACE_DRV_INCLUDES) - +ALL_CFLAGS = $(CFLAGS) @DEFS@ $(TYPE_FLAGS) $(TRACE_DRV_INCLUDES) \ + -I$(OBJDIR) -I$(ERL_TOP)/erts/emulator/$(TARGET) ifeq ($(TYPE),debug) TYPEMARKER = .debug -TYPE_FLAGS = -g -DDEBUG @DEBUG_FLAGS@ +TYPE_FLAGS = $(subst -O3,,$(subst -O2,,$(CFLAGS))) -DDEBUG @DEBUG_FLAGS@ +else +ifeq ($(TYPE),valgrind) +TYPEMARKER = .valgrind +TYPE_FLAGS = $(subst -O3,,$(subst -O2,,$(CFLAGS))) -DVALGRIND else TYPEMARKER = -TYPE_FLAGS = -O2 +TYPE_FLAGS = $(CFLAGS) +endif endif ROOTDIR = $(ERL_TOP)/lib @@ -69,6 +81,16 @@ RELSYSDIR = $(RELEASE_PATH)/lib/runtime_tools-$(VSN) # ---------------------------------------------------- # Misc Macros # ---------------------------------------------------- +before_DTrace_OBJS = $(OBJDIR)/dyntrace$(TYPEMARKER).o +## NIF_MAKEFILE = $(PRIVDIR)/Makefile + +# Higher-level makefiles says that we can only compile on UNIX flavors +NIF_LIB = $(LIBDIR)/dyntrace$(TYPEMARKER).@DED_EXT@ + +ifeq ($(HOST_OS),) +HOST_OS := $(shell $(ERL_TOP)/erts/autoconf/config.guess) +endif + TRACE_IP_DRV_OBJS = \ $(OBJDIR)/trace_ip_drv.o @@ -91,7 +113,44 @@ endif _create_dirs := $(shell mkdir -p $(OBJDIR) $(LIBDIR)) -debug opt: $(SOLIBS) +debug opt valgrind: $(SOLIBS) $(OBJDIR) $(LIBDIR) $(NIF_LIB) + +ifdef DTRACE_ENABLED +DTRACE_USER_HEADER=$(OBJDIR)/dtrace_user.h +$(OBJDIR)/dtrace_user.h: ./dtrace_user.d + dtrace -h -C $(INCLUDES) \ + -s ./dtrace_user.d \ + -o ./dtrace_user.tmp + sed -e '/^#define[ ]*ERLANG_[A-Z0-9_]*(.*)/y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/' ./dtrace_user.tmp > $@ + rm ./dtrace_user.tmp +else +DTRACE_USER_HEADER= +endif + +DTRACE_OBJS = +ifdef DTRACE_ENABLED_2STEP +DTRACE_OBJS += $(OBJDIR)/dtrace_user.o +$(OBJDIR)/dtrace_user.o: $(before_DTrace_OBJS) $(OBJDIR)/dtrace_user.h + dtrace -G -C \ + -s ./dtrace_user.d \ + -o $@ $(before_DTrace_OBJS) +endif + +DYNTRACE_OBJS = $(before_DTrace_OBJS) $(DTRACE_OBJS) + +$(OBJDIR): + -@mkdir -p $(OBJDIR) + +$(LIBDIR): + -@mkdir -p $(LIBDIR) + +$(OBJDIR)/dyntrace$(TYPEMARKER).o: dyntrace.c $(DTRACE_USER_HEADER) + $(INSTALL_DIR) $(OBJDIR) + $(CC) -c -o $@ $(ALL_CFLAGS) $< + +$(NIF_LIB): $(DYNTRACE_OBJS) + $(INSTALL_DIR) $(LIBDIR) + $(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS) $(OBJDIR)/%.o: %.c $(CC) -c -o $@ $(ALL_CFLAGS) $< @@ -118,6 +177,12 @@ $(LIBDIR)/trace_file_drv.eld: $(TRACE_FILE_DRV_OBJS) clean: rm -f $(SOLIBS) $(TRACE_IP_DRV_OBJS) $(TRACE_FILE_DRV_OBJS) + rm -f $(LIBDIR)/dyntrace.@DED_EXT@ + rm -f $(LIBDIR)/dyntrace.debug.@DED_EXT@ + rm -f $(LIBDIR)/dyntrace.valgrind.@DED_EXT@ + rm -f $(OBJDIR)/dyntrace.o + rm -f $(OBJDIR)/dyntrace.debug.o + rm -f $(OBJDIR)/dyntrace.valgrind.o rm -f core *~ docs: @@ -128,8 +193,10 @@ docs: include $(ERL_TOP)/make/otp_release_targets.mk release_spec: opt + $(INSTALL_DIR) $(RELSYSDIR)/priv/obj $(INSTALL_DIR) $(RELSYSDIR)/priv/lib - $(INSTALL_PROGRAM) $(SOLIBS) $(RELSYSDIR)/priv/lib + $(INSTALL_PROGRAM) $(DYNTRACE_OBJS) $(RELSYSDIR)/priv/obj + $(INSTALL_PROGRAM) $(NIF_LIB) $(SOLIBS) $(RELSYSDIR)/priv/lib release_docs_spec: diff --git a/lib/runtime_tools/c_src/dtrace_user.d b/lib/runtime_tools/c_src/dtrace_user.d new file mode 100644 index 0000000000..45d3ef3b66 --- /dev/null +++ b/lib/runtime_tools/c_src/dtrace_user.d @@ -0,0 +1,53 @@ +/* + * %CopyrightBegin% + * + * Copyright Scott Lystig Fritchie 2011. + * All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +provider erlang { + /** + * Send a single string to a probe. + * + * @param NUL-terminated string + */ + probe user_trace__s1(char* message); + + /** + * Multi-purpose probe: up to 4 NUL-terminated strings and 4 + * 64-bit integer arguments. + * + * @param proc, the PID (string form) of the sending process + * @param user_tag, the user tag of the sender + * @param i1, integer + * @param i2, integer + * @param i3, integer + * @param i4, integer + * @param s1, string/iolist. D's arg6 is NULL if not given by Erlang + * @param s2, string/iolist. D's arg7 is NULL if not given by Erlang + * @param s3, string/iolist. D's arg8 is NULL if not given by Erlang + * @param s4, string/iolist. D's arg9 is NULL if not given by Erlang + */ + probe user_trace__i4s4(char *proc, char *user_tag, + int i1, int i2, int i3, int i4, + char *s1, char *s2, char *s3, char *s4); +}; + +#pragma D attributes Evolving/Evolving/Common provider erlang provider +#pragma D attributes Private/Private/Common provider erlang module +#pragma D attributes Private/Private/Common provider erlang function +#pragma D attributes Evolving/Evolving/Common provider erlang name +#pragma D attributes Evolving/Evolving/Common provider erlang args diff --git a/lib/runtime_tools/c_src/dyntrace.c b/lib/runtime_tools/c_src/dyntrace.c new file mode 100644 index 0000000000..d94014559d --- /dev/null +++ b/lib/runtime_tools/c_src/dyntrace.c @@ -0,0 +1,172 @@ +/* + * %CopyrightBegin% + * + * Copyright Scott Lystig Fritchie 2011. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +/* + * Purpose: Dynamically loadable NIF library for DTrace + */ + + + +#include "erl_nif.h" +#include "config.h" +#include "sys.h" +#include "dtrace-wrapper.h" +#if defined(USE_DYNAMIC_TRACE) && (defined(USE_DTRACE) || defined(USE_SYSTEMTAP)) +#define HAVE_USE_DTRACE 1 +#endif +#ifdef HAVE_USE_DTRACE +#include "dtrace_user.h" +#endif + +void dtrace_nifenv_str(ErlNifEnv *env, char *process_buf); +void get_string_maybe(ErlNifEnv *env, const ERL_NIF_TERM term, char **ptr, char *buf, int bufsiz); + +#ifdef VALGRIND + # include +#endif + +#ifdef __GNUC__ + # define INLINE __inline__ +#else + # define INLINE +#endif + +#define MESSAGE_BUFSIZ 1024 + +/* NIF interface declarations */ +static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info); + +/* The NIFs: */ +static ERL_NIF_TERM available(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM user_trace_s1(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM user_trace_i4s4(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); + +static ErlNifFunc nif_funcs[] = { + {"available", 0, available}, + {"user_trace_s1", 1, user_trace_s1}, + {"user_trace_i4s4", 9, user_trace_i4s4} +}; + +ERL_NIF_INIT(dyntrace, nif_funcs, load, NULL, NULL, NULL) + +static ERL_NIF_TERM atom_true; +static ERL_NIF_TERM atom_false; +static ERL_NIF_TERM atom_error; +static ERL_NIF_TERM atom_not_available; +static ERL_NIF_TERM atom_badarg; +static ERL_NIF_TERM atom_ok; + +static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) +{ + atom_true = enif_make_atom(env,"true"); + atom_false = enif_make_atom(env,"false"); + atom_error = enif_make_atom(env,"error"); + atom_not_available = enif_make_atom(env,"not_available"); + atom_badarg = enif_make_atom(env,"badarg"); + atom_ok = enif_make_atom(env,"ok"); + + return 0; +} + +static ERL_NIF_TERM available(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ +#ifdef HAVE_USE_DTRACE + return atom_true; +#else + return atom_false; +#endif +} + +static ERL_NIF_TERM user_trace_s1(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ +#ifdef HAVE_USE_DTRACE + ErlNifBinary message_bin; + DTRACE_CHARBUF(messagebuf, MESSAGE_BUFSIZ + 1); + + if (DTRACE_ENABLED(user_trace_s1)) { + if (!enif_inspect_iolist_as_binary(env, argv[0], &message_bin) || + message_bin.size > MESSAGE_BUFSIZ) { + return atom_badarg; + } + memcpy(messagebuf, (char *) message_bin.data, message_bin.size); + messagebuf[message_bin.size] = '\0'; + DTRACE1(user_trace_s1, messagebuf); + return atom_true; + } else { + return atom_false; + } +#else + return atom_error; +#endif +} + +void +get_string_maybe(ErlNifEnv *env, + const ERL_NIF_TERM term, char **ptr, char *buf, int bufsiz) +{ + ErlNifBinary str_bin; + + if (!enif_inspect_iolist_as_binary(env, term, &str_bin) || + str_bin.size > bufsiz) { + *ptr = NULL; + } else { + memcpy(buf, (char *) str_bin.data, str_bin.size); + buf[str_bin.size] = '\0'; + *ptr = buf; + } +} + +static ERL_NIF_TERM user_trace_i4s4(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ +#ifdef HAVE_USE_DTRACE + DTRACE_CHARBUF(procbuf, 32 + 1); + DTRACE_CHARBUF(user_tagbuf, MESSAGE_BUFSIZ + 1); + char *utbuf = NULL; + ErlNifSInt64 i1, i2, i3, i4; + DTRACE_CHARBUF(messagebuf1, MESSAGE_BUFSIZ + 1); + DTRACE_CHARBUF(messagebuf2, MESSAGE_BUFSIZ + 1); + DTRACE_CHARBUF(messagebuf3, MESSAGE_BUFSIZ + 1); + DTRACE_CHARBUF(messagebuf4, MESSAGE_BUFSIZ + 1); + char *mbuf1 = NULL, *mbuf2 = NULL, *mbuf3 = NULL, *mbuf4 = NULL; + + if (DTRACE_ENABLED(user_trace_i4s4)) { + dtrace_nifenv_str(env, procbuf); + get_string_maybe(env, argv[0], &utbuf, user_tagbuf, MESSAGE_BUFSIZ); + if (! enif_get_int64(env, argv[1], &i1)) + i1 = 0; + if (! enif_get_int64(env, argv[2], &i2)) + i2 = 0; + if (! enif_get_int64(env, argv[3], &i3)) + i3 = 0; + if (! enif_get_int64(env, argv[4], &i4)) + i4 = 0; + get_string_maybe(env, argv[5], &mbuf1, messagebuf1, MESSAGE_BUFSIZ); + get_string_maybe(env, argv[6], &mbuf2, messagebuf2, MESSAGE_BUFSIZ); + get_string_maybe(env, argv[7], &mbuf3, messagebuf3, MESSAGE_BUFSIZ); + get_string_maybe(env, argv[8], &mbuf4, messagebuf4, MESSAGE_BUFSIZ); + DTRACE10(user_trace_i4s4, procbuf, utbuf, + i1, i2, i3, i4, mbuf1, mbuf2, mbuf3, mbuf4); + return atom_true; + } else { + return atom_false; + } +#else + return atom_error; +#endif +} diff --git a/lib/runtime_tools/examples/dist.d b/lib/runtime_tools/examples/dist.d new file mode 100644 index 0000000000..550e10d363 --- /dev/null +++ b/lib/runtime_tools/examples/dist.d @@ -0,0 +1,62 @@ +/* example usage: dtrace -q -s /path/to/dist.d */ +/* + * %CopyrightBegin% + * + * Copyright Scott Lystig Fritchie 2011. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +erlang*:::dist-monitor +{ + printf("monitor: pid %d, who %s, what %s, node %s, type %s, reason %s\n", + pid, + copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), copyinstr(arg3), + copyinstr(arg4)); +} + +erlang*:::dist-port_busy +{ + printf("dist port_busy: node %s, port %s, remote_node %s, blocked pid %s\n", + copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), copyinstr(arg3)); + /* + * For variable use advice, see: + * http://dtrace.org/blogs/brendan/2011/11/25/dtrace-variable-types/ + * + * Howevever, it's quite possible for the blocked events to span + * threads, so we'll use globals. + */ + blocked_procs[copyinstr(arg3)] = timestamp; +} + +erlang*:::dist-output +{ + printf("dist output: node %s, port %s, remote_node %s bytes %d\n", + copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), arg3); +} + +erlang*:::dist-outputv +{ + printf("port outputv: node %s, port %s, remote_node %s bytes %d\n", + copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), arg3); +} + +erlang*:::process-scheduled +/blocked_procs[copyinstr(arg0)]/ +{ + pidstr = copyinstr(arg0); + printf("blocked pid %s scheduled now, waited %d microseconds\n", + pidstr, (timestamp - blocked_procs[pidstr]) / 1000); + blocked_procs[pidstr] = 0; +} diff --git a/lib/runtime_tools/examples/dist.systemtap b/lib/runtime_tools/examples/dist.systemtap new file mode 100644 index 0000000000..af27b2cab6 --- /dev/null +++ b/lib/runtime_tools/examples/dist.systemtap @@ -0,0 +1,76 @@ +/* example usage: stap /path/to/dist.systemtap -x */ +/* + * %CopyrightBegin% + * + * Copyright Scott Lystig Fritchie and Andreas Schultz, 2011. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ +/* + * Note: This file assumes that you're using the non-SMP-enabled Erlang + * virtual machine, "beam". The SMP-enabled VM is called "beam.smp". + * Note that other variations of the virtual machine also have + * different names, e.g. the debug build of the SMP-enabled VM + * is "beam.debug.smp". + * + * To use a different virtual machine, replace each instance of + * "beam" with "beam.smp" or the VM name appropriate to your + * environment. + */ + +probe process("beam").mark("dist-monitor") +{ + printf("monitor: pid %d, who %s, what %s, node %s, type %s, reason %s\n", + pid(), + user_string($arg1), user_string($arg2), user_string($arg3), user_string($arg4), + user_string($arg5)); +} + +probe process("beam").mark("dist-port_busy") +{ + printf("dist port_busy: node %s, port %s, remote_node %s, blocked pid %s\n", + user_string($arg1), user_string($arg2), user_string($arg3), user_string($arg4)); + blocked_procs[user_string($arg4)] = timestamp; +} + +probe process("beam").mark("dist-port_busy") +{ + printf("dist port_busy: node %s, port %s, remote_node %s, blocked pid %s\n", + user_string($arg1), user_string($arg2), user_string($arg3), user_string($arg4)); + blocked_procs[user_string($arg4)] = timestamp; +} + +probe process("beam").mark("dist-output") +{ + printf("dist output: node %s, port %s, remote_node %s bytes %d\n", + user_string($arg1), user_string($arg2), user_string($arg3), $arg4); +} + +probe process("beam").mark("dist-outputv") +{ + printf("port outputv: node %s, port %s, remote_node %s bytes %d\n", + user_string($arg1), user_string($arg2), user_string($arg3), $arg4); +} + +probe process("beam").mark("process-scheduled") +{ + pidstr = user_string($arg1); + if (pidstr in blocked_procs) { + printf("blocked pid %s scheduled now, waited %d microseconds\n", + pidstr, (timestamp - blocked_procs[pidstr]) / 1000); + delete blocked_procs[pidstr]; + } +} + +global blocked_procs; diff --git a/lib/runtime_tools/examples/driver1.d b/lib/runtime_tools/examples/driver1.d new file mode 100644 index 0000000000..9f53ffeb2a --- /dev/null +++ b/lib/runtime_tools/examples/driver1.d @@ -0,0 +1,114 @@ +/* example usage: dtrace -q -s /path/to/driver1.d */ +/* + * %CopyrightBegin% + * + * Copyright Scott Lystig Fritchie 2011. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +erlang*:::driver-init +{ + printf("driver init name %s major %d minor %d flags %d\n", + copyinstr(arg0), arg1, arg2, arg3); +} + +erlang*:::driver-start +{ + printf("driver start pid %s driver name %s port %s\n", + copyinstr(arg0), copyinstr(arg1), copyinstr(arg2)); +} + +erlang*:::driver-stop +{ + printf("driver stop pid %s driver name %s port %s\n", + copyinstr(arg0), copyinstr(arg1), copyinstr(arg2)); +} + +erlang*:::driver-finish +{ + printf("driver finish driver name %s port %s\n", + copyinstr(arg0), copyinstr(arg1)); +} + +erlang*:::driver-flush +{ + printf("driver flush pid %s port %s port name %s\n", + copyinstr(arg0), copyinstr(arg1), copyinstr(arg2)); +} + +erlang*:::driver-output +{ + printf("driver output pid %s port %s port name %s bytes %d\n", + copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), arg3); +} + +erlang*:::driver-outputv +{ + printf("driver outputv pid %s port %s port name %s bytes %d\n", + copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), arg3); +} + +erlang*:::driver-control +{ + printf("driver control pid %s port %s port name %s command %d bytes %d\n", + copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), arg3, arg4); +} + +erlang*:::driver-call +{ + printf("driver call pid %s port %s port name %s command %d bytes %d\n", + copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), arg3, arg4); +} + +erlang*:::driver-event +{ + printf("driver event pid %s port %s port name %s\n", + copyinstr(arg0), copyinstr(arg1), copyinstr(arg2)); +} + +erlang*:::driver-ready_input +{ + printf("driver ready_input pid %s port %s port name %s\n", + copyinstr(arg0), copyinstr(arg1), copyinstr(arg2)); +} + +erlang*:::driver-ready_output +{ + printf("driver ready_output pid %s port %s port name %s\n", + copyinstr(arg0), copyinstr(arg1), copyinstr(arg2)); +} + +erlang*:::driver-timeout +{ + printf("driver timeout pid %s port %s port name %s\n", + copyinstr(arg0), copyinstr(arg1), copyinstr(arg2)); +} + +erlang*:::driver-ready_async +{ + printf("driver ready_async pid %s port %s port name %s\n", + copyinstr(arg0), copyinstr(arg1), copyinstr(arg2)); +} + +erlang*:::driver-process_exit +{ + printf("driver process_exit pid %s port %s port name %s\n", + copyinstr(arg0), copyinstr(arg1), copyinstr(arg2)); +} + +erlang*:::driver-stop_select +{ + printf("driver stop_select driver name %s\n", copyinstr(arg0)); +} diff --git a/lib/runtime_tools/examples/driver1.systemtap b/lib/runtime_tools/examples/driver1.systemtap new file mode 100644 index 0000000000..8b99e465b7 --- /dev/null +++ b/lib/runtime_tools/examples/driver1.systemtap @@ -0,0 +1,125 @@ +/* example usage: stap /path/to/driver1.systemtap -x */ +/* + * %CopyrightBegin% + * + * Copyright Scott Lystig Fritchie and Andreas Schultz, 2011. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ +/* + * Note: This file assumes that you're using the non-SMP-enabled Erlang + * virtual machine, "beam". The SMP-enabled VM is called "beam.smp". + * Note that other variations of the virtual machine also have + * different names, e.g. the debug build of the SMP-enabled VM + * is "beam.debug.smp". + * + * To use a different virtual machine, replace each instance of + * "beam" with "beam.smp" or the VM name appropriate to your + * environment. + */ + +probe process("beam").mark("driver-init") +{ + printf("driver init name %s major %d minor %d flags %d\n", + user_string($arg1), $arg2, $arg3, $arg4); +} + +probe process("beam").mark("driver-start") +{ + printf("driver start pid %s driver name %s port %s\n", + user_string($arg1), user_string($arg2), user_string($arg3)); +} + +probe process("beam").mark("driver-stop") +{ + printf("driver stop pid %s driver name %s port %s\n", + user_string($arg1), user_string($arg2), user_string($arg3)); +} + +probe process("beam").mark("driver-finish") +{ + printf("driver finish driver name %s\n", + user_string($arg1)); +} + +probe process("beam").mark("driver-flush") +{ + printf("driver flush pid %s port %s port name %s\n", + user_string($arg1), user_string($arg2), user_string($arg3)); +} + +probe process("beam").mark("driver-output") +{ + printf("driver output pid %s port %s port name %s bytes %d\n", + user_string($arg1), user_string($arg2), user_string($arg3), $arg4); +} + +probe process("beam").mark("driver-outputv") +{ + printf("driver outputv pid %s port %s port name %s bytes %d\n", + user_string($arg1), user_string($arg2), user_string($arg3), $arg4); +} + +probe process("beam").mark("driver-control") +{ + printf("driver control pid %s port %s port name %s command %d bytes %d\n", + user_string($arg1), user_string($arg2), user_string($arg3), $arg4, $arg5); +} + +probe process("beam").mark("driver-call") +{ + printf("driver call pid %s port %s port name %s command %d bytes %d\n", + user_string($arg1), user_string($arg2), user_string($arg3), $arg4, $arg5); +} + +probe process("beam").mark("driver-event") +{ + printf("driver event pid %s port %s port name %s\n", + user_string($arg1), user_string($arg2), user_string($arg3)); +} + +probe process("beam").mark("driver-ready_input") +{ + printf("driver ready_input pid %s port %s port name %s\n", + user_string($arg1), user_string($arg2), user_string($arg3)); +} + +probe process("beam").mark("driver-ready_output") +{ + printf("driver ready_output pid %s port %s port name %s\n", + user_string($arg1), user_string($arg2), user_string($arg3)); +} + +probe process("beam").mark("driver-timeout") +{ + printf("driver timeout pid %s port %s port name %s\n", + user_string($arg1), user_string($arg2), user_string($arg3)); +} + +probe process("beam").mark("driver-ready_async") +{ + printf("driver ready_async pid %s port %s port name %s\n", + user_string($arg1), user_string($arg2), user_string($arg3)); +} + +probe process("beam").mark("driver-process_exit") +{ + printf("driver process_exit pid %s port %s port name %s\n", + user_string($arg1), user_string($arg2), user_string($arg3)); +} + +probe process("beam").mark("driver-stop_select") +{ + printf("driver stop_select driver name %s\n", user_string($arg1)); +} diff --git a/lib/runtime_tools/examples/efile_drv.d b/lib/runtime_tools/examples/efile_drv.d new file mode 100644 index 0000000000..085995ce58 --- /dev/null +++ b/lib/runtime_tools/examples/efile_drv.d @@ -0,0 +1,104 @@ +/* example usage: dtrace -q -s /path/to/efile_drv.d */ +/* + * %CopyrightBegin% + * + * Copyright Scott Lystig Fritchie 2011. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +BEGIN +{ + op_map[1] = "OPEN"; + op_map[2] = "READ"; + op_map[3] = "LSEEK"; + op_map[4] = "WRITE"; + op_map[5] = "FSTAT"; + op_map[6] = "PWD"; + op_map[7] = "READDIR"; + op_map[8] = "CHDIR"; + op_map[9] = "FSYNC"; + op_map[10] = "MKDIR"; + op_map[11] = "DELETE"; + op_map[12] = "RENAME"; + op_map[13] = "RMDIR"; + op_map[14] = "TRUNCATE"; + op_map[15] = "READ_FILE"; + op_map[16] = "WRITE_INFO"; + op_map[19] = "LSTAT"; + op_map[20] = "READLINK"; + op_map[21] = "LINK"; + op_map[22] = "SYMLINK"; + op_map[23] = "CLOSE"; + op_map[24] = "PWRITEV"; + op_map[25] = "PREADV"; + op_map[26] = "SETOPT"; + op_map[27] = "IPREAD"; + op_map[28] = "ALTNAME"; + op_map[29] = "READ_LINE"; + op_map[30] = "FDATASYNC"; + op_map[31] = "FADVISE"; +} + +erlang*:::aio_pool-add +{ + printf("async I/O pool port %s queue len %d\n", copyinstr(arg0), arg1); +} + +erlang*:::aio_pool-get +{ + printf("async I/O pool port %s queue len %d\n", copyinstr(arg0), arg1); +} + +erlang*:::efile_drv-entry +{ + printf("efile_drv enter tag={%d,%d} %s%s | %s (%d) | args: %s %s , %d %d (port %s)\n", + arg0, arg1, + arg2 == NULL ? "" : "user tag ", + arg2 == NULL ? "" : copyinstr(arg2), + op_map[arg3], arg3, + arg4 == NULL ? "" : copyinstr(arg4), + arg5 == NULL ? "" : copyinstr(arg5), arg6, arg7, + /* NOTE: port name in args[10] is experimental */ + (args[10] == NULL) ? + "?" : copyinstr((user_addr_t) args[10])); +} + +erlang*:::efile_drv-int* +{ + printf("async I/O worker tag={%d,%d} | %s (%d) | %s\n", + arg0, arg1, op_map[arg2], arg2, probename); +} + +/* efile_drv-return error case */ +erlang*:::efile_drv-return +/arg4 == 0/ +{ + printf("efile_drv return tag={%d,%d} %s%s | %s (%d) | errno %d\n", + arg0, arg1, + arg2 == NULL ? "" : "user tag ", + arg2 == NULL ? "" : copyinstr(arg2), + op_map[arg3], arg3, + arg5); +} + +/* efile_drv-return success case */ +erlang*:::efile_drv-return +/arg4 != 0/ +{ + printf("efile_drv return tag={%d,%d} %s | %s (%d) ok\n", + arg0, arg1, + arg2 == NULL ? "" : copyinstr(arg2), + op_map[arg3], arg3); +} diff --git a/lib/runtime_tools/examples/efile_drv.systemtap b/lib/runtime_tools/examples/efile_drv.systemtap new file mode 100644 index 0000000000..5a47b3e22b --- /dev/null +++ b/lib/runtime_tools/examples/efile_drv.systemtap @@ -0,0 +1,112 @@ +/* + * %CopyrightBegin% + * + * Copyright Scott Lystig Fritchie and Andreas Schultz, 2011. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ +/* + * Note: This file assumes that you're using the non-SMP-enabled Erlang + * virtual machine, "beam". The SMP-enabled VM is called "beam.smp". + * Note that other variations of the virtual machine also have + * different names, e.g. the debug build of the SMP-enabled VM + * is "beam.debug.smp". + * + * To use a different virtual machine, replace each instance of + * "beam" with "beam.smp" or the VM name appropriate to your + * environment. + */ + +probe begin +{ + op_map[1] = "OPEN"; + op_map[2] = "READ"; + op_map[3] = "LSEEK"; + op_map[4] = "WRITE"; + op_map[5] = "FSTAT"; + op_map[6] = "PWD"; + op_map[7] = "READDIR"; + op_map[8] = "CHDIR"; + op_map[9] = "FSYNC"; + op_map[10] = "MKDIR"; + op_map[11] = "DELETE"; + op_map[12] = "RENAME"; + op_map[13] = "RMDIR"; + op_map[14] = "TRUNCATE"; + op_map[15] = "READ_FILE"; + op_map[16] = "WRITE_INFO"; + op_map[19] = "LSTAT"; + op_map[20] = "READLINK"; + op_map[21] = "LINK"; + op_map[22] = "SYMLINK"; + op_map[23] = "CLOSE"; + op_map[24] = "PWRITEV"; + op_map[25] = "PREADV"; + op_map[26] = "SETOPT"; + op_map[27] = "IPREAD"; + op_map[28] = "ALTNAME"; + op_map[29] = "READ_LINE"; + op_map[30] = "FDATASYNC"; + op_map[31] = "FADVISE"; +} + +probe process("beam").mark("aio_pool-add") +{ + printf("async I/O pool port %s queue len %d\n", user_string($arg1), $arg2); +} + +probe process("beam").mark("aio_pool-get") +{ + printf("async I/O pool port %s queue len %d\n", user_string($arg1), $arg2); +} + +probe process("beam").mark("efile_drv-entry") +{ + printf("efile_drv enter tag={%d,%d} %s%s | %s (%d) | args: %s %s , %d %d (port %s)\n", + $arg1, $arg2, + $arg3 == NULL ? "" : "user tag ", + $arg3 == NULL ? "" : user_string($arg3), + op_map[$arg4], $arg4, + $arg5 == NULL ? "" : user_string($arg5), + $arg6 == NULL ? "" : user_string($arg6), $arg7, $arg8, + /* NOTE: port name in $arg[11] is experimental */ + user_string($arg11)) +} + +probe process("beam").mark("efile_drv-int*") +{ + printf("async I/O worker tag={%d,%d} | %s (%d) | %s\n", + $arg1, $arg2, op_map[$arg3], $arg3, probefunc()); +} + +probe process("beam").mark("efile_drv-return") +{ + if ($arg5 == 0) { + /* efile_drv-return error case */ + printf("efile_drv return tag={%d,%d} %s%s | %s (%d) | errno %d\n", + $arg1, $arg2, + $arg3 == NULL ? "" : "user tag ", + $arg3 == NULL ? "" : user_string($arg3), + op_map[$arg4], $arg4, + $arg6); + } else { + /* efile_drv-return success case */ + printf("efile_drv return tag={%d,%d} %s | %s (%d) ok\n", + $arg1, $arg2, + $arg3 == NULL ? "" : user_string($arg3), + op_map[$arg4], $arg4); + } +} + +global op_map; diff --git a/lib/runtime_tools/examples/function-calls.d b/lib/runtime_tools/examples/function-calls.d new file mode 100644 index 0000000000..238c5211ac --- /dev/null +++ b/lib/runtime_tools/examples/function-calls.d @@ -0,0 +1,51 @@ +/* example usage: dtrace -q -s /path/to/function-calls.d */ +/* + * %CopyrightBegin% + * + * Copyright Scott Lystig Fritchie 2011. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +erlang*:::function-entry +{ + printf("pid %s enter %s depth %d\n", + copyinstr(arg0), copyinstr(arg1), arg2); +} + +erlang*:::function-return +{ + printf("pid %s return %s depth %d\n", + copyinstr(arg0), copyinstr(arg1), arg2); +} + +erlang*:::bif-entry +{ + printf("pid %s BIF entry mfa %s\n", copyinstr(arg0), copyinstr(arg1)); +} + +erlang*:::bif-return +{ + printf("pid %s BIF return mfa %s\n", copyinstr(arg0), copyinstr(arg1)); +} + +erlang*:::nif-entry +{ + printf("pid %s NIF entry mfa %s\n", copyinstr(arg0), copyinstr(arg1)); +} + +erlang*:::nif-return +{ + printf("pid %s NIF return mfa %s\n", copyinstr(arg0), copyinstr(arg1)); +} diff --git a/lib/runtime_tools/examples/function-calls.systemtap b/lib/runtime_tools/examples/function-calls.systemtap new file mode 100644 index 0000000000..8fc4375135 --- /dev/null +++ b/lib/runtime_tools/examples/function-calls.systemtap @@ -0,0 +1,61 @@ +/* + * %CopyrightBegin% + * + * Copyright Scott Lystig Fritchie and Andreas Schultz, 2011. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ +/* + * Note: This file assumes that you're using the non-SMP-enabled Erlang + * virtual machine, "beam". The SMP-enabled VM is called "beam.smp". + * Note that other variations of the virtual machine also have + * different names, e.g. the debug build of the SMP-enabled VM + * is "beam.debug.smp". + * + * To use a different virtual machine, replace each instance of + * "beam" with "beam.smp" or the VM name appropriate to your + * environment. + */ + +probe process("beam").mark("function-entry") +{ + printf("pid %s enter %s depth %d\n", + user_string($arg1), user_string($arg2), $arg3); +} + +probe process("beam").mark("function-return") +{ + printf("pid %s return %s depth %d\n", + user_string($arg1), user_string($arg2), $arg3); +} + +probe process("beam").mark("bif-entry") +{ + printf("pid %s BIF entry mfa %s\n", user_string($arg1), user_string($arg2)); +} + +probe process("beam").mark("bif-return") +{ + printf("pid %s BIF return mfa %s\n", user_string($arg1), user_string($arg2)); +} + +probe process("beam").mark("nif-entry") +{ + printf("pid %s NIF entry mfa %s\n", user_string($arg1), user_string($arg2)); +} + +probe process("beam").mark("nif-return") +{ + printf("pid %s NIF return mfa %s\n", user_string($arg1), user_string($arg2)); +} diff --git a/lib/runtime_tools/examples/garbage-collection.d b/lib/runtime_tools/examples/garbage-collection.d new file mode 100644 index 0000000000..f234e7d4db --- /dev/null +++ b/lib/runtime_tools/examples/garbage-collection.d @@ -0,0 +1,39 @@ +/* example usage: dtrace -q -s /path/to/garbage-collection.d */ +/* + * %CopyrightBegin% + * + * Copyright Scott Lystig Fritchie 2011. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +erlang*:::gc_major-start +{ + printf("GC major start pid %s need %d words\n", copyinstr(arg0), arg1); +} + +erlang*:::gc_minor-start +{ + printf("GC minor start pid %s need %d words\n", copyinstr(arg0), arg1); +} + +erlang*:::gc_major-end +{ + printf("GC major end pid %s reclaimed %d words\n", copyinstr(arg0), arg1); +} + +erlang*:::gc_minor-start +{ + printf("GC minor end pid %s reclaimed %d words\n", copyinstr(arg0), arg1); +} diff --git a/lib/runtime_tools/examples/garbage-collection.systemtap b/lib/runtime_tools/examples/garbage-collection.systemtap new file mode 100644 index 0000000000..64d69c6fbd --- /dev/null +++ b/lib/runtime_tools/examples/garbage-collection.systemtap @@ -0,0 +1,49 @@ +/* + * %CopyrightBegin% + * + * Copyright Scott Lystig Fritchie and Andreas Schultz, 2011. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ +/* + * Note: This file assumes that you're using the non-SMP-enabled Erlang + * virtual machine, "beam". The SMP-enabled VM is called "beam.smp". + * Note that other variations of the virtual machine also have + * different names, e.g. the debug build of the SMP-enabled VM + * is "beam.debug.smp". + * + * To use a different virtual machine, replace each instance of + * "beam" with "beam.smp" or the VM name appropriate to your + * environment. + */ + +probe process("beam").mark("gc_major-start") +{ + printf("GC major start pid %s need %d words\n", user_string($arg1), $arg2); +} + +probe process("beam").mark("gc_minor-start") +{ + printf("GC minor start pid %s need %d words\n", user_string($arg1), $arg2); +} + +probe process("beam").mark("gc_major-end") +{ + printf("GC major end pid %s reclaimed %d words\n", user_string($arg1), $arg2); +} + +probe process("beam").mark("gc_minor-start") +{ + printf("GC minor end pid %s reclaimed %d words\n", user_string($arg1), $arg2); +} diff --git a/lib/runtime_tools/examples/memory1.d b/lib/runtime_tools/examples/memory1.d new file mode 100644 index 0000000000..c2e16e0779 --- /dev/null +++ b/lib/runtime_tools/examples/memory1.d @@ -0,0 +1,41 @@ +/* example usage: dtrace -q -s /path/to/memory1.d */ +/* + * %CopyrightBegin% + * + * Copyright Scott Lystig Fritchie 2011. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +erlang*:::copy-struct +{ + printf("copy_struct %d bytes\n", arg0); +} + +erlang*:::copy-object +{ + printf("copy_object pid %s %d bytes\n", copyinstr(arg0), arg1); +} + +erlang*:::process-heap_grow +{ + printf("proc heap grow pid %s %d -> %d bytes\n", copyinstr(arg0), + arg1, arg2); +} + +erlang*:::process-heap_shrink +{ + printf("proc heap shrink pid %s %d -> %d bytes\n", copyinstr(arg0), + arg1, arg2); +} diff --git a/lib/runtime_tools/examples/memory1.systemtap b/lib/runtime_tools/examples/memory1.systemtap new file mode 100644 index 0000000000..9723f2d02d --- /dev/null +++ b/lib/runtime_tools/examples/memory1.systemtap @@ -0,0 +1,51 @@ +/* + * %CopyrightBegin% + * + * Copyright Scott Lystig Fritchie and Andreas Schultz, 2011. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ +/* + * Note: This file assumes that you're using the non-SMP-enabled Erlang + * virtual machine, "beam". The SMP-enabled VM is called "beam.smp". + * Note that other variations of the virtual machine also have + * different names, e.g. the debug build of the SMP-enabled VM + * is "beam.debug.smp". + * + * To use a different virtual machine, replace each instance of + * "beam" with "beam.smp" or the VM name appropriate to your + * environment. + */ + +probe process("beam").mark("copy-struct") +{ + printf("copy_struct %d bytes\n", $arg1); +} + +probe process("beam").mark("copy-object") +{ + printf("copy_object pid %s %d bytes\n", user_string($arg1), $arg2); +} + +probe process("beam").mark("process-heap_grow") +{ + printf("proc heap grow pid %s %d -> %d bytes\n", user_string($arg1), + $arg2, $arg3); +} + +probe process("beam").mark("process-heap_shrink") +{ + printf("proc heap shrink pid %s %d -> %d bytes\n", user_string($arg1), + $arg2, $arg3); +} diff --git a/lib/runtime_tools/examples/messages.d b/lib/runtime_tools/examples/messages.d new file mode 100644 index 0000000000..6361f3a220 --- /dev/null +++ b/lib/runtime_tools/examples/messages.d @@ -0,0 +1,94 @@ +/* example usage: dtrace -q -s /path/to/messages.d */ +/* + * %CopyrightBegin% + * + * Copyright Scott Lystig Fritchie 2011. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +BEGIN +{ + printf("\n"); + printf("NOTE: message-queue message size 4294967295 means an external\n"); + printf(" message that the code isn't smart enough to determine\n"); + printf(" the actual size.\n"); + printf("\n"); +} + +erlang*:::message-send +/arg3 == 0 && arg4 == 0 && arg5 == 0/ +{ + printf("send: %s -> %s: %d words\n", + copyinstr(arg0), copyinstr(arg1), arg2); +} + +erlang*:::message-send +/arg3 != 0 || arg4 != 0 || arg5 != 0/ +{ + printf("send: %s label %d token {%d,%d} -> %s: %d words\n", + copyinstr(arg0), + arg3, arg4, arg5, + copyinstr(arg1), arg2); +} + +/* + * TODO: + * Weird, on my OS X box, beam says arg6 = 0 but this script says 4294967296. + */ + +erlang*:::message-send-remote +/arg4 == 0 && arg5 == 0 && (arg6 == 0 || arg6 >= 4294967296)/ +{ + printf("send : %s -> %s %s: %d words\n", + copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), arg3); +} + +erlang*:::message-send-remote +/arg4 != 0 || arg5 != 0 || arg6 < 4294967296/ +{ + printf("send : %s label %d token {%d,%d} -> %s %s: %d words\n", + copyinstr(arg0), + arg4, arg5, arg6, + copyinstr(arg1), copyinstr(arg2), arg3); +} + +erlang*:::message-queued +/arg3 == 0 && arg4 == 0 && arg5 == 0/ +{ + printf("queued: %s: %d words, queue len %d\n", copyinstr(arg0), arg1, arg2); +} + +erlang*:::message-queued +/arg3 != 0 || arg4 != 0 || arg5 != 0/ +{ + printf("queued: %s label %d token {%d,%d}: %d words, queue len %d\n", + copyinstr(arg0), arg3, arg4, arg5, + arg1, arg2); +} + +erlang*:::message-receive +/arg3 == 0 && arg4 == 0 && arg5 == 0/ +{ + printf("receive: %s: %d words, queue len %d\n", + copyinstr(arg0), arg1, arg2); +} + +erlang*:::message-receive +/arg3 != 0 || arg4 != 0 || arg5 != 0/ +{ + printf("receive: %s label %d token {%d,%d}: %d words, queue len %d\n", + copyinstr(arg0), arg3, arg4, arg5, + arg1, arg2); +} diff --git a/lib/runtime_tools/examples/messages.systemtap b/lib/runtime_tools/examples/messages.systemtap new file mode 100644 index 0000000000..ff8f4076b1 --- /dev/null +++ b/lib/runtime_tools/examples/messages.systemtap @@ -0,0 +1,87 @@ +/* + * %CopyrightBegin% + * + * Copyright Scott Lystig Fritchie and Andreas Schultz, 2011. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ +/* + * Note: This file assumes that you're using the non-SMP-enabled Erlang + * virtual machine, "beam". The SMP-enabled VM is called "beam.smp". + * Note that other variations of the virtual machine also have + * different names, e.g. the debug build of the SMP-enabled VM + * is "beam.debug.smp". + * + * To use a different virtual machine, replace each instance of + * "beam" with "beam.smp" or the VM name appropriate to your + * environment. + */ + +probe begin +{ + printf("\n"); + printf("NOTE: message-queue message size 4294967295 means an external\n"); + printf(" message that the code isn't smart enough to determine\n"); + printf(" the actual size.\n"); + printf("\n"); +} + +probe process("beam").mark("message-send") +{ + if ($arg4 == 0 && $arg5 == 0 && $arg6 == 0) { + printf("send: %s -> %s: %d words\n", + user_string($arg1), user_string($arg2), $arg3); + } else { + printf("send: %s label %d token {%d,%d} -> %s: %d words\n", + user_string($arg1), + $arg4, $arg5, $arg6, + user_string($arg2), $arg3); + } +} + +probe process("beam").mark("message-send-remote") +{ + if ($arg5 == 0 && $arg6 == 0 && $arg7 == 0) { + printf("send : %s -> %s %s: %d words\n", + user_string($arg1), user_string($arg2), user_string($arg3), $arg4); + } else { + printf("send : %s label %d token {%d,%d} -> %s %s: %d words\n", + user_string($arg1), + $arg5, $arg6, $arg7, + user_string($arg2), user_string($arg3), $arg4); + } +} + +probe process("beam").mark("message-queued") +{ + if ($arg4 == 0 && $arg5 == 0 && $arg6 == 0) { + printf("queued: %s: %d words, queue len %d\n", user_string($arg1), $arg2, $arg3); + } else { + printf("queued: %s label %d token {%d,%d}: %d words, queue len %d\n", + user_string($arg1), $arg4, $arg5, $arg6, + $arg2, $arg3); + } +} + +probe process("beam").mark("message-receive") +{ + if ($arg4 == 0 && $arg5 == 0 && $arg6 == 0) { + printf("receive: %s: %d words, queue len %d\n", + user_string($arg1), $arg2, $arg3); + } else { + printf("receive: %s label %d token {%d,%d}: %d words, queue len %d\n", + user_string($arg1), $arg4, $arg5, $arg6, + $arg2, $arg3); + } +} diff --git a/lib/runtime_tools/examples/port1.d b/lib/runtime_tools/examples/port1.d new file mode 100644 index 0000000000..204abbd3b8 --- /dev/null +++ b/lib/runtime_tools/examples/port1.d @@ -0,0 +1,142 @@ +/* example usage: dtrace -q -s /path/to/port1.d */ +/* + * %CopyrightBegin% + * + * Copyright Scott Lystig Fritchie 2011. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +BEGIN +{ + driver_map["tcp_inet", 1] = "OPEN"; + driver_map["tcp_inet", 2] = "CLOSE"; + driver_map["tcp_inet", 3] = "CONNECT"; + driver_map["tcp_inet", 4] = "PEER"; + driver_map["tcp_inet", 5] = "NAME"; + driver_map["tcp_inet", 6] = "BIND"; + driver_map["tcp_inet", 7] = "SETOPTS"; + driver_map["tcp_inet", 8] = "GETOPTS"; + driver_map["tcp_inet", 11] = "GETSTAT"; + driver_map["tcp_inet", 12] = "GETHOSTNAME"; + driver_map["tcp_inet", 13] = "FDOPEN"; + driver_map["tcp_inet", 14] = "GETFD"; + driver_map["tcp_inet", 15] = "GETTYPE"; + driver_map["tcp_inet", 16] = "GETSTATUS"; + driver_map["tcp_inet", 17] = "GETSERVBYNAME"; + driver_map["tcp_inet", 18] = "GETSERVBYPORT"; + driver_map["tcp_inet", 19] = "SETNAME"; + driver_map["tcp_inet", 20] = "SETPEER"; + driver_map["tcp_inet", 21] = "GETIFLIST"; + driver_map["tcp_inet", 22] = "IFGET"; + driver_map["tcp_inet", 23] = "IFSET"; + driver_map["tcp_inet", 24] = "SUBSCRIBE"; + driver_map["tcp_inet", 25] = "GETIFADDRS"; + driver_map["tcp_inet", 40] = "ACCEPT"; + driver_map["tcp_inet", 41] = "LISTEN"; + driver_map["tcp_inet", 42] = "RECV"; + driver_map["tcp_inet", 43] = "UNRECV"; + driver_map["tcp_inet", 44] = "SHUTDOWN"; + driver_map["tcp_inet", 60] = "RECV"; + driver_map["tcp_inet", 61] = "LISTEN"; + driver_map["tcp_inet", 62] = "BINDX"; + /* No looping constructs, so repeat for udp_inet */ + driver_map["udp_inet", 1] = "OPEN"; + driver_map["udp_inet", 2] = "CLOSE"; + driver_map["udp_inet", 3] = "CONNECT"; + driver_map["udp_inet", 4] = "PEER"; + driver_map["udp_inet", 5] = "NAME"; + driver_map["udp_inet", 6] = "BIND"; + driver_map["udp_inet", 7] = "SETOPTS"; + driver_map["udp_inet", 8] = "GETOPTS"; + driver_map["udp_inet", 11] = "GETSTAT"; + driver_map["udp_inet", 12] = "GETHOSTNAME"; + driver_map["udp_inet", 13] = "FDOPEN"; + driver_map["udp_inet", 14] = "GETFD"; + driver_map["udp_inet", 15] = "GETTYPE"; + driver_map["udp_inet", 16] = "GETSTATUS"; + driver_map["udp_inet", 17] = "GETSERVBYNAME"; + driver_map["udp_inet", 18] = "GETSERVBYPORT"; + driver_map["udp_inet", 19] = "SETNAME"; + driver_map["udp_inet", 20] = "SETPEER"; + driver_map["udp_inet", 21] = "GETIFLIST"; + driver_map["udp_inet", 22] = "IFGET"; + driver_map["udp_inet", 23] = "IFSET"; + driver_map["udp_inet", 24] = "SUBSCRIBE"; + driver_map["udp_inet", 25] = "GETIFADDRS"; + driver_map["udp_inet", 40] = "ACCEPT"; + driver_map["udp_inet", 41] = "LISTEN"; + driver_map["udp_inet", 42] = "RECV"; + driver_map["udp_inet", 43] = "UNRECV"; + driver_map["udp_inet", 44] = "SHUTDOWN"; + driver_map["udp_inet", 60] = "RECV"; + driver_map["udp_inet", 61] = "LISTEN"; + driver_map["udp_inet", 62] = "BINDX"; +} + +erlang*:::port-open +{ + printf("port open pid %s port name %s port %s\n", + copyinstr(arg0), copyinstr(arg1), copyinstr(arg2)); +} + +erlang*:::port-command +{ + printf("port command pid %s port %s port name %s command type %s\n", + copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), copyinstr(arg3)); +} + +erlang*:::port-control +{ + /* http://dtrace.org/blogs/brendan/2011/11/25/dtrace-variable-types/ */ + this->cmd = driver_map[copyinstr(arg2), arg3]; + this->cmd_str = (this->cmd == 0) ? "unknown" : this->cmd; + printf("port control pid %s port %s port name %s command %d %s\n", + copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), arg3, + this->cmd_str); +} + +/* port-exit is fired as a result of port_close() or exit signal */ + +erlang*:::port-exit +{ + printf("port exit pid %s port %s port name %s reason %s\n", + copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), copyinstr(arg3)); +} + +erlang*:::port-connect +{ + printf("port connect pid %s port %s port name %s new pid %s\n", + copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), copyinstr(arg3)); +} + +erlang*:::port-busy +{ + printf("port busy %s\n", copyinstr(arg0)); +} + +erlang*:::port-not_busy +{ + printf("port not busy %s\n", copyinstr(arg0)); +} + +erlang*:::aio_pool-add +{ + printf("async I/O pool add thread %d queue len %d\n", arg0, arg1); +} + +erlang*:::aio_pool-get +{ + printf("async I/O pool get thread %d queue len %d\n", arg0, arg1); +} diff --git a/lib/runtime_tools/examples/port1.systemtap b/lib/runtime_tools/examples/port1.systemtap new file mode 100644 index 0000000000..a63d9b670c --- /dev/null +++ b/lib/runtime_tools/examples/port1.systemtap @@ -0,0 +1,152 @@ +/* + * %CopyrightBegin% + * + * Copyright Scott Lystig Fritchie and Andreas Schultz, 2011. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ +/* + * Note: This file assumes that you're using the non-SMP-enabled Erlang + * virtual machine, "beam". The SMP-enabled VM is called "beam.smp". + * Note that other variations of the virtual machine also have + * different names, e.g. the debug build of the SMP-enabled VM + * is "beam.debug.smp". + * + * To use a different virtual machine, replace each instance of + * "beam" with "beam.smp" or the VM name appropriate to your + * environment. + */ + +probe begin +{ + driver_map["tcp_inet", 1] = "OPEN"; + driver_map["tcp_inet", 2] = "CLOSE"; + driver_map["tcp_inet", 3] = "CONNECT"; + driver_map["tcp_inet", 4] = "PEER"; + driver_map["tcp_inet", 5] = "NAME"; + driver_map["tcp_inet", 6] = "BIND"; + driver_map["tcp_inet", 7] = "SETOPTS"; + driver_map["tcp_inet", 8] = "GETOPTS"; + driver_map["tcp_inet", 11] = "GETSTAT"; + driver_map["tcp_inet", 12] = "GETHOSTNAME"; + driver_map["tcp_inet", 13] = "FDOPEN"; + driver_map["tcp_inet", 14] = "GETFD"; + driver_map["tcp_inet", 15] = "GETTYPE"; + driver_map["tcp_inet", 16] = "GETSTATUS"; + driver_map["tcp_inet", 17] = "GETSERVBYNAME"; + driver_map["tcp_inet", 18] = "GETSERVBYPORT"; + driver_map["tcp_inet", 19] = "SETNAME"; + driver_map["tcp_inet", 20] = "SETPEER"; + driver_map["tcp_inet", 21] = "GETIFLIST"; + driver_map["tcp_inet", 22] = "IFGET"; + driver_map["tcp_inet", 23] = "IFSET"; + driver_map["tcp_inet", 24] = "SUBSCRIBE"; + driver_map["tcp_inet", 25] = "GETIFADDRS"; + driver_map["tcp_inet", 40] = "ACCEPT"; + driver_map["tcp_inet", 41] = "LISTEN"; + driver_map["tcp_inet", 42] = "RECV"; + driver_map["tcp_inet", 43] = "UNRECV"; + driver_map["tcp_inet", 44] = "SHUTDOWN"; + driver_map["tcp_inet", 60] = "RECV"; + driver_map["tcp_inet", 61] = "LISTEN"; + driver_map["tcp_inet", 62] = "BINDX"; + /* No looping constructs, so repeat for udp_inet */ + driver_map["udp_inet", 1] = "OPEN"; + driver_map["udp_inet", 2] = "CLOSE"; + driver_map["udp_inet", 3] = "CONNECT"; + driver_map["udp_inet", 4] = "PEER"; + driver_map["udp_inet", 5] = "NAME"; + driver_map["udp_inet", 6] = "BIND"; + driver_map["udp_inet", 7] = "SETOPTS"; + driver_map["udp_inet", 8] = "GETOPTS"; + driver_map["udp_inet", 11] = "GETSTAT"; + driver_map["udp_inet", 12] = "GETHOSTNAME"; + driver_map["udp_inet", 13] = "FDOPEN"; + driver_map["udp_inet", 14] = "GETFD"; + driver_map["udp_inet", 15] = "GETTYPE"; + driver_map["udp_inet", 16] = "GETSTATUS"; + driver_map["udp_inet", 17] = "GETSERVBYNAME"; + driver_map["udp_inet", 18] = "GETSERVBYPORT"; + driver_map["udp_inet", 19] = "SETNAME"; + driver_map["udp_inet", 20] = "SETPEER"; + driver_map["udp_inet", 21] = "GETIFLIST"; + driver_map["udp_inet", 22] = "IFGET"; + driver_map["udp_inet", 23] = "IFSET"; + driver_map["udp_inet", 24] = "SUBSCRIBE"; + driver_map["udp_inet", 25] = "GETIFADDRS"; + driver_map["udp_inet", 40] = "ACCEPT"; + driver_map["udp_inet", 41] = "LISTEN"; + driver_map["udp_inet", 42] = "RECV"; + driver_map["udp_inet", 43] = "UNRECV"; + driver_map["udp_inet", 44] = "SHUTDOWN"; + driver_map["udp_inet", 60] = "RECV"; + driver_map["udp_inet", 61] = "LISTEN"; + driver_map["udp_inet", 62] = "BINDX"; +} + +probe process("beam").mark("port-open") +{ + printf("port open pid %s port name %s port %s\n", + user_string($arg1), user_string($arg2), user_string($arg3)); +} + +probe process("beam").mark("port-command") +{ + printf("port command pid %s port %s port name %s command type %s\n", + user_string($arg1), user_string($arg2), user_string($arg3), user_string($arg4)); +} + +probe process("beam").mark("port-control") +{ + cmd = driver_map[user_string($arg3), $arg4]; + cmd_str = (cmd == "") ? "unknown" : cmd; + printf("port control pid %s port %s port name %s command %d %s\n", + user_string($arg1), user_string($arg2), user_string($arg3), $arg4, cmd_str); +} + +/* port-exit is fired as a result of port_close() or exit signal */ + +probe process("beam").mark("port-exit") +{ + printf("port exit pid %s port %s port name %s reason %s\n", + user_string($arg1), user_string($arg2), user_string($arg3), user_string($arg4)); +} + +probe process("beam").mark("port-connect") +{ + printf("port connect pid %s port %s port name %s new pid %s\n", + user_string($arg1), user_string($arg2), user_string($arg3), user_string($arg4)); +} + +probe process("beam").mark("port-busy") +{ + printf("port busy %s\n", user_string($arg1)); +} + +probe process("beam").mark("port-not_busy") +{ + printf("port not busy %s\n", user_string($arg1)); +} + +probe process("beam").mark("aio_pool-add") +{ + printf("async I/O pool add thread %d queue len %d\n", $arg1, $arg2); +} + +probe process("beam").mark("aio_pool-get") +{ + printf("async I/O pool get thread %d queue len %d\n", $arg1, $arg2); +} + +global driver_map; \ No newline at end of file diff --git a/lib/runtime_tools/examples/process-scheduling.d b/lib/runtime_tools/examples/process-scheduling.d new file mode 100644 index 0000000000..79e9cc598c --- /dev/null +++ b/lib/runtime_tools/examples/process-scheduling.d @@ -0,0 +1,35 @@ +/* example usage: dtrace -q -s /path/to/process-scheduling.d */ +/* + * %CopyrightBegin% + * + * Copyright Scott Lystig Fritchie 2011. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +erlang*:::process-scheduled +{ + printf(" Schedule pid %s mfa %s\n", copyinstr(arg0), copyinstr(arg1)); +} + +erlang*:::process-unscheduled +{ + printf("Unschedule pid %s\n", copyinstr(arg0)); +} + +erlang*:::process-hibernate +{ + printf(" Hibernate pid %s resume mfa %s\n", + copyinstr(arg0), copyinstr(arg1)); +} diff --git a/lib/runtime_tools/examples/process-scheduling.systemtap b/lib/runtime_tools/examples/process-scheduling.systemtap new file mode 100644 index 0000000000..c8cee60a07 --- /dev/null +++ b/lib/runtime_tools/examples/process-scheduling.systemtap @@ -0,0 +1,45 @@ +/* + * %CopyrightBegin% + * + * Copyright Scott Lystig Fritchie and Andreas Schultz, 2011. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ +/* + * Note: This file assumes that you're using the non-SMP-enabled Erlang + * virtual machine, "beam". The SMP-enabled VM is called "beam.smp". + * Note that other variations of the virtual machine also have + * different names, e.g. the debug build of the SMP-enabled VM + * is "beam.debug.smp". + * + * To use a different virtual machine, replace each instance of + * "beam" with "beam.smp" or the VM name appropriate to your + * environment. + */ + +probe process("beam").mark("process-scheduled") +{ + printf(" Schedule pid %s mfa %s\n", user_string($arg1), user_string($arg2)); +} + +probe process("beam").mark("process-unscheduled") +{ + printf("Unschedule pid %s\n", user_string($arg1)); +} + +probe process("beam").mark("process-hibernate") +{ + printf(" Hibernate pid %s resume mfa %s\n", + user_string($arg1), user_string($arg2)); +} diff --git a/lib/runtime_tools/examples/spawn-exit.d b/lib/runtime_tools/examples/spawn-exit.d new file mode 100644 index 0000000000..7310f3343d --- /dev/null +++ b/lib/runtime_tools/examples/spawn-exit.d @@ -0,0 +1,41 @@ +/* example usage: dtrace -q -s /path/to/spawn-exit.d */ +/* + * %CopyrightBegin% + * + * Copyright Scott Lystig Fritchie 2011. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +erlang*:::process-spawn +{ + printf("pid %s mfa %s\n", copyinstr(arg0), copyinstr(arg1)); +} + +erlang*:::process-exit +{ + printf("pid %s reason %s\n", copyinstr(arg0), copyinstr(arg1)); +} + +erlang*:::process-exit_signal +{ + printf("sender %s -> pid %s reason %s\n", + copyinstr(arg0), copyinstr(arg1), copyinstr(arg2)); +} + +erlang*:::process-exit_signal-remote +{ + printf("sender %s -> node %s pid %s reason %s\n", + copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), copyinstr(arg3)); +} diff --git a/lib/runtime_tools/examples/spawn-exit.systemtap b/lib/runtime_tools/examples/spawn-exit.systemtap new file mode 100644 index 0000000000..5e3be9fc1b --- /dev/null +++ b/lib/runtime_tools/examples/spawn-exit.systemtap @@ -0,0 +1,51 @@ +/* + * %CopyrightBegin% + * + * Copyright Scott Lystig Fritchie and Andreas Schultz, 2011. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ +/* + * Note: This file assumes that you're using the non-SMP-enabled Erlang + * virtual machine, "beam". The SMP-enabled VM is called "beam.smp". + * Note that other variations of the virtual machine also have + * different names, e.g. the debug build of the SMP-enabled VM + * is "beam.debug.smp". + * + * To use a different virtual machine, replace each instance of + * "beam" with "beam.smp" or the VM name appropriate to your + * environment. + */ + +probe process("beam").mark("process-spawn") +{ + printf("pid %s mfa %s\n", user_string($arg1), user_string($arg2)); +} + +probe process("beam").mark("process-exit") +{ + printf("pid %s reason %s\n", user_string($arg1), user_string($arg2)); +} + +probe process("beam").mark("process-exit_signal") +{ + printf("sender %s -> pid %s reason %s\n", + user_string($arg1), user_string($arg2), user_string($arg3)); +} + +probe process("beam").mark("process-exit_signal-remote") +{ + printf("sender %s -> node %s pid %s reason %s\n", + user_string($arg1), user_string($arg2), user_string($arg3), user_string($arg4)); +} diff --git a/lib/runtime_tools/examples/user-probe.d b/lib/runtime_tools/examples/user-probe.d new file mode 100644 index 0000000000..13baff6a32 --- /dev/null +++ b/lib/runtime_tools/examples/user-probe.d @@ -0,0 +1,36 @@ +/* example usage: dtrace -q -s /path/to/user-probe.d */ +/* + * %CopyrightBegin% + * + * Copyright Scott Lystig Fritchie 2011. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ + +erlang*:::user_trace-s1 +{ + printf("%s\n", copyinstr(arg0)); +} + +erlang*:::user_trace-i4s4 +{ + printf("%s %s %d %d %d %d '%s' '%s' '%s' '%s'\n", + copyinstr(arg0), + arg1 == NULL ? "" : copyinstr(arg1), + arg2, arg3, arg4, arg5, + arg6 == NULL ? "" : copyinstr(arg6), + arg7 == NULL ? "" : copyinstr(arg7), + arg8 == NULL ? "" : copyinstr(arg8), + arg9 == NULL ? "" : copyinstr(arg9)); +} diff --git a/lib/runtime_tools/examples/user-probe.systemtap b/lib/runtime_tools/examples/user-probe.systemtap new file mode 100644 index 0000000000..84a45709e8 --- /dev/null +++ b/lib/runtime_tools/examples/user-probe.systemtap @@ -0,0 +1,46 @@ +/* + * %CopyrightBegin% + * + * Copyright Scott Lystig Fritchie and Andreas Schultz, 2011. All Rights Reserved. + * + * The contents of this file are subject to the Erlang Public License, + * Version 1.1, (the "License"); you may not use this file except in + * compliance with the License. You should have received a copy of the + * Erlang Public License along with this software. If not, it can be + * retrieved online at http://www.erlang.org/. + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * %CopyrightEnd% + */ +/* + * Note: This file assumes that you're using the non-SMP-enabled Erlang + * virtual machine, "beam". The SMP-enabled VM is called "beam.smp". + * Note that other variations of the virtual machine also have + * different names, e.g. the debug build of the SMP-enabled VM + * is "beam.debug.smp". + * + * To use a different virtual machine, replace each instance of + * "beam" with "beam.smp" or the VM name appropriate to your + * environment. + */ + +probe process("dyntrace.so").mark("user_trace-s1") +{ + printf("%s\n", user_string($arg1)); +} + +probe process("dyntrace.so").mark("user_trace-i4s4") +{ + printf("%s %s %d %d %d %d '%s' '%s' '%s' '%s'\n", + user_string($arg1), + $arg2 == NULL ? "" : user_string($arg2), + $arg3, $arg4, $arg5, $arg6, + $arg7 == NULL ? "" : user_string($arg7), + $arg8 == NULL ? "" : user_string($arg8), + $arg9 == NULL ? "" : user_string($arg9), + $arg9 == NULL ? "" : user_string($arg9)); +} diff --git a/lib/runtime_tools/src/Makefile b/lib/runtime_tools/src/Makefile index 946409b262..6dc89bea32 100644 --- a/lib/runtime_tools/src/Makefile +++ b/lib/runtime_tools/src/Makefile @@ -45,6 +45,7 @@ MODULES= \ runtime_tools \ runtime_tools_sup \ dbg \ + dyntrace \ percept_profile \ observer_backend \ ttb_autostart @@ -64,10 +65,15 @@ APPUP_FILE= runtime_tools.appup APPUP_SRC= $(APPUP_FILE).src APPUP_TARGET= $(EBIN)/$(APPUP_FILE) +EXAMPLE_FILES= \ + ../examples/* # ---------------------------------------------------- # FLAGS # ---------------------------------------------------- -ERL_COMPILE_FLAGS += -I../include +ERL_COMPILE_FLAGS += \ + -I../include \ + -I ../../et/include \ + -I ../../../libraries/et/include # ---------------------------------------------------- # Targets @@ -97,6 +103,8 @@ release_spec: opt $(INSTALL_DATA) $(ERL_FILES) $(RELSYSDIR)/src $(INSTALL_DIR) $(RELSYSDIR)/include $(INSTALL_DATA) $(HRL_FILES) $(RELSYSDIR)/include + $(INSTALL_DIR) $(RELSYSDIR)/examples + $(INSTALL_DATA) $(EXAMPLE_FILES) $(RELSYSDIR)/examples $(INSTALL_DIR) $(RELSYSDIR)/ebin $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin diff --git a/lib/runtime_tools/src/dyntrace.erl b/lib/runtime_tools/src/dyntrace.erl new file mode 100644 index 0000000000..20472a2be6 --- /dev/null +++ b/lib/runtime_tools/src/dyntrace.erl @@ -0,0 +1,279 @@ +-module(dyntrace). + +%%% @doc The Dynamic tracing interface module +%%% +%%% This Dynamic tracing interface module, with the corresponding NIFs, should +%%% work on any operating system platform where user-space DTrace/Systemtap +%%% (and in the future LttNG UST) probes are supported. +%%% +%%% Use the `dyntrace:init()' function to load the NIF shared library and +%%% to initialize library's private state. +%%% +%%% It is recommended that you use the `dyntrace:p()' function to add +%%% Dynamic trace probes to your Erlang code. This function can accept up to +%%% four integer arguments and four string arguments; the integer +%%% argument(s) must come before any string argument. For example: +%%% ``` +%%% 1> dyntrace:put_utag("GGOOOAAALL!!!!!"). +%%% true +%%% 2> dyntrace:init(). +%%% ok +%%% +%%% % % % If using dtrace, enable the Dynamic trace probe using the 'dtrace' +%%% % % % command. +%%% +%%% 3> dyntrace:p(7, 8, 9, "one", "four"). +%%% true +%%% ''' +%%% +%%% Output from the example D script `user-probe.d' looks like: +%%% ``` +%%% <0.34.0> GGOOOAAALL!!!!! 7 8 9 0 'one' 'four' '' '' +%%% ''' +%%% +%%% If the expected type of variable is not present, e.g. integer when +%%% integer() is expected, or an I/O list when iolist() is expected, +%%% then the driver will ignore the user's input and use a default +%%% value of 0 or NULL, respectively. + +-export([available/0, + user_trace_s1/1, % TODO: unify with pid & tag args like user_trace_i4s4 + p/0, p/1, p/2, p/3, p/4, p/5, p/6, p/7, p/8]). +-export([put_utag/1, get_utag/0, get_utag_data/0, spread_utag/1, restore_utag/1]). + +-export([scaff/0]). % Development only +-export([user_trace_i4s4/9]). % Know what you're doing! +-on_load(on_load/0). + +-type probe_arg() :: integer() | iolist(). +-type int_p_arg() :: integer() | iolist() | undef. + +%% The *_maybe() types use atom() instead of a stricter 'undef' +%% because user_trace_i4s4/9 is exposed to the outside world, and +%% because the driver will allow any atom to be used as a "not +%% present" indication, we'll allow any atom in the types. + +-type integer_maybe() :: integer() | atom(). +-type iolist_maybe() :: iolist() | atom(). + +on_load() -> + PrivDir = code:priv_dir(runtime_tools), + LibName = "dyntrace", + Lib = filename:join([PrivDir, "lib", LibName]), + Status = case erlang:load_nif(Lib, 0) of + ok -> ok; + {error, {load_failed, _}}=Error1 -> + ArchLibDir = + filename:join([PrivDir, "lib", + erlang:system_info(system_architecture)]), + Candidate = + filelib:wildcard(filename:join([ArchLibDir,LibName ++ "*" ])), + case Candidate of + [] -> Error1; + _ -> + ArchLib = filename:join([ArchLibDir, LibName]), + erlang:load_nif(ArchLib, 0) + end; + Error1 -> Error1 + end, + case Status of + ok -> ok; + {error, {E, Str}} -> + case erlang:system_info(dynamic_trace) of + none -> + ok; + _ -> + error_logger:error_msg("Unable to load dyntrace library. Failed with error:~n +\"~p, ~s\"~n" + "Dynamic tracing is enabled but the driver is not built correctly~n",[ + E,Str]), + Status + end + end. + +%%% +%%% NIF placeholders +%%% + +-spec available() -> true | false. + +available() -> + erlang:nif_error(nif_not_loaded). + +-spec user_trace_s1(iolist()) -> true | false | error | badarg. + +user_trace_s1(_Message) -> + erlang:nif_error(nif_not_loaded). + +-spec user_trace_i4s4(iolist(), + integer_maybe(), integer_maybe(), + integer_maybe(), integer_maybe(), + iolist_maybe(), iolist_maybe(), + iolist_maybe(), iolist_maybe()) -> + true | false | error | badarg. + +user_trace_i4s4(_, _, _, _, _, _, _, _, _) -> + erlang:nif_error(nif_not_loaded). + +%%% +%%% Erlang support functions +%%% + +-spec p() -> true | false | error | badarg. + +p() -> + user_trace_int(undef, undef, undef, undef, undef, undef, undef, undef). + +-spec p(probe_arg()) -> true | false | error | badarg. + +p(I1) when is_integer(I1) -> + user_trace_int(I1, undef, undef, undef, undef, undef, undef, undef); +p(S1) -> + user_trace_int(undef, undef, undef, undef, S1, undef, undef, undef). + +-spec p(probe_arg(), probe_arg()) -> true | false | error | badarg. + +p(I1, I2) when is_integer(I1), is_integer(I2) -> + user_trace_int(I1, I2, undef, undef, undef, undef, undef, undef); +p(I1, S1) when is_integer(I1) -> + user_trace_int(I1, undef, undef, undef, S1, undef, undef, undef); +p(S1, S2) -> + user_trace_int(undef, undef, undef, undef, S1, S2, undef, undef). + +-spec p(probe_arg(), probe_arg(), probe_arg()) -> true | false | error | badarg. + +p(I1, I2, I3) when is_integer(I1), is_integer(I2), is_integer(I3) -> + user_trace_int(I1, I2, I3, undef, undef, undef, undef, undef); +p(I1, I2, S1) when is_integer(I1), is_integer(I2) -> + user_trace_int(I1, I2, undef, undef, S1, undef, undef, undef); +p(I1, S1, S2) when is_integer(I1) -> + user_trace_int(I1, undef, undef, undef, S1, S2, undef, undef); +p(S1, S2, S3) -> + user_trace_int(undef, undef, undef, undef, S1, S2, S3, undef). + +-spec p(probe_arg(), probe_arg(), probe_arg(), probe_arg()) -> + true | false | error | badarg. + +p(I1, I2, I3, I4) when is_integer(I1), is_integer(I2), is_integer(I3), is_integer(I4) -> + user_trace_int(I1, I2, I3, I4, undef, undef, undef, undef); +p(I1, I2, I3, S1) when is_integer(I1), is_integer(I2), is_integer(I3) -> + user_trace_int(I1, I2, I3, undef, S1, undef, undef, undef); +p(I1, I2, S1, S2) when is_integer(I1), is_integer(I2) -> + user_trace_int(I1, I2, undef, undef, S1, S2, undef, undef); +p(I1, S1, S2, S3) when is_integer(I1) -> + user_trace_int(I1, undef, undef, undef, S1, S2, S3, undef); +p(S1, S2, S3, S4) -> + user_trace_int(undef, undef, undef, undef, S1, S2, S3, S4). + +-spec p(probe_arg(), probe_arg(), probe_arg(), probe_arg(), + probe_arg()) -> + true | false | error | badarg. + +p(I1, I2, I3, I4, S1) when is_integer(I1), is_integer(I2), is_integer(I3), is_integer(I4) -> + user_trace_int(I1, I2, I3, I4, S1, undef, undef, undef); +p(I1, I2, I3, S1, S2) when is_integer(I1), is_integer(I2), is_integer(I3) -> + user_trace_int(I1, I2, I3, undef, S1, S2, undef, undef); +p(I1, I2, S1, S2, S3) when is_integer(I1), is_integer(I2) -> + user_trace_int(I1, I2, undef, undef, S1, S2, S3, undef); +p(I1, S1, S2, S3, S4) when is_integer(I1) -> + user_trace_int(I1, undef, undef, undef, S1, S2, S3, S4). + +-spec p(probe_arg(), probe_arg(), probe_arg(), probe_arg(), + probe_arg(), probe_arg()) -> + true | false | error | badarg. + +p(I1, I2, I3, I4, S1, S2) when is_integer(I1), is_integer(I2), is_integer(I3), is_integer(I4) -> + user_trace_int(I1, I2, I3, I4, S1, S2, undef, undef); +p(I1, I2, I3, S1, S2, S3) when is_integer(I1), is_integer(I2), is_integer(I3) -> + user_trace_int(I1, I2, I3, undef, S1, S2, S3, undef); +p(I1, I2, S1, S2, S3, S4) when is_integer(I1), is_integer(I2) -> + user_trace_int(I1, I2, undef, undef, S1, S2, S3, S4). + +-spec p(probe_arg(), probe_arg(), probe_arg(), probe_arg(), + probe_arg(), probe_arg(), probe_arg()) -> + true | false | error | badarg. + +p(I1, I2, I3, I4, S1, S2, S3) when is_integer(I1), is_integer(I2), is_integer(I3), is_integer(I4) -> + user_trace_int(I1, I2, I3, I4, S1, S2, S3, undef); +p(I1, I2, I3, S1, S2, S3, S4) when is_integer(I1), is_integer(I2), is_integer(I3) -> + user_trace_int(I1, I2, I3, undef, S1, S2, S3, S4). + +-spec p(probe_arg(), probe_arg(), probe_arg(), probe_arg(), + probe_arg(), probe_arg(), probe_arg(), probe_arg()) -> + true | false | error | badarg. + +p(I1, I2, I3, I4, S1, S2, S3, S4) when is_integer(I1), is_integer(I2), is_integer(I3), is_integer(I4) -> + user_trace_int(I1, I2, I3, I4, S1, S2, S3, S4). + +-spec user_trace_int(int_p_arg(), int_p_arg(), int_p_arg(), int_p_arg(), + int_p_arg(), int_p_arg(), int_p_arg(), int_p_arg()) -> + true | false | error | badarg. + +user_trace_int(I1, I2, I3, I4, S1, S2, S3, S4) -> + UTag = get_utag(), + try + user_trace_i4s4(UTag, I1, I2, I3, I4, S1, S2, S3, S4) + catch + error:nif_not_loaded -> + false + end. + +-spec put_utag(undefined | iodata()) -> binary() | undefined. +put_utag(Data) -> + erlang:put_utag(unicode:characters_to_binary(Data)). + +-spec get_utag() -> binary() | undefined. +get_utag() -> + erlang:get_utag(). + +-spec get_utag_data() -> binary() | undefined. +%% Gets utag if set, otherwise the spread utag data from last incoming message +get_utag_data() -> + erlang:get_utag_data(). + +-spec spread_utag(boolean()) -> true | {non_neg_integer(), binary() | []}. +%% Makes the utag behave as a sequential trace token, will spread with messages to be picked up by someone using +%% get_utag_data or get_drv_utag_data. +spread_utag(B) -> + erlang:spread_utag(B). + +-spec restore_utag(true | {non_neg_integer(), binary() | []}) -> true. +restore_utag(T) -> + erlang:restore_utag(T). + + +%% Scaffolding to write tedious code: quick brute force and not 100% correct. + +scaff_int_args(N) -> + L = lists:sublist(["I1", "I2", "I3", "I4"], N), + [string:join(L, ", ")]. + +scaff_int_guards(N) -> + L = lists:sublist(["is_integer(I1)", "is_integer(I2)", "is_integer(I3)", + "is_integer(I4)"], N), + lists:flatten(string:join(L, ", ")). + +scaff_char_args(N) -> + L = lists:sublist(["S1", "S2", "S3", "S4"], N), + [string:join(L, ", ")]. + +scaff_fill(N) -> + [string:join(lists:duplicate(N, "undef"), ", ")]. + +scaff() -> + L = [begin + IntArgs = scaff_int_args(N_int), + IntGuards = scaff_int_guards(N_int), + IntFill = scaff_fill(4 - N_int), + CharArgs = scaff_char_args(N_char), + CharFill = scaff_fill(4 - N_char), + InArgs = string:join(IntArgs ++ CharArgs, ", "), + OutArgs = string:join(IntArgs ++ IntFill ++ CharArgs ++ CharFill, + ", "), + {N_int + N_char, + lists:flatten([io_lib:format("p(~s) when ~s ->\n", + [InArgs, IntGuards]), + io_lib:format(" user_trace_int(~s);\n", [OutArgs]) + ])} + end || N_int <- [0,1,2,3,4], N_char <- [0,1,2,3,4]], + [io:format("%%~p\n~s", [N, Str]) || {N, Str} <- lists:sort(L)]. diff --git a/lib/runtime_tools/src/runtime_tools.app.src b/lib/runtime_tools/src/runtime_tools.app.src index 76fd998530..a9d2d68857 100644 --- a/lib/runtime_tools/src/runtime_tools.app.src +++ b/lib/runtime_tools/src/runtime_tools.app.src @@ -23,7 +23,7 @@ inviso_rt,inviso_rt_lib,inviso_rt_meta, inviso_as_lib,inviso_autostart,inviso_autostart_server, runtime_tools,runtime_tools_sup,erts_alloc_config, - ttb_autostart]}, + ttb_autostart,dyntrace]}, {registered, [runtime_tools_sup,inviso_rt,inviso_rt_meta]}, {applications, [kernel, stdlib]}, % {env, [{inviso_autostart_mod,your_own_autostart_module}]}, -- cgit v1.2.3