diff options
Diffstat (limited to 'erts/emulator/test/trace_bif_SUITE.erl')
-rw-r--r-- | erts/emulator/test/trace_bif_SUITE.erl | 268 |
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. |