aboutsummaryrefslogtreecommitdiffstats
path: root/lib/dtrace/src/dtrace.erl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dtrace/src/dtrace.erl')
-rw-r--r--lib/dtrace/src/dtrace.erl247
1 files changed, 0 insertions, 247 deletions
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)].