aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/test/trace_bif_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/test/trace_bif_SUITE.erl')
-rw-r--r--erts/emulator/test/trace_bif_SUITE.erl268
1 files changed, 268 insertions, 0 deletions
diff --git a/erts/emulator/test/trace_bif_SUITE.erl b/erts/emulator/test/trace_bif_SUITE.erl
new file mode 100644
index 0000000000..3f91f8dc08
--- /dev/null
+++ b/erts/emulator/test/trace_bif_SUITE.erl
@@ -0,0 +1,268 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1998-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_bif_SUITE).
+
+-include("test_server.hrl").
+
+-export([all/1]).
+-export([trace_bif/1, trace_bif_timestamp/1, trace_on_and_off/1, trace_bif_local/1,
+ trace_bif_timestamp_local/1, trace_bif_return/1, not_run/1,
+ trace_info_old_code/1]).
+
+-export([bif_process/0]).
+
+all(suite) ->
+ case test_server:is_native(?MODULE) of
+ true -> [not_run];
+ false ->
+ [trace_bif, trace_bif_timestamp, trace_on_and_off,
+ trace_bif_local, trace_bif_timestamp_local,
+ trace_bif_return, trace_info_old_code]
+ end.
+
+not_run(Config) when is_list(Config) ->
+ {skipped,"Native code"}.
+
+trace_on_and_off(doc) ->
+ "Tests switching tracing on and off.";
+trace_on_and_off(Config) when is_list(Config) ->
+ ?line Pid = spawn(?MODULE, bif_process, []),
+ ?line Self = self(),
+ ?line 1 = erlang:trace(Pid, true, [call,timestamp]),
+ ?line {flags,[timestamp,call]} = erlang:trace_info(Pid,flags),
+ ?line {tracer, Self} = erlang:trace_info(Pid,tracer),
+ ?line 1 = erlang:trace(Pid, false, [timestamp]),
+ ?line {flags,[call]} = erlang:trace_info(Pid,flags),
+ ?line {tracer, Self} = erlang:trace_info(Pid,tracer),
+ ?line 1 = erlang:trace(Pid, false, [call]),
+ ?line {flags,[]} = erlang:trace_info(Pid,flags),
+ ?line {tracer, []} = erlang:trace_info(Pid,tracer),
+ ?line exit(Pid,kill),
+ ok.
+
+trace_bif(doc) -> "Test tracing BIFs.";
+trace_bif(Config) when is_list(Config) ->
+ do_trace_bif([]).
+
+trace_bif_local(doc) -> "Test tracing BIFs with local flag.";
+trace_bif_local(Config) when is_list(Config) ->
+ do_trace_bif([local]).
+
+do_trace_bif(Flags) ->
+ ?line Pid = spawn(?MODULE, bif_process, []),
+ ?line 1 = erlang:trace(Pid, true, [call]),
+ ?line erlang:trace_pattern({erlang,'_','_'}, [], Flags),
+ ?line Pid ! {do_bif, time, []},
+ ?line receive_trace_msg({trace,Pid,call,{erlang,time, []}}),
+ ?line Pid ! {do_bif, statistics, [runtime]},
+ ?line receive_trace_msg({trace,Pid,call,
+ {erlang,statistics, [runtime]}}),
+
+ ?line Pid ! {do_time_bif},
+ ?line receive_trace_msg({trace,Pid,call,
+ {erlang,time, []}}),
+
+ ?line Pid ! {do_statistics_bif},
+ ?line receive_trace_msg({trace,Pid,call,
+ {erlang,statistics, [runtime]}}),
+
+ ?line 1 = erlang:trace(Pid, false, [call]),
+ ?line erlang:trace_pattern({erlang,'_','_'}, false, Flags),
+ ?line exit(Pid, die),
+ ok.
+
+trace_bif_timestamp(doc) -> "Test tracing BIFs with timestamps.";
+trace_bif_timestamp(Config) when is_list(Config) ->
+ do_trace_bif_timestamp([]).
+
+trace_bif_timestamp_local(doc) ->
+ "Test tracing BIFs with timestamps and local flag.";
+trace_bif_timestamp_local(Config) when is_list(Config) ->
+ do_trace_bif_timestamp([local]).
+
+do_trace_bif_timestamp(Flags) ->
+ ?line Pid=spawn(?MODULE, bif_process, []),
+ ?line 1 = erlang:trace(Pid, true, [call,timestamp]),
+ ?line erlang:trace_pattern({erlang,'_','_'}, [], Flags),
+
+ ?line Pid ! {do_bif, time, []},
+ ?line receive_trace_msg_ts({trace_ts,Pid,call,{erlang,time,[]}}),
+
+ ?line Pid ! {do_bif, statistics, [runtime]},
+ ?line receive_trace_msg_ts({trace_ts,Pid,call,
+ {erlang,statistics, [runtime]}}),
+
+ ?line Pid ! {do_time_bif},
+ ?line receive_trace_msg_ts({trace_ts,Pid,call,
+ {erlang,time, []}}),
+
+ ?line Pid ! {do_statistics_bif},
+ ?line receive_trace_msg_ts({trace_ts,Pid,call,
+ {erlang,statistics, [runtime]}}),
+
+ %% We should be able to turn off the timestamp.
+ ?line 1 = erlang:trace(Pid, false, [timestamp]),
+
+ ?line Pid ! {do_statistics_bif},
+ ?line receive_trace_msg({trace,Pid,call,
+ {erlang,statistics, [runtime]}}),
+
+ ?line Pid ! {do_bif, statistics, [runtime]},
+ ?line receive_trace_msg({trace,Pid,call,
+ {erlang,statistics, [runtime]}}),
+
+ ?line 1 = erlang:trace(Pid, false, [call]),
+ ?line erlang:trace_pattern({erlang,'_','_'}, false, Flags),
+
+ ?line exit(Pid, die),
+ ok.
+
+trace_bif_return(doc) ->
+ "Test tracing BIF's with return/return_to trace.";
+trace_bif_return(Config) when is_list(Config) ->
+ ?line Pid=spawn(?MODULE, bif_process, []),
+ ?line 1 = erlang:trace(Pid, true, [call,timestamp,return_to]),
+ ?line erlang:trace_pattern({erlang,'_','_'}, [{'_',[],[{return_trace}]}],
+ [local]),
+
+
+ ?line Pid ! {do_bif, time, []},
+ ?line receive_trace_msg_ts({trace_ts,Pid,call,{erlang,time,[]}}),
+ ?line receive_trace_msg_ts_return_from({trace_ts,Pid,return_from,
+ {erlang,time,0}}),
+ ?line receive_trace_msg_ts_return_to({trace_ts,Pid,return_to,
+ {?MODULE, bif_process,0}}),
+
+
+ ?line Pid ! {do_bif, statistics, [runtime]},
+ ?line receive_trace_msg_ts({trace_ts,Pid,call,
+ {erlang,statistics, [runtime]}}),
+ ?line receive_trace_msg_ts_return_from({trace_ts,Pid,return_from,
+ {erlang,statistics,1}}),
+ ?line receive_trace_msg_ts_return_to({trace_ts,Pid,return_to,
+ {?MODULE, bif_process,0}}),
+
+
+ ?line Pid ! {do_time_bif},
+ ?line receive_trace_msg_ts({trace_ts,Pid,call,
+ {erlang,time, []}}),
+ ?line receive_trace_msg_ts_return_from({trace_ts,Pid,return_from,
+ {erlang,time,0}}),
+ ?line receive_trace_msg_ts_return_to({trace_ts,Pid,return_to,
+ {?MODULE, bif_process,0}}),
+
+
+
+ ?line Pid ! {do_statistics_bif},
+ ?line receive_trace_msg_ts({trace_ts,Pid,call,
+ {erlang,statistics, [runtime]}}),
+ ?line receive_trace_msg_ts_return_from({trace_ts,Pid,return_from,
+ {erlang,statistics,1}}),
+ ?line receive_trace_msg_ts_return_to({trace_ts,Pid,return_to,
+ {?MODULE, bif_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_trace_msg_ts({trace_ts, Pid, call, {erlang,F,A}}) ->
+ receive
+ {trace_ts, Pid, call, {erlang, F, A}, _Ts} ->
+ ok;
+ Other ->
+ io:format("Expected: {trace, ~p, call, {~p, ~p, ~p}, TimeStamp}},~n"
+ "Got: ~p~n",
+ [Pid, erlang, 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, {erlang,F,A}}) ->
+ receive
+ {trace_ts, Pid, return_from, {erlang, F, A}, _Value, _Ts} ->
+ ok;
+ Other ->
+ io:format("Expected: {trace_ts, ~p, return_from, {~p, ~p, ~p}, Value, TimeStamp}},~n"
+ "Got: ~p~n",
+ [Pid, erlang, 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.
+
+bif_process() ->
+ receive
+ {do_bif, Name, Args} ->
+ apply(erlang, Name, Args),
+ bif_process();
+ {do_time_bif} ->
+ _ = time(), %Assignment tells compiler to keep call.
+ bif_process();
+ {do_statistics_bif} ->
+ statistics(runtime),
+ bif_process();
+ _Stuff ->
+ bif_process()
+ end.
+
+
+
+trace_info_old_code(doc) -> "trace_info on deleted module (OTP-5057).";
+trace_info_old_code(Config) when is_list(Config) ->
+ ?line MFA = {M,F,0} = {test,foo,0},
+ ?line Fname = atom_to_list(M)++".erl",
+ ?line AbsForms =
+ [{attribute,1,module,M}, % -module(M).
+ {attribute,2,export,[{F,0}]}, % -export([F/0]).
+ {function,3,F,0, % F() ->
+ [{clause,4,[],[],[{atom,4,F}]}]}], % F.
+ %%
+ ?line {ok,M,Mbin} = compile:forms(AbsForms),
+ ?line {module,M} = code:load_binary(M, Fname, Mbin),
+ ?line true = erlang:delete_module(M),
+ ?line {traced,undefined} = erlang:trace_info(MFA, traced),
+ ok.