1: %% 2: %% %CopyrightBegin% 3: %% 4: %% Copyright Ericsson AB 2010-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_nif_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_nif/1, 27: trace_nif_timestamp/1, 28: trace_nif_local/1, 29: trace_nif_meta/1, 30: trace_nif_timestamp_local/1, 31: trace_nif_return/1, 32: not_run/1]). 33: 34: -export([nif_process/0, nif/0, nif/1]). 35: 36: suite() -> [{ct_hooks,[ts_install_cth]}]. 37: 38: all() -> 39: case test_server:is_native(trace_nif_SUITE) of 40: true -> [not_run]; 41: false -> 42: [trace_nif, trace_nif_timestamp, trace_nif_local, 43: trace_nif_meta, trace_nif_timestamp_local, 44: trace_nif_return] 45: end. 46: 47: groups() -> 48: []. 49: 50: init_per_suite(Config) -> 51: Config. 52: 53: end_per_suite(_Config) -> 54: ok. 55: 56: init_per_group(_GroupName, Config) -> 57: Config. 58: 59: end_per_group(_GroupName, Config) -> 60: Config. 61: 62: 63: not_run(Config) when is_list(Config) -> 64: {skipped,"Native code"}. 65: 66: trace_nif(doc) -> "Test tracing NIFs."; 67: trace_nif(Config) when is_list(Config) -> 68: load_nif(Config), 69: 70: do_trace_nif([]). 71: 72: trace_nif_local(doc) -> "Test tracing NIFs with local flag."; 73: trace_nif_local(Config) when is_list(Config) -> 74: load_nif(Config), 75: do_trace_nif([local]). 76: 77: trace_nif_meta(doc) -> "Test tracing NIFs with meta flag."; 78: trace_nif_meta(Config) when is_list(Config) -> 79: load_nif(Config), 80: ?line Pid=spawn_link(?MODULE, nif_process, []), 81: ?line erlang:trace_pattern({?MODULE,nif,'_'}, [], [meta]), 82: 83: ?line Pid ! {apply_nif, nif, []}, 84: ?line receive_trace_msg_ts({trace_ts,Pid,call,{?MODULE,nif,[]}}), 85: 86: ?line Pid ! {apply_nif, nif, ["Arg1"]}, 87: ?line receive_trace_msg_ts({trace_ts,Pid,call, 88: {?MODULE,nif, ["Arg1"]}}), 89: 90: ?line Pid ! {call_nif, nif, []}, 91: ?line receive_trace_msg_ts({trace_ts,Pid,call, 92: {?MODULE,nif, []}}), 93: 94: ?line Pid ! {call_nif, nif, ["Arg1"]}, 95: ?line receive_trace_msg_ts({trace_ts,Pid,call, 96: {?MODULE,nif, ["Arg1"]}}), 97: ok. 98: do_trace_nif(Flags) -> 99: ?line Pid = spawn(?MODULE, nif_process, []), 100: ?line 1 = erlang:trace(Pid, true, [call]), 101: ?line erlang:trace_pattern({?MODULE,nif,'_'}, [], Flags), 102: ?line Pid ! {apply_nif, nif, []}, 103: ?line receive_trace_msg({trace,Pid,call,{?MODULE,nif, []}}), 104: ?line Pid ! {apply_nif, nif, ["Arg1"]}, 105: ?line receive_trace_msg({trace,Pid,call,{?MODULE,nif, ["Arg1"]}}), 106: 107: ?line Pid ! {call_nif, nif, []}, 108: ?line receive_trace_msg({trace, Pid, call, {?MODULE,nif, []}}), 109: 110: ?line Pid ! {call_nif, nif, ["Arg1"]}, 111: ?line receive_trace_msg({trace, Pid, call, {?MODULE,nif, ["Arg1"]}}), 112: 113: 114: %% Switch off 115: ?line 1 = erlang:trace(Pid, false, [call]), 116: 117: ?line Pid ! {apply_nif, nif, []}, 118: receive_nothing(), 119: ?line Pid ! {apply_nif, nif, ["Arg1"]}, 120: receive_nothing(), 121: ?line Pid ! {call_nif, nif, []}, 122: receive_nothing(), 123: ?line Pid ! {call_nif, nif, ["Arg1"]}, 124: receive_nothing(), 125: 126: %% Switch on again 127: ?line 1 = erlang:trace(Pid, true, [call]), 128: ?line erlang:trace_pattern({?MODULE,nif,'_'}, [], Flags), 129: ?line Pid ! {apply_nif, nif, []}, 130: ?line receive_trace_msg({trace,Pid,call,{?MODULE,nif, []}}), 131: ?line Pid ! {apply_nif, nif, ["Arg1"]}, 132: ?line receive_trace_msg({trace,Pid,call,{?MODULE,nif, ["Arg1"]}}), 133: 134: ?line Pid ! {call_nif, nif, []}, 135: ?line receive_trace_msg({trace, Pid, call, {?MODULE,nif, []}}), 136: 137: ?line Pid ! {call_nif, nif, ["Arg1"]}, 138: ?line receive_trace_msg({trace, Pid, call, {?MODULE,nif, ["Arg1"]}}), 139: 140: ?line 1 = erlang:trace(Pid, false, [call]), 141: ?line erlang:trace_pattern({?MODULE,nif,'_'}, false, Flags), 142: ?line exit(Pid, die), 143: ok. 144: 145: trace_nif_timestamp(doc) -> "Test tracing NIFs with timestamps."; 146: trace_nif_timestamp(Config) when is_list(Config) -> 147: load_nif(Config), 148: do_trace_nif_timestamp([]). 149: 150: trace_nif_timestamp_local(doc) -> 151: "Test tracing NIFs with timestamps and local flag."; 152: trace_nif_timestamp_local(Config) when is_list(Config) -> 153: load_nif(Config), 154: do_trace_nif_timestamp([local]). 155: 156: do_trace_nif_timestamp(Flags) -> 157: ?line Pid=spawn(?MODULE, nif_process, []), 158: ?line 1 = erlang:trace(Pid, true, [call,timestamp]), 159: ?line erlang:trace_pattern({?MODULE,nif,'_'}, [], Flags), 160: 161: ?line Pid ! {apply_nif, nif, []}, 162: ?line receive_trace_msg_ts({trace_ts,Pid,call,{?MODULE,nif,[]}}), 163: 164: ?line Pid ! {apply_nif, nif, ["Arg1"]}, 165: ?line receive_trace_msg_ts({trace_ts,Pid,call, 166: {?MODULE,nif, ["Arg1"]}}), 167: 168: ?line Pid ! {call_nif, nif, []}, 169: ?line receive_trace_msg_ts({trace_ts,Pid,call, 170: {?MODULE,nif, []}}), 171: 172: ?line Pid ! {call_nif, nif, ["Arg1"]}, 173: ?line receive_trace_msg_ts({trace_ts,Pid,call, 174: {?MODULE,nif, ["Arg1"]}}), 175: 176: %% We should be able to turn off the timestamp. 177: ?line 1 = erlang:trace(Pid, false, [timestamp]), 178: 179: ?line Pid ! {call_nif, nif, []}, 180: ?line receive_trace_msg({trace,Pid,call, 181: {?MODULE,nif, []}}), 182: 183: ?line Pid ! {apply_nif, nif, ["tjoho"]}, 184: ?line receive_trace_msg({trace,Pid,call, 185: {?MODULE,nif, ["tjoho"]}}), 186: 187: ?line 1 = erlang:trace(Pid, false, [call]), 188: ?line erlang:trace_pattern({erlang,'_','_'}, false, Flags), 189: 190: ?line exit(Pid, die), 191: ok. 192: 193: trace_nif_return(doc) -> 194: "Test tracing NIF's with return/return_to trace."; 195: trace_nif_return(Config) when is_list(Config) -> 196: load_nif(Config), 197: 198: ?line Pid=spawn(?MODULE, nif_process, []), 199: ?line 1 = erlang:trace(Pid, true, [call,timestamp,return_to]), 200: ?line erlang:trace_pattern({?MODULE,nif,'_'}, [{'_',[],[{return_trace}]}], 201: [local]), 202: 203: ?line Pid ! {apply_nif, nif, []}, 204: ?line receive_trace_msg_ts({trace_ts,Pid,call,{?MODULE,nif,[]}}), 205: ?line receive_trace_msg_ts_return_from({trace_ts,Pid,return_from, 206: {?MODULE,nif,0}}), 207: ?line receive_trace_msg_ts_return_to({trace_ts,Pid,return_to, 208: {?MODULE, nif_process,0}}), 209: 210: ?line Pid ! {call_nif, nif, ["Arg1"]}, 211: ?line receive_trace_msg_ts({trace_ts,Pid,call, 212: {?MODULE,nif, ["Arg1"]}}), 213: ?line receive_trace_msg_ts_return_from({trace_ts,Pid,return_from, 214: {?MODULE,nif,1}}), 215: ?line receive_trace_msg_ts_return_to({trace_ts,Pid,return_to, 216: {?MODULE, nif_process,0}}), 217: ok. 218: 219: 220: receive_trace_msg(Mess) -> 221: receive 222: Mess -> 223: ok; 224: Other -> 225: io:format("Expected: ~p,~nGot: ~p~n", [Mess, Other]), 226: ?t:fail() 227: after 5000 -> 228: io:format("Expected: ~p,~nGot: timeout~n", [Mess]), 229: ?t:fail() 230: end. 231: 232: receive_nothing() -> 233: ?line timeout = receive M -> M after 100 -> timeout end. 234: 235: receive_trace_msg_ts({trace_ts, Pid, call, {M,F,A}}) -> 236: receive 237: {trace_ts, Pid, call, {M, F, A}, _Ts} -> 238: ok; 239: Other -> 240: io:format("Expected: {trace, ~p, call, {~p, ~p, ~p}, TimeStamp}},~n" 241: "Got: ~p~n", 242: [Pid, M, F, A, Other]), 243: ?t:fail() 244: after 5000 -> 245: io:format("Got timeout~n", []), 246: ?t:fail() 247: end. 248: 249: receive_trace_msg_ts_return_from({trace_ts, Pid, return_from, {M,F,A}}) -> 250: receive 251: {trace_ts, Pid, return_from, {M, F, A}, _Value, _Ts} -> 252: ok; 253: Other -> 254: io:format("Expected: {trace_ts, ~p, return_from, {~p, ~p, ~p}, Value, TimeStamp}},~n" 255: "Got: ~p~n", 256: [Pid, M, F, A, Other]), 257: ?t:fail() 258: after 5000 -> 259: io:format("Got timeout~n", []), 260: ?t:fail() 261: end. 262: 263: receive_trace_msg_ts_return_to({trace_ts, Pid, return_to, {M,F,A}}) -> 264: receive 265: {trace_ts, Pid, return_to, {M, F, A}, _Ts} -> 266: ok; 267: Other -> 268: io:format("Expected: {trace_ts, ~p, return_to, {~p, ~p, ~p}, TimeStamp}},~n" 269: "Got: ~p~n", 270: [Pid, M, F, A, Other]), 271: ?t:fail() 272: after 5000 -> 273: io:format("Got timeout~n", []), 274: ?t:fail() 275: end. 276: 277: nif_process() -> 278: receive 279: {apply_nif, Name, Args} -> 280: ?line {ok,Args} = apply(?MODULE, Name, Args); 281: 282: {call_nif, Name, []} -> 283: ?line {ok, []} = ?MODULE:Name(); 284: 285: {call_nif, Name, [A1]} -> 286: ?line {ok, [A1]} = ?MODULE:Name(A1); 287: 288: {call_nif, Name, [A1,A2]} -> 289: ?line {ok,[A1,A2]} = ?MODULE:Name(A1,A2); 290: 291: {call_nif, Name, [A1,A2,A3]} -> 292: ?line {ok,[A1,A2,A3]} = ?MODULE:Name(A1,A2,A3) 293: end, 294: nif_process(). 295: 296: load_nif(Config) -> 297: ?line Path = ?config(data_dir, Config), 298: 299: ?line ok = erlang:load_nif(filename:join(Path,"trace_nif"), 0). 300: 301: 302: nif() -> 303: {"Stub0",[]}. %exit("nif/0 stub called"). 304: 305: nif(A1) -> 306: {"Stub1",[A1]}. %exit(["nif/1 stub called",A1]). 307: