1: %% 2: %% %CopyrightBegin% 3: %% 4: %% Copyright Ericsson AB 1998-2011. All Rights Reserved. 5: %% 6: %% The contents of this file are subject to the Erlang Public License, 7: %% Version 1.1, (the "License"); you may not use this file except in 8: %% compliance with the License. You should have received a copy of the 9: %% Erlang Public License along with this software. If not, it can be 10: %% retrieved online at http://www.erlang.org/. 11: %% 12: %% Software distributed under the License is distributed on an "AS IS" 13: %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 14: %% the License for the specific language governing rights and limitations 15: %% under the License. 16: %% 17: %% %CopyrightEnd% 18: %% 19: 20: -module(trace_bif_SUITE). 21: 22: -include_lib("test_server/include/test_server.hrl"). 23: 24: -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, 25: init_per_group/2,end_per_group/2]). 26: -export([trace_bif/1, trace_bif_timestamp/1, trace_on_and_off/1, 27: trace_bif_local/1, 28: trace_bif_timestamp_local/1, trace_bif_return/1, not_run/1, 29: trace_info_old_code/1]). 30: 31: -export([bif_process/0]). 32: 33: suite() -> [{ct_hooks,[ts_install_cth]}]. 34: 35: all() -> 36: case test_server:is_native(trace_bif_SUITE) of 37: true -> [not_run]; 38: false -> 39: [trace_bif, trace_bif_timestamp, trace_on_and_off, 40: trace_bif_local, trace_bif_timestamp_local, 41: trace_bif_return, trace_info_old_code] 42: end. 43: 44: groups() -> 45: []. 46: 47: init_per_suite(Config) -> 48: Config. 49: 50: end_per_suite(_Config) -> 51: ok. 52: 53: init_per_group(_GroupName, Config) -> 54: Config. 55: 56: end_per_group(_GroupName, Config) -> 57: Config. 58: 59: 60: not_run(Config) when is_list(Config) -> 61: {skipped,"Native code"}. 62: 63: trace_on_and_off(doc) -> 64: "Tests switching tracing on and off."; 65: trace_on_and_off(Config) when is_list(Config) -> 66: ?line Pid = spawn(?MODULE, bif_process, []), 67: ?line Self = self(), 68: ?line 1 = erlang:trace(Pid, true, [call,timestamp]), 69: ?line {flags,[timestamp,call]} = erlang:trace_info(Pid,flags), 70: ?line {tracer, Self} = erlang:trace_info(Pid,tracer), 71: ?line 1 = erlang:trace(Pid, false, [timestamp]), 72: ?line {flags,[call]} = erlang:trace_info(Pid,flags), 73: ?line {tracer, Self} = erlang:trace_info(Pid,tracer), 74: ?line 1 = erlang:trace(Pid, false, [call]), 75: ?line {flags,[]} = erlang:trace_info(Pid,flags), 76: ?line {tracer, []} = erlang:trace_info(Pid,tracer), 77: ?line exit(Pid,kill), 78: ok. 79: 80: trace_bif(doc) -> "Test tracing BIFs."; 81: trace_bif(Config) when is_list(Config) -> 82: do_trace_bif([]). 83: 84: trace_bif_local(doc) -> "Test tracing BIFs with local flag."; 85: trace_bif_local(Config) when is_list(Config) -> 86: do_trace_bif([local]). 87: 88: do_trace_bif(Flags) -> 89: ?line Pid = spawn(?MODULE, bif_process, []), 90: ?line 1 = erlang:trace(Pid, true, [call]), 91: ?line erlang:trace_pattern({erlang,'_','_'}, [], Flags), 92: ?line Pid ! {do_bif, time, []}, 93: ?line receive_trace_msg({trace,Pid,call,{erlang,time, []}}), 94: ?line Pid ! {do_bif, statistics, [runtime]}, 95: ?line receive_trace_msg({trace,Pid,call, 96: {erlang,statistics, [runtime]}}), 97: 98: ?line Pid ! {do_time_bif}, 99: ?line receive_trace_msg({trace,Pid,call, 100: {erlang,time, []}}), 101: 102: ?line Pid ! {do_statistics_bif}, 103: ?line receive_trace_msg({trace,Pid,call, 104: {erlang,statistics, [runtime]}}), 105: 106: ?line 1 = erlang:trace(Pid, false, [call]), 107: ?line erlang:trace_pattern({erlang,'_','_'}, false, Flags), 108: ?line exit(Pid, die), 109: ok. 110: 111: trace_bif_timestamp(doc) -> "Test tracing BIFs with timestamps."; 112: trace_bif_timestamp(Config) when is_list(Config) -> 113: do_trace_bif_timestamp([]). 114: 115: trace_bif_timestamp_local(doc) -> 116: "Test tracing BIFs with timestamps and local flag."; 117: trace_bif_timestamp_local(Config) when is_list(Config) -> 118: do_trace_bif_timestamp([local]). 119: 120: do_trace_bif_timestamp(Flags) -> 121: ?line Pid=spawn(?MODULE, bif_process, []), 122: ?line 1 = erlang:trace(Pid, true, [call,timestamp]), 123: ?line erlang:trace_pattern({erlang,'_','_'}, [], Flags), 124: 125: ?line Pid ! {do_bif, time, []}, 126: ?line receive_trace_msg_ts({trace_ts,Pid,call,{erlang,time,[]}}), 127: 128: ?line Pid ! {do_bif, statistics, [runtime]}, 129: ?line receive_trace_msg_ts({trace_ts,Pid,call, 130: {erlang,statistics, [runtime]}}), 131: 132: ?line Pid ! {do_time_bif}, 133: ?line receive_trace_msg_ts({trace_ts,Pid,call, 134: {erlang,time, []}}), 135: 136: ?line Pid ! {do_statistics_bif}, 137: ?line receive_trace_msg_ts({trace_ts,Pid,call, 138: {erlang,statistics, [runtime]}}), 139: 140: %% We should be able to turn off the timestamp. 141: ?line 1 = erlang:trace(Pid, false, [timestamp]), 142: 143: ?line Pid ! {do_statistics_bif}, 144: ?line receive_trace_msg({trace,Pid,call, 145: {erlang,statistics, [runtime]}}), 146: 147: ?line Pid ! {do_bif, statistics, [runtime]}, 148: ?line receive_trace_msg({trace,Pid,call, 149: {erlang,statistics, [runtime]}}), 150: 151: ?line 1 = erlang:trace(Pid, false, [call]), 152: ?line erlang:trace_pattern({erlang,'_','_'}, false, Flags), 153: 154: ?line exit(Pid, die), 155: ok. 156: 157: trace_bif_return(doc) -> 158: "Test tracing BIF's with return/return_to trace."; 159: trace_bif_return(Config) when is_list(Config) -> 160: ?line Pid=spawn(?MODULE, bif_process, []), 161: ?line 1 = erlang:trace(Pid, true, [call,timestamp,return_to]), 162: ?line erlang:trace_pattern({erlang,'_','_'}, [{'_',[],[{return_trace}]}], 163: [local]), 164: 165: 166: ?line Pid ! {do_bif, time, []}, 167: ?line receive_trace_msg_ts({trace_ts,Pid,call,{erlang,time,[]}}), 168: ?line receive_trace_msg_ts_return_from({trace_ts,Pid,return_from, 169: {erlang,time,0}}), 170: ?line receive_trace_msg_ts_return_to({trace_ts,Pid,return_to, 171: {?MODULE, bif_process,0}}), 172: 173: 174: ?line Pid ! {do_bif, statistics, [runtime]}, 175: ?line receive_trace_msg_ts({trace_ts,Pid,call, 176: {erlang,statistics, [runtime]}}), 177: ?line receive_trace_msg_ts_return_from({trace_ts,Pid,return_from, 178: {erlang,statistics,1}}), 179: ?line receive_trace_msg_ts_return_to({trace_ts,Pid,return_to, 180: {?MODULE, bif_process,0}}), 181: 182: 183: ?line Pid ! {do_time_bif}, 184: ?line receive_trace_msg_ts({trace_ts,Pid,call, 185: {erlang,time, []}}), 186: ?line receive_trace_msg_ts_return_from({trace_ts,Pid,return_from, 187: {erlang,time,0}}), 188: ?line receive_trace_msg_ts_return_to({trace_ts,Pid,return_to, 189: {?MODULE, bif_process,0}}), 190: 191: 192: 193: ?line Pid ! {do_statistics_bif}, 194: ?line receive_trace_msg_ts({trace_ts,Pid,call, 195: {erlang,statistics, [runtime]}}), 196: ?line receive_trace_msg_ts_return_from({trace_ts,Pid,return_from, 197: {erlang,statistics,1}}), 198: ?line receive_trace_msg_ts_return_to({trace_ts,Pid,return_to, 199: {?MODULE, bif_process,0}}), 200: ok. 201: 202: 203: receive_trace_msg(Mess) -> 204: receive 205: Mess -> 206: ok; 207: Other -> 208: io:format("Expected: ~p,~nGot: ~p~n", [Mess, Other]), 209: ?t:fail() 210: after 5000 -> 211: io:format("Expected: ~p,~nGot: timeout~n", [Mess]), 212: ?t:fail() 213: end. 214: 215: receive_trace_msg_ts({trace_ts, Pid, call, {erlang,F,A}}) -> 216: receive 217: {trace_ts, Pid, call, {erlang, F, A}, _Ts} -> 218: ok; 219: Other -> 220: io:format("Expected: {trace, ~p, call, {~p, ~p, ~p}, TimeStamp}},~n" 221: "Got: ~p~n", 222: [Pid, erlang, F, A, Other]), 223: ?t:fail() 224: after 5000 -> 225: io:format("Got timeout~n", []), 226: ?t:fail() 227: end. 228: 229: receive_trace_msg_ts_return_from({trace_ts, Pid, return_from, {erlang,F,A}}) -> 230: receive 231: {trace_ts, Pid, return_from, {erlang, F, A}, _Value, _Ts} -> 232: ok; 233: Other -> 234: io:format("Expected: {trace_ts, ~p, return_from, {~p, ~p, ~p}, Value, TimeStamp}},~n" 235: "Got: ~p~n", 236: [Pid, erlang, F, A, Other]), 237: ?t:fail() 238: after 5000 -> 239: io:format("Got timeout~n", []), 240: ?t:fail() 241: end. 242: 243: receive_trace_msg_ts_return_to({trace_ts, Pid, return_to, {M,F,A}}) -> 244: receive 245: {trace_ts, Pid, return_to, {M, F, A}, _Ts} -> 246: ok; 247: Other -> 248: io:format("Expected: {trace_ts, ~p, return_to, {~p, ~p, ~p}, TimeStamp}},~n" 249: "Got: ~p~n", 250: [Pid, M, F, A, Other]), 251: ?t:fail() 252: after 5000 -> 253: io:format("Got timeout~n", []), 254: ?t:fail() 255: end. 256: 257: bif_process() -> 258: receive 259: {do_bif, Name, Args} -> 260: apply(erlang, Name, Args), 261: bif_process(); 262: {do_time_bif} -> 263: _ = time(), %Assignment tells compiler to keep call. 264: bif_process(); 265: {do_statistics_bif} -> 266: statistics(runtime), 267: bif_process(); 268: _Stuff -> 269: bif_process() 270: end. 271: 272: 273: 274: trace_info_old_code(doc) -> "trace_info on deleted module (OTP-5057)."; 275: trace_info_old_code(Config) when is_list(Config) -> 276: ?line MFA = {M,F,0} = {test,foo,0}, 277: ?line Fname = atom_to_list(M)++".erl", 278: ?line AbsForms = 279: [{attribute,1,module,M}, % -module(M). 280: {attribute,2,export,[{F,0}]}, % -export([F/0]). 281: {function,3,F,0, % F() -> 282: [{clause,4,[],[],[{atom,4,F}]}]}], % F. 283: %% 284: ?line {ok,M,Mbin} = compile:forms(AbsForms), 285: ?line {module,M} = code:load_binary(M, Fname, Mbin), 286: ?line true = erlang:delete_module(M), 287: ?line {traced,undefined} = erlang:trace_info(MFA, traced), 288: ok.