aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/test/trace_nif_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/test/trace_nif_SUITE.erl')
-rw-r--r--erts/emulator/test/trace_nif_SUITE.erl292
1 files changed, 292 insertions, 0 deletions
diff --git a/erts/emulator/test/trace_nif_SUITE.erl b/erts/emulator/test/trace_nif_SUITE.erl
new file mode 100644
index 0000000000..587cc08979
--- /dev/null
+++ b/erts/emulator/test/trace_nif_SUITE.erl
@@ -0,0 +1,292 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 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%
+%%
+
+-module(trace_nif_SUITE).
+
+-include("test_server.hrl").
+
+-export([all/1]).
+-export([trace_nif/1,
+ trace_nif_timestamp/1,
+ trace_nif_local/1,
+ trace_nif_meta/1,
+ trace_nif_timestamp_local/1,
+ trace_nif_return/1,
+ not_run/1]).
+
+-export([nif_process/0, nif/0, nif/1]).
+
+all(suite) ->
+ case test_server:is_native(?MODULE) of
+ true -> [not_run];
+ false ->
+ [trace_nif,
+ trace_nif_timestamp,
+ trace_nif_local,
+ trace_nif_meta,
+ trace_nif_timestamp_local,
+ trace_nif_return
+ ]
+ end.
+
+not_run(Config) when is_list(Config) ->
+ {skipped,"Native code"}.
+
+trace_nif(doc) -> "Test tracing NIFs.";
+trace_nif(Config) when is_list(Config) ->
+ load_nif(Config),
+
+ do_trace_nif([]).
+
+trace_nif_local(doc) -> "Test tracing NIFs with local flag.";
+trace_nif_local(Config) when is_list(Config) ->
+ load_nif(Config),
+ do_trace_nif([local]).
+
+trace_nif_meta(doc) -> "Test tracing NIFs with meta flag.";
+trace_nif_meta(Config) when is_list(Config) ->
+ load_nif(Config),
+ ?line Pid=spawn_link(?MODULE, nif_process, []),
+ ?line erlang:trace_pattern({?MODULE,nif,'_'}, [], [meta]),
+
+ ?line Pid ! {apply_nif, nif, []},
+ ?line receive_trace_msg_ts({trace_ts,Pid,call,{?MODULE,nif,[]}}),
+
+ ?line Pid ! {apply_nif, nif, ["Arg1"]},
+ ?line receive_trace_msg_ts({trace_ts,Pid,call,
+ {?MODULE,nif, ["Arg1"]}}),
+
+ ?line Pid ! {call_nif, nif, []},
+ ?line receive_trace_msg_ts({trace_ts,Pid,call,
+ {?MODULE,nif, []}}),
+
+ ?line Pid ! {call_nif, nif, ["Arg1"]},
+ ?line receive_trace_msg_ts({trace_ts,Pid,call,
+ {?MODULE,nif, ["Arg1"]}}),
+ ok.
+do_trace_nif(Flags) ->
+ ?line Pid = spawn(?MODULE, nif_process, []),
+ ?line 1 = erlang:trace(Pid, true, [call]),
+ ?line erlang:trace_pattern({?MODULE,nif,'_'}, [], Flags),
+ ?line Pid ! {apply_nif, nif, []},
+ ?line receive_trace_msg({trace,Pid,call,{?MODULE,nif, []}}),
+ ?line Pid ! {apply_nif, nif, ["Arg1"]},
+ ?line receive_trace_msg({trace,Pid,call,{?MODULE,nif, ["Arg1"]}}),
+
+ ?line Pid ! {call_nif, nif, []},
+ ?line receive_trace_msg({trace, Pid, call, {?MODULE,nif, []}}),
+
+ ?line Pid ! {call_nif, nif, ["Arg1"]},
+ ?line receive_trace_msg({trace, Pid, call, {?MODULE,nif, ["Arg1"]}}),
+
+
+ %% Switch off
+ ?line 1 = erlang:trace(Pid, false, [call]),
+
+ ?line Pid ! {apply_nif, nif, []},
+ receive_nothing(),
+ ?line Pid ! {apply_nif, nif, ["Arg1"]},
+ receive_nothing(),
+ ?line Pid ! {call_nif, nif, []},
+ receive_nothing(),
+ ?line Pid ! {call_nif, nif, ["Arg1"]},
+ receive_nothing(),
+
+ %% Switch on again
+ ?line 1 = erlang:trace(Pid, true, [call]),
+ ?line erlang:trace_pattern({?MODULE,nif,'_'}, [], Flags),
+ ?line Pid ! {apply_nif, nif, []},
+ ?line receive_trace_msg({trace,Pid,call,{?MODULE,nif, []}}),
+ ?line Pid ! {apply_nif, nif, ["Arg1"]},
+ ?line receive_trace_msg({trace,Pid,call,{?MODULE,nif, ["Arg1"]}}),
+
+ ?line Pid ! {call_nif, nif, []},
+ ?line receive_trace_msg({trace, Pid, call, {?MODULE,nif, []}}),
+
+ ?line Pid ! {call_nif, nif, ["Arg1"]},
+ ?line receive_trace_msg({trace, Pid, call, {?MODULE,nif, ["Arg1"]}}),
+
+ ?line 1 = erlang:trace(Pid, false, [call]),
+ ?line erlang:trace_pattern({?MODULE,nif,'_'}, false, Flags),
+ ?line exit(Pid, die),
+ ok.
+
+trace_nif_timestamp(doc) -> "Test tracing NIFs with timestamps.";
+trace_nif_timestamp(Config) when is_list(Config) ->
+ load_nif(Config),
+ do_trace_nif_timestamp([]).
+
+trace_nif_timestamp_local(doc) ->
+ "Test tracing NIFs with timestamps and local flag.";
+trace_nif_timestamp_local(Config) when is_list(Config) ->
+ load_nif(Config),
+ do_trace_nif_timestamp([local]).
+
+do_trace_nif_timestamp(Flags) ->
+ ?line Pid=spawn(?MODULE, nif_process, []),
+ ?line 1 = erlang:trace(Pid, true, [call,timestamp]),
+ ?line erlang:trace_pattern({?MODULE,nif,'_'}, [], Flags),
+
+ ?line Pid ! {apply_nif, nif, []},
+ ?line receive_trace_msg_ts({trace_ts,Pid,call,{?MODULE,nif,[]}}),
+
+ ?line Pid ! {apply_nif, nif, ["Arg1"]},
+ ?line receive_trace_msg_ts({trace_ts,Pid,call,
+ {?MODULE,nif, ["Arg1"]}}),
+
+ ?line Pid ! {call_nif, nif, []},
+ ?line receive_trace_msg_ts({trace_ts,Pid,call,
+ {?MODULE,nif, []}}),
+
+ ?line Pid ! {call_nif, nif, ["Arg1"]},
+ ?line receive_trace_msg_ts({trace_ts,Pid,call,
+ {?MODULE,nif, ["Arg1"]}}),
+
+ %% We should be able to turn off the timestamp.
+ ?line 1 = erlang:trace(Pid, false, [timestamp]),
+
+ ?line Pid ! {call_nif, nif, []},
+ ?line receive_trace_msg({trace,Pid,call,
+ {?MODULE,nif, []}}),
+
+ ?line Pid ! {apply_nif, nif, ["tjoho"]},
+ ?line receive_trace_msg({trace,Pid,call,
+ {?MODULE,nif, ["tjoho"]}}),
+
+ ?line 1 = erlang:trace(Pid, false, [call]),
+ ?line erlang:trace_pattern({erlang,'_','_'}, false, Flags),
+
+ ?line exit(Pid, die),
+ ok.
+
+trace_nif_return(doc) ->
+ "Test tracing NIF's with return/return_to trace.";
+trace_nif_return(Config) when is_list(Config) ->
+ load_nif(Config),
+
+ ?line Pid=spawn(?MODULE, nif_process, []),
+ ?line 1 = erlang:trace(Pid, true, [call,timestamp,return_to]),
+ ?line erlang:trace_pattern({?MODULE,nif,'_'}, [{'_',[],[{return_trace}]}],
+ [local]),
+
+ ?line Pid ! {apply_nif, nif, []},
+ ?line receive_trace_msg_ts({trace_ts,Pid,call,{?MODULE,nif,[]}}),
+ ?line receive_trace_msg_ts_return_from({trace_ts,Pid,return_from,
+ {?MODULE,nif,0}}),
+ ?line receive_trace_msg_ts_return_to({trace_ts,Pid,return_to,
+ {?MODULE, nif_process,0}}),
+
+ ?line Pid ! {call_nif, nif, ["Arg1"]},
+ ?line receive_trace_msg_ts({trace_ts,Pid,call,
+ {?MODULE,nif, ["Arg1"]}}),
+ ?line receive_trace_msg_ts_return_from({trace_ts,Pid,return_from,
+ {?MODULE,nif,1}}),
+ ?line receive_trace_msg_ts_return_to({trace_ts,Pid,return_to,
+ {?MODULE, nif_process,0}}),
+ ok.
+
+
+receive_trace_msg(Mess) ->
+ receive
+ Mess ->
+ ok;
+ Other ->
+ io:format("Expected: ~p,~nGot: ~p~n", [Mess, Other]),
+ ?t:fail()
+ after 5000 ->
+ io:format("Expected: ~p,~nGot: timeout~n", [Mess]),
+ ?t:fail()
+ end.
+
+receive_nothing() ->
+ ?line timeout = receive M -> M after 100 -> timeout end.
+
+receive_trace_msg_ts({trace_ts, Pid, call, {M,F,A}}) ->
+ receive
+ {trace_ts, Pid, call, {M, F, A}, _Ts} ->
+ ok;
+ Other ->
+ io:format("Expected: {trace, ~p, call, {~p, ~p, ~p}, TimeStamp}},~n"
+ "Got: ~p~n",
+ [Pid, M, F, A, Other]),
+ ?t:fail()
+ after 5000 ->
+ io:format("Got timeout~n", []),
+ ?t:fail()
+ end.
+
+receive_trace_msg_ts_return_from({trace_ts, Pid, return_from, {M,F,A}}) ->
+ receive
+ {trace_ts, Pid, return_from, {M, F, A}, _Value, _Ts} ->
+ ok;
+ Other ->
+ io:format("Expected: {trace_ts, ~p, return_from, {~p, ~p, ~p}, Value, TimeStamp}},~n"
+ "Got: ~p~n",
+ [Pid, M, F, A, Other]),
+ ?t:fail()
+ after 5000 ->
+ io:format("Got timeout~n", []),
+ ?t:fail()
+ end.
+
+receive_trace_msg_ts_return_to({trace_ts, Pid, return_to, {M,F,A}}) ->
+ receive
+ {trace_ts, Pid, return_to, {M, F, A}, _Ts} ->
+ ok;
+ Other ->
+ io:format("Expected: {trace_ts, ~p, return_to, {~p, ~p, ~p}, TimeStamp}},~n"
+ "Got: ~p~n",
+ [Pid, M, F, A, Other]),
+ ?t:fail()
+ after 5000 ->
+ io:format("Got timeout~n", []),
+ ?t:fail()
+ end.
+
+nif_process() ->
+ receive
+ {apply_nif, Name, Args} ->
+ ?line {ok,Args} = apply(?MODULE, Name, Args);
+
+ {call_nif, Name, []} ->
+ ?line {ok, []} = ?MODULE:Name();
+
+ {call_nif, Name, [A1]} ->
+ ?line {ok, [A1]} = ?MODULE:Name(A1);
+
+ {call_nif, Name, [A1,A2]} ->
+ ?line {ok,[A1,A2]} = ?MODULE:Name(A1,A2);
+
+ {call_nif, Name, [A1,A2,A3]} ->
+ ?line {ok,[A1,A2,A3]} = ?MODULE:Name(A1,A2,A3)
+ end,
+ nif_process().
+
+load_nif(Config) ->
+ ?line Path = ?config(data_dir, Config),
+
+ ?line ok = erlang:load_nif(filename:join(Path,"trace_nif"), 0).
+
+
+nif() ->
+ {"Stub0",[]}. %exit("nif/0 stub called").
+
+nif(A1) ->
+ {"Stub1",[A1]}. %exit(["nif/1 stub called",A1]).
+