aboutsummaryrefslogtreecommitdiffstats
path: root/lib/dtrace
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dtrace')
-rw-r--r--lib/dtrace/c_src/Makefile2
-rw-r--r--lib/dtrace/c_src/Makefile.in15
-rw-r--r--lib/dtrace/c_src/dtrace.c16
-rw-r--r--lib/dtrace/examples/dist.d14
-rw-r--r--lib/dtrace/examples/port1.d8
-rw-r--r--lib/dtrace/examples/process-scheduling.d2
-rw-r--r--lib/dtrace/src/dtrace.erl38
7 files changed, 59 insertions, 36 deletions
diff --git a/lib/dtrace/c_src/Makefile b/lib/dtrace/c_src/Makefile
index f3320bb766..a65491d45d 100644
--- a/lib/dtrace/c_src/Makefile
+++ b/lib/dtrace/c_src/Makefile
@@ -1,4 +1,4 @@
#
-# Invoke with GNU make or clearmake -C gnu.
+# 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
index ed13684a95..831ce5ce75 100644
--- a/lib/dtrace/c_src/Makefile.in
+++ b/lib/dtrace/c_src/Makefile.in
@@ -72,7 +72,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/dtrace-$(VSN)
# ----------------------------------------------------
# Misc Macros
# ----------------------------------------------------
-OBJS = $(OBJDIR)/dtrace$(TYPEMARKER).o
+before_DTrace_OBJS = $(OBJDIR)/dtrace$(TYPEMARKER).o
## NIF_MAKEFILE = $(PRIVDIR)/Makefile
# Higher-level makefiles says that we can only compile on UNIX flavors
@@ -100,18 +100,17 @@ else
DTRACE_USER_HEADER=
endif
+DTRACE_OBJS =
ifdef DTRACE_ENABLED_2STEP
-OBJS += $(OBJDIR)/dtrace_user.o
-$(OBJDIR)/dtrace_user.o: $(OBJS) $(OBJDIR)/dtrace_user.h
- touch $(OBJDIR)/erlang_dtrace.c
- $(CC) $(CFLAGS) -c -o $@ $(OBJDIR)/erlang_dtrace.c
- # The object file created above is immediately clobbered below.
- # But creating it above avoids chicken-and-egg problem with OBJS
+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 $@ $(OBJS)
+ -o $@ $(before_DTrace_OBJS)
endif
+OBJS = $(before_DTrace_OBJS) $(DTRACE_OBJS)
+
$(OBJDIR):
-@mkdir -p $(OBJDIR)
diff --git a/lib/dtrace/c_src/dtrace.c b/lib/dtrace/c_src/dtrace.c
index c9d25ece9c..90bb39a4b8 100644
--- a/lib/dtrace/c_src/dtrace.c
+++ b/lib/dtrace/c_src/dtrace.c
@@ -25,7 +25,6 @@
#include "erl_nif.h"
#include "config.h"
#include "sys.h"
-#define DTRACE_DRIVER_SKIP_FUNC_DECLARATIONS
#include "dtrace-wrapper.h"
#ifdef HAVE_DTRACE
#include "dtrace_user.h"
@@ -144,8 +143,7 @@ static ERL_NIF_TERM user_trace_i4s4(ErlNifEnv* env, int argc, const ERL_NIF_TERM
if (DTRACE_ENABLED(user_trace_i4s4)) {
dtrace_nifenv_str(env, procbuf);
- get_string_maybe(env, argv[0], &utbuf,
- user_tagbuf, sizeof(user_tagbuf)-1);
+ 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))
@@ -154,14 +152,10 @@ static ERL_NIF_TERM user_trace_i4s4(ErlNifEnv* env, int argc, const ERL_NIF_TERM
i3 = 0;
if (! enif_get_int64(env, argv[4], &i4))
i4 = 0;
- get_string_maybe(env, argv[5], &mbuf1,
- messagebuf1, sizeof(messagebuf1)-1);
- get_string_maybe(env, argv[6], &mbuf2,
- messagebuf2, sizeof(messagebuf2)-1);
- get_string_maybe(env, argv[7], &mbuf3,
- messagebuf3, sizeof(messagebuf3)-1);
- get_string_maybe(env, argv[8], &mbuf4,
- messagebuf4, sizeof(messagebuf4)-1);
+ 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;
diff --git a/lib/dtrace/examples/dist.d b/lib/dtrace/examples/dist.d
index f37c827f14..550e10d363 100644
--- a/lib/dtrace/examples/dist.d
+++ b/lib/dtrace/examples/dist.d
@@ -30,13 +30,13 @@ 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));
- blocked_procs[copyinstr(arg3)] = timestamp;
-}
-
-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;
}
diff --git a/lib/dtrace/examples/port1.d b/lib/dtrace/examples/port1.d
index b82e783a14..204abbd3b8 100644
--- a/lib/dtrace/examples/port1.d
+++ b/lib/dtrace/examples/port1.d
@@ -99,10 +99,12 @@ erlang*:::port-command
erlang*:::port-control
{
- cmd = driver_map[copyinstr(arg2), arg3];
- cmd_str = (cmd == 0) ? "unknown" : cmd;
+ /* 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, cmd_str);
+ copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), arg3,
+ this->cmd_str);
}
/* port-exit is fired as a result of port_close() or exit signal */
diff --git a/lib/dtrace/examples/process-scheduling.d b/lib/dtrace/examples/process-scheduling.d
index 9e31da2774..79e9cc598c 100644
--- a/lib/dtrace/examples/process-scheduling.d
+++ b/lib/dtrace/examples/process-scheduling.d
@@ -31,5 +31,5 @@ erlang*:::process-unscheduled
erlang*:::process-hibernate
{
printf(" Hibernate pid %s resume mfa %s\n",
- copyinstr(arg0), copyinstr(arg1));
+ copyinstr(arg0), copyinstr(arg1));
}
diff --git a/lib/dtrace/src/dtrace.erl b/lib/dtrace/src/dtrace.erl
index 45addafc53..6951c03215 100644
--- a/lib/dtrace/src/dtrace.erl
+++ b/lib/dtrace/src/dtrace.erl
@@ -14,8 +14,8 @@
%%% four integer arguments and four string arguments; the integer
%%% argument(s) must come before any string argument. For example:
%%% ```
-%%% 1> put(dtrace_utag, "GGOOOAAALL!!!!!").
-%%% undefined
+%%% 1> dtrace:put_tag("GGOOOAAALL!!!!!").
+%%% true
%%% 2> dtrace:init().
%%% ok
%%%
@@ -35,9 +35,13 @@
%%% then the driver will ignore the user's input and use a default
%%% value of 0 or NULL, respectively.
+-define(DTRACE_UT_KEY, '_dtrace_utag_@_@'). % Match prim_file:get_dtrace_utag()!
+
-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]).
+
-export([scaff/0]). % Development only
-export([user_trace_i4s4/9]). % Know what you're doing!
@@ -68,7 +72,7 @@ available() ->
-spec user_trace_s1(iolist()) -> true | false | error | badarg.
-user_trace_s1(Message) ->
+user_trace_s1(_Message) ->
erlang:nif_error(nif_not_loaded).
-spec user_trace_i4s4(iolist(),
@@ -176,8 +180,32 @@ p(I1, I2, I3, I4, S1, S2, S3, S4) when is_integer(I1), is_integer(I2), is_intege
true | false | error | badarg.
user_trace_int(I1, I2, I3, I4, S1, S2, S3, S4) ->
- UTag = prim_file:get_dtrace_utag(),
- user_trace_i4s4(UTag, 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 | iolist()) -> ok.
+
+put_utag(undefined) ->
+ put_utag(<<>>);
+put_utag(T) when is_binary(T) ->
+ put(?DTRACE_UT_KEY, T),
+ ok;
+put_utag(T) when is_list(T) ->
+ put(?DTRACE_UT_KEY, list_to_binary(T)),
+ ok.
+
+get_utag() ->
+ case get(?DTRACE_UT_KEY) of
+ undefined ->
+ <<>>;
+ X ->
+ X
+ end.
%% Scaffolding to write tedious code: quick brute force and not 100% correct.