aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/test
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/test')
-rw-r--r--erts/emulator/test/Makefile1
-rw-r--r--erts/emulator/test/dirty_nif_SUITE.erl327
-rw-r--r--erts/emulator/test/dirty_nif_SUITE_data/Makefile.src6
-rw-r--r--erts/emulator/test/dirty_nif_SUITE_data/dirty_nif_SUITE.c223
-rw-r--r--erts/emulator/test/nif_SUITE.erl80
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_SUITE.c123
-rw-r--r--erts/emulator/test/scheduler_SUITE.erl50
-rw-r--r--erts/emulator/test/scheduler_SUITE_data/Makefile.src8
-rw-r--r--erts/emulator/test/scheduler_SUITE_data/scheduler_SUITE.c37
-rw-r--r--erts/emulator/test/trace_bif_SUITE.erl1
-rw-r--r--erts/emulator/test/tracer_SUITE.erl90
-rw-r--r--erts/emulator/test/tracer_SUITE_data/tracer_test.c12
12 files changed, 607 insertions, 351 deletions
diff --git a/erts/emulator/test/Makefile b/erts/emulator/test/Makefile
index de395dfb97..b580211eff 100644
--- a/erts/emulator/test/Makefile
+++ b/erts/emulator/test/Makefile
@@ -53,6 +53,7 @@ MODULES= \
crypto_SUITE \
ddll_SUITE \
decode_packet_SUITE \
+ dirty_nif_SUITE \
distribution_SUITE \
driver_SUITE \
efile_SUITE \
diff --git a/erts/emulator/test/dirty_nif_SUITE.erl b/erts/emulator/test/dirty_nif_SUITE.erl
new file mode 100644
index 0000000000..c3afbc0803
--- /dev/null
+++ b/erts/emulator/test/dirty_nif_SUITE.erl
@@ -0,0 +1,327 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2010-2014. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(dirty_nif_SUITE).
+
+%%-define(line_trace,true).
+-define(CHECK(Exp,Got), check(Exp,Got,?LINE)).
+%%-define(CHECK(Exp,Got), Exp = Got).
+
+-include_lib("common_test/include/ct.hrl").
+
+-export([all/0, suite/0,
+ init_per_suite/1, end_per_suite/1,
+ init_per_testcase/2, end_per_testcase/2,
+ dirty_nif/1, dirty_nif_send/1,
+ dirty_nif_exception/1, call_dirty_nif_exception/1,
+ dirty_scheduler_exit/1, dirty_call_while_terminated/1,
+ dirty_heap_access/1]).
+
+-define(nif_stub,nif_stub_error(?LINE)).
+
+suite() -> [{ct_hooks,[ts_install_cth]}].
+
+all() ->
+ [dirty_nif,
+ dirty_nif_send,
+ dirty_nif_exception,
+ dirty_scheduler_exit,
+ dirty_call_while_terminated,
+ dirty_heap_access].
+
+init_per_suite(Config) ->
+ try erlang:system_info(dirty_cpu_schedulers) of
+ N when is_integer(N), N > 0 ->
+ case lib_loaded() of
+ false ->
+ ok = erlang:load_nif(
+ filename:join(?config(data_dir, Config),
+ "dirty_nif_SUITE"), []);
+ true ->
+ ok
+ end,
+ Config
+ catch _:_ ->
+ {skipped, "No dirty scheduler support"}
+ end.
+
+end_per_suite(_Config) ->
+ ok.
+
+init_per_testcase(Case, Config) ->
+ [{testcase, Case} | Config].
+
+end_per_testcase(_Case, _Config) ->
+ ok.
+
+dirty_nif(Config) when is_list(Config) ->
+ Val1 = 42,
+ Val2 = "Erlang",
+ Val3 = list_to_binary([Val2, 0]),
+ {Val1, Val2, Val3} = call_dirty_nif(Val1, Val2, Val3),
+ LargeArray = lists:duplicate(1000, ok),
+ LargeArray = call_dirty_nif_zero_args(),
+ ok.
+
+dirty_nif_send(Config) when is_list(Config) ->
+ Parent = self(),
+ Pid = spawn_link(fun() ->
+ Self = self(),
+ {ok, Self} = receive_any(),
+ Parent ! {ok, Self}
+ end),
+ {ok, Pid} = send_from_dirty_nif(Pid),
+ {ok, Pid} = receive_any(),
+ ok.
+
+dirty_nif_exception(Config) when is_list(Config) ->
+ try
+ %% this checks that the expected exception occurs when the
+ %% dirty NIF returns the result of enif_make_badarg
+ %% directly
+ call_dirty_nif_exception(1),
+ ct:fail(expected_badarg)
+ catch
+ error:badarg ->
+ [{?MODULE,call_dirty_nif_exception,[1],_}|_] =
+ erlang:get_stacktrace(),
+ ok
+ end,
+ try
+ %% this checks that the expected exception occurs when the
+ %% dirty NIF calls enif_make_badarg at some point but then
+ %% returns a value that isn't an exception
+ call_dirty_nif_exception(0),
+ ct:fail(expected_badarg)
+ catch
+ error:badarg ->
+ [{?MODULE,call_dirty_nif_exception,[0],_}|_] =
+ erlang:get_stacktrace(),
+ ok
+ end,
+ %% this checks that a dirty NIF can raise various terms as
+ %% exceptions
+ ok = nif_raise_exceptions(call_dirty_nif_exception).
+
+nif_raise_exceptions(NifFunc) ->
+ ExcTerms = [{error, test}, "a string", <<"a binary">>,
+ 42, [1,2,3,4,5], [{p,1},{p,2},{p,3}]],
+ lists:foldl(fun(Term, ok) ->
+ try
+ erlang:apply(?MODULE,NifFunc,[Term]),
+ ct:fail({expected,Term})
+ catch
+ error:Term ->
+ [{?MODULE,NifFunc,[Term],_}|_] = erlang:get_stacktrace(),
+ ok
+ end
+ end, ok, ExcTerms).
+
+dirty_scheduler_exit(Config) when is_list(Config) ->
+ {ok, Node} = start_node(Config, "+SDio 1"),
+ Path = proplists:get_value(data_dir, Config),
+ NifLib = filename:join(Path, atom_to_list(?MODULE)),
+ [ok] = mcall(Node,
+ [fun() ->
+ ok = erlang:load_nif(NifLib, []),
+ Start = erlang:monotonic_time(milli_seconds),
+ ok = test_dirty_scheduler_exit(),
+ End = erlang:monotonic_time(milli_seconds),
+ io:format("Time=~p ms~n", [End-Start]),
+ ok
+ end]),
+ stop_node(Node),
+ ok.
+
+test_dirty_scheduler_exit() ->
+ process_flag(trap_exit,true),
+ test_dse(10,[]).
+test_dse(0,Pids) ->
+ timer:sleep(100),
+ kill_dse(Pids,[]);
+test_dse(N,Pids) ->
+ Pid = spawn_link(fun dirty_sleeper/0),
+ test_dse(N-1,[Pid|Pids]).
+
+kill_dse([],Killed) ->
+ wait_dse(Killed);
+kill_dse([Pid|Pids],AlreadyKilled) ->
+ exit(Pid,kill),
+ kill_dse(Pids,[Pid|AlreadyKilled]).
+
+wait_dse([]) ->
+ ok;
+wait_dse([Pid|Pids]) ->
+ receive
+ {'EXIT',Pid,Reason} ->
+ killed = Reason
+ end,
+ wait_dse(Pids).
+
+dirty_call_while_terminated(Config) when is_list(Config) ->
+ Me = self(),
+ Bin = list_to_binary(lists:duplicate(4711, $r)),
+ {value, {BinAddr, 4711, 1}} = lists:keysearch(4711, 2,
+ element(2,
+ process_info(self(),
+ binary))),
+ {Dirty, DM} = spawn_opt(fun () ->
+ dirty_call_while_terminated_nif(Me),
+ blipp:blupp(Bin)
+ end,
+ [monitor,link]),
+ receive {dirty_alive, Pid} -> ok end,
+ {value, {BinAddr, 4711, 2}} = lists:keysearch(4711, 2,
+ element(2,
+ process_info(self(),
+ binary))),
+ Reason = die_dirty_process,
+ OT = process_flag(trap_exit, true),
+ exit(Dirty, Reason),
+ receive
+ {'DOWN', DM, process, Dirty, R0} ->
+ R0 = Reason
+ end,
+ receive
+ {'EXIT', Dirty, R1} ->
+ R1 = Reason
+ end,
+ undefined = process_info(Dirty),
+ undefined = process_info(Dirty, status),
+ false = erlang:is_process_alive(Dirty),
+ false = lists:member(Dirty, processes()),
+ %% Binary still refered by Dirty process not yet cleaned up
+ %% since the dirty nif has not yet returned...
+ {value, {BinAddr, 4711, 2}} = lists:keysearch(4711, 2,
+ element(2,
+ process_info(self(),
+ binary))),
+ receive after 2000 -> ok end,
+ receive
+ Msg ->
+ ct:fail({unexpected_message, Msg})
+ after
+ 0 ->
+ ok
+ end,
+ {value, {BinAddr, 4711, 1}} = lists:keysearch(4711, 2,
+ element(2,
+ process_info(self(),
+ binary))),
+ process_flag(trap_exit, OT),
+ ok.
+
+dirty_heap_access(Config) when is_list(Config) ->
+ {ok, Node} = start_node(Config),
+ Me = self(),
+ RGL = rpc:call(Node,erlang,whereis,[init]),
+ Ref = rpc:call(Node,erlang,make_ref,[]),
+ Dirty = spawn_link(fun () ->
+ Res = dirty_heap_access_nif(Ref),
+ garbage_collect(),
+ Me ! {self(), Res},
+ receive after infinity -> ok end
+ end),
+ {N, R} = access_dirty_heap(Dirty, RGL, 0, 0),
+ receive
+ {Pid, Res} ->
+ 1000 = length(Res),
+ lists:foreach(fun (X) -> Ref = X end, Res)
+ end,
+ unlink(Dirty),
+ exit(Dirty, kill),
+ stop_node(Node),
+ {comment, integer_to_list(N) ++ " GL change loops; "
+ ++ integer_to_list(R) ++ " while running dirty"}.
+
+access_dirty_heap(Dirty, RGL, N, R) ->
+ case process_info(Dirty, status) of
+ {status, waiting} ->
+ {N, R};
+ {status, Status} ->
+ {group_leader, GL} = process_info(Dirty, group_leader),
+ true = group_leader(RGL, Dirty),
+ {group_leader, RGL} = process_info(Dirty, group_leader),
+ true = group_leader(GL, Dirty),
+ {group_leader, GL} = process_info(Dirty, group_leader),
+ access_dirty_heap(Dirty, RGL, N+1, case Status of
+ running ->
+ R+1;
+ _ ->
+ R
+ end)
+ end.
+
+%%
+%% Internal...
+%%
+
+receive_any() ->
+ receive M -> M end.
+
+start_node(Config) ->
+ start_node(Config, "").
+
+start_node(Config, Args) when is_list(Config) ->
+ Pa = filename:dirname(code:which(?MODULE)),
+ Name = list_to_atom(atom_to_list(?MODULE)
+ ++ "-"
+ ++ atom_to_list(proplists:get_value(testcase, Config))
+ ++ "-"
+ ++ integer_to_list(erlang:system_time(seconds))
+ ++ "-"
+ ++ integer_to_list(erlang:unique_integer([positive]))),
+ test_server:start_node(Name, slave, [{args, "-pa "++Pa++" "++Args}]).
+
+stop_node(Node) ->
+ test_server:stop_node(Node).
+
+mcall(Node, Funs) ->
+ Parent = self(),
+ Refs = lists:map(fun (Fun) ->
+ Ref = make_ref(),
+ spawn_link(Node,
+ fun () ->
+ Res = Fun(),
+ unlink(Parent),
+ Parent ! {Ref, Res}
+ end),
+ Ref
+ end, Funs),
+ lists:map(fun (Ref) ->
+ receive
+ {Ref, Res} ->
+ Res
+ end
+ end, Refs).
+
+%% The NIFs:
+lib_loaded() -> false.
+call_nif_schedule(_,_) -> ?nif_stub.
+call_dirty_nif(_,_,_) -> ?nif_stub.
+send_from_dirty_nif(_) -> ?nif_stub.
+call_dirty_nif_exception(_) -> ?nif_stub.
+call_dirty_nif_zero_args() -> ?nif_stub.
+dirty_call_while_terminated_nif(_) -> ?nif_stub.
+dirty_sleeper() -> ?nif_stub.
+dirty_heap_access_nif(_) -> ?nif_stub.
+
+nif_stub_error(Line) ->
+ exit({nif_not_loaded,module,?MODULE,line,Line}).
diff --git a/erts/emulator/test/dirty_nif_SUITE_data/Makefile.src b/erts/emulator/test/dirty_nif_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..e9301753b0
--- /dev/null
+++ b/erts/emulator/test/dirty_nif_SUITE_data/Makefile.src
@@ -0,0 +1,6 @@
+
+NIF_LIBS = dirty_nif_SUITE@dll@
+
+all: $(NIF_LIBS)
+
+@SHLIB_RULES@
diff --git a/erts/emulator/test/dirty_nif_SUITE_data/dirty_nif_SUITE.c b/erts/emulator/test/dirty_nif_SUITE_data/dirty_nif_SUITE.c
new file mode 100644
index 0000000000..2013c88167
--- /dev/null
+++ b/erts/emulator/test/dirty_nif_SUITE_data/dirty_nif_SUITE.c
@@ -0,0 +1,223 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2009-2014. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * %CopyrightEnd%
+ */
+#include "erl_nif.h"
+#include <assert.h>
+#ifndef __WIN32__
+#include <unistd.h>
+#endif
+
+static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
+{
+ return 0;
+}
+
+static ERL_NIF_TERM lib_loaded(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ return enif_make_atom(env, "true");
+}
+
+static int have_dirty_schedulers(void)
+{
+ ErlNifSysInfo si;
+ enif_system_info(&si, sizeof(si));
+ return si.dirty_scheduler_support;
+}
+
+static ERL_NIF_TERM dirty_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ int n;
+ char s[10];
+ ErlNifBinary b;
+ if (have_dirty_schedulers()) {
+ assert(enif_is_on_dirty_scheduler(env));
+ }
+ assert(argc == 3);
+ enif_get_int(env, argv[0], &n);
+ enif_get_string(env, argv[1], s, sizeof s, ERL_NIF_LATIN1);
+ enif_inspect_binary(env, argv[2], &b);
+ return enif_make_tuple3(env,
+ enif_make_int(env, n),
+ enif_make_string(env, s, ERL_NIF_LATIN1),
+ enif_make_binary(env, &b));
+}
+
+static ERL_NIF_TERM call_dirty_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ int n;
+ char s[10];
+ ErlNifBinary b;
+ assert(!enif_is_on_dirty_scheduler(env));
+ if (argc != 3)
+ return enif_make_badarg(env);
+ if (have_dirty_schedulers()) {
+ if (enif_get_int(env, argv[0], &n) &&
+ enif_get_string(env, argv[1], s, sizeof s, ERL_NIF_LATIN1) &&
+ enif_inspect_binary(env, argv[2], &b))
+ return enif_schedule_nif(env, "call_dirty_nif", ERL_NIF_DIRTY_JOB_CPU_BOUND, dirty_nif, argc, argv);
+ else
+ return enif_make_badarg(env);
+ } else {
+ return dirty_nif(env, argc, argv);
+ }
+}
+
+static ERL_NIF_TERM send_from_dirty_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ ERL_NIF_TERM result;
+ ErlNifPid pid;
+ ErlNifEnv* menv;
+ int res;
+
+ if (!enif_get_local_pid(env, argv[0], &pid))
+ return enif_make_badarg(env);
+ result = enif_make_tuple2(env, enif_make_atom(env, "ok"), enif_make_pid(env, &pid));
+ menv = enif_alloc_env();
+ res = enif_send(env, &pid, menv, result);
+ enif_free_env(menv);
+ if (!res)
+ return enif_make_badarg(env);
+ else
+ return result;
+}
+
+static ERL_NIF_TERM call_dirty_nif_exception(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ switch (argc) {
+ case 1: {
+ int arg;
+ if (enif_get_int(env, argv[0], &arg) && arg < 2) {
+ ERL_NIF_TERM args[255];
+ int i;
+ args[0] = argv[0];
+ for (i = 1; i < 255; i++)
+ args[i] = enif_make_int(env, i);
+ return enif_schedule_nif(env, "call_dirty_nif_exception", ERL_NIF_DIRTY_JOB_CPU_BOUND,
+ call_dirty_nif_exception, 255, args);
+ } else {
+ return enif_raise_exception(env, argv[0]);
+ }
+ }
+ case 2: {
+ int return_badarg_directly;
+ enif_get_int(env, argv[0], &return_badarg_directly);
+ assert(return_badarg_directly == 1 || return_badarg_directly == 0);
+ if (return_badarg_directly)
+ return enif_make_badarg(env);
+ else {
+ /* ignore return value */ enif_make_badarg(env);
+ return enif_make_atom(env, "ok");
+ }
+ }
+ default:
+ return enif_schedule_nif(env, "call_dirty_nif_exception", ERL_NIF_DIRTY_JOB_CPU_BOUND,
+ call_dirty_nif_exception, argc-1, argv);
+ }
+}
+
+static ERL_NIF_TERM call_dirty_nif_zero_args(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ int i;
+ ERL_NIF_TERM result[1000];
+ ERL_NIF_TERM ok = enif_make_atom(env, "ok");
+ assert(argc == 0);
+ for (i = 0; i < sizeof(result)/sizeof(*result); i++) {
+ result[i] = ok;
+ }
+ return enif_make_list_from_array(env, result, i);
+}
+
+static ERL_NIF_TERM
+dirty_sleeper(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ assert(enif_is_on_dirty_scheduler(env));
+#ifdef __WIN32__
+ Sleep(6000);
+#else
+ sleep(6);
+#endif
+ return enif_make_atom(env, "ok");
+}
+
+static ERL_NIF_TERM dirty_call_while_terminated_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ ErlNifPid self;
+ ERL_NIF_TERM result, self_term;
+ ErlNifPid to;
+ ErlNifEnv* menv;
+ int res;
+
+ if (!enif_get_local_pid(env, argv[0], &to))
+ return enif_make_badarg(env);
+
+ if (!enif_self(env, &self))
+ return enif_make_badarg(env);
+
+ self_term = enif_make_pid(env, &self);
+
+ result = enif_make_tuple2(env, enif_make_atom(env, "dirty_alive"), self_term);
+ menv = enif_alloc_env();
+ res = enif_send(env, &to, menv, result);
+ enif_free_env(menv);
+ if (!res)
+ return enif_make_badarg(env);
+
+ /* Wait until we have been killed */
+ while (enif_is_process_alive(env, &self))
+ ;
+
+ result = enif_make_tuple2(env, enif_make_atom(env, "dirty_dead"), self_term);
+ menv = enif_alloc_env();
+ res = enif_send(env, &to, menv, result);
+ enif_free_env(menv);
+
+#ifdef __WIN32__
+ Sleep(1000);
+#else
+ sleep(1);
+#endif
+
+ return enif_make_atom(env, "ok");
+}
+
+static ERL_NIF_TERM dirty_heap_access_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ ERL_NIF_TERM res = enif_make_list(env, 0);
+ int i;
+ assert(enif_is_on_dirty_scheduler(env));
+ for (i = 0; i < 1000; i++)
+ res = enif_make_list_cell(env, enif_make_copy(env, argv[0]), res);
+
+ return res;
+}
+
+
+static ErlNifFunc nif_funcs[] =
+{
+ {"lib_loaded", 0, lib_loaded},
+ {"call_dirty_nif", 3, call_dirty_nif},
+ {"send_from_dirty_nif", 1, send_from_dirty_nif, ERL_NIF_DIRTY_JOB_CPU_BOUND},
+ {"call_dirty_nif_exception", 1, call_dirty_nif_exception, ERL_NIF_DIRTY_JOB_IO_BOUND},
+ {"call_dirty_nif_zero_args", 0, call_dirty_nif_zero_args, ERL_NIF_DIRTY_JOB_CPU_BOUND},
+ {"dirty_sleeper", 0, dirty_sleeper, ERL_NIF_DIRTY_JOB_IO_BOUND},
+ {"dirty_call_while_terminated_nif", 1, dirty_call_while_terminated_nif, ERL_NIF_DIRTY_JOB_CPU_BOUND},
+ {"dirty_heap_access_nif", 1, dirty_heap_access_nif, ERL_NIF_DIRTY_JOB_CPU_BOUND}
+};
+
+ERL_NIF_INIT(dirty_nif_SUITE,nif_funcs,load,NULL,NULL,NULL)
diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl
index e764071415..a0e9f1bad6 100644
--- a/erts/emulator/test/nif_SUITE.erl
+++ b/erts/emulator/test/nif_SUITE.erl
@@ -38,8 +38,7 @@
is_checks/1,
get_length/1, make_atom/1, make_string/1, reverse_list_test/1,
otp_9828/1,
- otp_9668/1, consume_timeslice/1, dirty_nif/1, dirty_nif_send/1,
- dirty_nif_exception/1, call_dirty_nif_exception/1, nif_schedule/1,
+ otp_9668/1, consume_timeslice/1, nif_schedule/1,
nif_exception/1, call_nif_exception/1,
nif_nan_and_inf/1, nif_atom_too_long/1,
nif_monotonic_time/1, nif_time_offset/1, nif_convert_time_unit/1,
@@ -76,8 +75,7 @@ all() ->
make_string,reverse_list_test,
otp_9828,
otp_9668, consume_timeslice,
- nif_schedule, dirty_nif, dirty_nif_send, dirty_nif_exception,
- nif_exception, nif_nan_and_inf, nif_atom_too_long,
+ nif_schedule, nif_exception, nif_nan_and_inf, nif_atom_too_long,
nif_monotonic_time, nif_time_offset, nif_convert_time_unit,
nif_now_time, nif_cpu_time, nif_unique_integer,
nif_is_process_alive, nif_is_port_alive,
@@ -1542,76 +1540,6 @@ nif_schedule(Config) when is_list(Config) ->
end,
ok.
-dirty_nif(Config) when is_list(Config) ->
- try erlang:system_info(dirty_cpu_schedulers) of
- N when is_integer(N) ->
- ensure_lib_loaded(Config),
- Val1 = 42,
- Val2 = "Erlang",
- Val3 = list_to_binary([Val2, 0]),
- {Val1, Val2, Val3} = call_dirty_nif(Val1, Val2, Val3),
- LargeArray = lists:duplicate(1000, ok),
- LargeArray = call_dirty_nif_zero_args(),
- ok
- catch
- error:badarg ->
- {skipped,"No dirty scheduler support"}
- end.
-
-dirty_nif_send(Config) when is_list(Config) ->
- try erlang:system_info(dirty_cpu_schedulers) of
- N when is_integer(N) ->
- ensure_lib_loaded(Config),
- Parent = self(),
- Pid = spawn_link(fun() ->
- Self = self(),
- {ok, Self} = receive_any(),
- Parent ! {ok, Self}
- end),
- {ok, Pid} = send_from_dirty_nif(Pid),
- {ok, Pid} = receive_any(),
- ok
- catch
- error:badarg ->
- {skipped,"No dirty scheduler support"}
- end.
-
-dirty_nif_exception(Config) when is_list(Config) ->
- try erlang:system_info(dirty_cpu_schedulers) of
- N when is_integer(N) ->
- ensure_lib_loaded(Config),
- try
- %% this checks that the expected exception occurs when the
- %% dirty NIF returns the result of enif_make_badarg
- %% directly
- call_dirty_nif_exception(1),
- ct:fail(expected_badarg)
- catch
- error:badarg ->
- [{?MODULE,call_dirty_nif_exception,[1],_}|_] =
- erlang:get_stacktrace(),
- ok
- end,
- try
- %% this checks that the expected exception occurs when the
- %% dirty NIF calls enif_make_badarg at some point but then
- %% returns a value that isn't an exception
- call_dirty_nif_exception(0),
- ct:fail(expected_badarg)
- catch
- error:badarg ->
- [{?MODULE,call_dirty_nif_exception,[0],_}|_] =
- erlang:get_stacktrace(),
- ok
- end,
- %% this checks that a dirty NIF can raise various terms as
- %% exceptions
- ok = nif_raise_exceptions(call_dirty_nif_exception)
- catch
- error:badarg ->
- {skipped,"No dirty scheduler support"}
- end.
-
nif_exception(Config) when is_list(Config) ->
ensure_lib_loaded(Config),
try
@@ -2088,10 +2016,6 @@ otp_9668_nif(_) -> ?nif_stub.
otp_9828_nif(_) -> ?nif_stub.
consume_timeslice_nif(_,_) -> ?nif_stub.
call_nif_schedule(_,_) -> ?nif_stub.
-call_dirty_nif(_,_,_) -> ?nif_stub.
-send_from_dirty_nif(_) -> ?nif_stub.
-call_dirty_nif_exception(_) -> ?nif_stub.
-call_dirty_nif_zero_args() -> ?nif_stub.
call_nif_exception(_) -> ?nif_stub.
call_nif_nan_or_inf(_) -> ?nif_stub.
call_nif_atom_too_long(_) -> ?nif_stub.
diff --git a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
index 951b6959a8..13846244d4 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
+++ b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
@@ -23,6 +23,9 @@
#include <string.h>
#include <assert.h>
#include <limits.h>
+#ifndef __WIN32__
+#include <unistd.h>
+#endif
#include "nif_mod.h"
@@ -1574,120 +1577,6 @@ static ERL_NIF_TERM call_nif_schedule(ErlNifEnv* env, int argc, const ERL_NIF_TE
return result;
}
-#ifdef ERL_NIF_DIRTY_SCHEDULER_SUPPORT
-
-static int have_dirty_schedulers(void)
-{
- ErlNifSysInfo si;
- enif_system_info(&si, sizeof(si));
- return si.dirty_scheduler_support;
-}
-
-static ERL_NIF_TERM dirty_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
-{
- int n;
- char s[10];
- ErlNifBinary b;
- ERL_NIF_TERM result;
- if (have_dirty_schedulers()) {
- assert(enif_is_on_dirty_scheduler(env));
- }
- assert(argc == 3);
- enif_get_int(env, argv[0], &n);
- enif_get_string(env, argv[1], s, sizeof s, ERL_NIF_LATIN1);
- enif_inspect_binary(env, argv[2], &b);
- return enif_make_tuple3(env,
- enif_make_int(env, n),
- enif_make_string(env, s, ERL_NIF_LATIN1),
- enif_make_binary(env, &b));
-}
-
-static ERL_NIF_TERM call_dirty_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
-{
- int n;
- char s[10];
- ErlNifBinary b;
- assert(!enif_is_on_dirty_scheduler(env));
- if (argc != 3)
- return enif_make_badarg(env);
- if (have_dirty_schedulers()) {
- if (enif_get_int(env, argv[0], &n) &&
- enif_get_string(env, argv[1], s, sizeof s, ERL_NIF_LATIN1) &&
- enif_inspect_binary(env, argv[2], &b))
- return enif_schedule_nif(env, "call_dirty_nif", ERL_NIF_DIRTY_JOB_CPU_BOUND, dirty_nif, argc, argv);
- else
- return enif_make_badarg(env);
- } else {
- return dirty_nif(env, argc, argv);
- }
-}
-
-static ERL_NIF_TERM send_from_dirty_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
-{
- ERL_NIF_TERM result;
- ErlNifPid pid;
- ErlNifEnv* menv;
- int res;
-
- if (!enif_get_local_pid(env, argv[0], &pid))
- return enif_make_badarg(env);
- result = enif_make_tuple2(env, enif_make_atom(env, "ok"), enif_make_pid(env, &pid));
- menv = enif_alloc_env();
- res = enif_send(env, &pid, menv, result);
- enif_free_env(menv);
- if (!res)
- return enif_make_badarg(env);
- else
- return result;
-}
-
-static ERL_NIF_TERM call_dirty_nif_exception(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
-{
- switch (argc) {
- case 1: {
- int arg;
- if (enif_get_int(env, argv[0], &arg) && arg < 2) {
- ERL_NIF_TERM args[255];
- int i;
- args[0] = argv[0];
- for (i = 1; i < 255; i++)
- args[i] = enif_make_int(env, i);
- return enif_schedule_nif(env, "call_dirty_nif_exception", ERL_NIF_DIRTY_JOB_CPU_BOUND,
- call_dirty_nif_exception, 255, args);
- } else {
- return enif_raise_exception(env, argv[0]);
- }
- }
- case 2: {
- int return_badarg_directly;
- enif_get_int(env, argv[0], &return_badarg_directly);
- assert(return_badarg_directly == 1 || return_badarg_directly == 0);
- if (return_badarg_directly)
- return enif_make_badarg(env);
- else {
- /* ignore return value */ enif_make_badarg(env);
- return enif_make_atom(env, "ok");
- }
- }
- default:
- return enif_schedule_nif(env, "call_dirty_nif_exception", ERL_NIF_DIRTY_JOB_CPU_BOUND,
- call_dirty_nif_exception, argc-1, argv);
- }
-}
-
-static ERL_NIF_TERM call_dirty_nif_zero_args(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
-{
- int i;
- ERL_NIF_TERM result[1000];
- ERL_NIF_TERM ok = enif_make_atom(env, "ok");
- assert(argc == 0);
- for (i = 0; i < sizeof(result)/sizeof(*result); i++) {
- result[i] = ok;
- }
- return enif_make_list_from_array(env, result, i);
-}
-#endif
-
/*
* If argv[0] is the integer 0, call enif_make_badarg, but don't return its
* return value. Instead, return ok. Result should still be a badarg
@@ -2179,12 +2068,6 @@ static ErlNifFunc nif_funcs[] =
{"otp_9828_nif", 1, otp_9828_nif},
{"consume_timeslice_nif", 2, consume_timeslice_nif},
{"call_nif_schedule", 2, call_nif_schedule},
-#ifdef ERL_NIF_DIRTY_SCHEDULER_SUPPORT
- {"call_dirty_nif", 3, call_dirty_nif},
- {"send_from_dirty_nif", 1, send_from_dirty_nif, ERL_NIF_DIRTY_JOB_CPU_BOUND},
- {"call_dirty_nif_exception", 1, call_dirty_nif_exception, ERL_NIF_DIRTY_JOB_IO_BOUND},
- {"call_dirty_nif_zero_args", 0, call_dirty_nif_zero_args, ERL_NIF_DIRTY_JOB_CPU_BOUND},
-#endif
{"call_nif_exception", 1, call_nif_exception},
{"call_nif_nan_or_inf", 1, call_nif_nan_or_inf},
{"call_nif_atom_too_long", 1, call_nif_atom_too_long},
diff --git a/erts/emulator/test/scheduler_SUITE.erl b/erts/emulator/test/scheduler_SUITE.erl
index 6b49b68ec8..f18d79d770 100644
--- a/erts/emulator/test/scheduler_SUITE.erl
+++ b/erts/emulator/test/scheduler_SUITE.erl
@@ -57,7 +57,6 @@
scheduler_suspend_basic/1,
scheduler_suspend/1,
dirty_scheduler_threads/1,
- dirty_scheduler_exit/1,
reader_groups/1]).
suite() ->
@@ -72,7 +71,7 @@ all() ->
bound_process,
{group, scheduler_bind}, scheduler_threads,
scheduler_suspend_basic, scheduler_suspend,
- dirty_scheduler_threads, dirty_scheduler_exit,
+ dirty_scheduler_threads,
reader_groups].
groups() ->
@@ -1162,53 +1161,6 @@ get_dsstate(Config, Cmd) ->
stop_node(Node),
{DSCPU, DSCPUOnln, DSIO}.
-dirty_scheduler_exit(Config) when is_list(Config) ->
- try
- erlang:system_info(dirty_cpu_schedulers),
- dirty_scheduler_exit_test(Config)
- catch
- error:badarg ->
- {skipped, "No dirty scheduler support"}
- end.
-
-dirty_scheduler_exit_test(Config) ->
- {ok, Node} = start_node(Config, "+SDio 1"),
- [ok] = mcall(Node,
- [fun() ->
- Path = proplists:get_value(data_dir, Config),
- Lib = atom_to_list(?MODULE),
- ok = erlang:load_nif(filename:join(Path,Lib), []),
- ok = test_dirty_scheduler_exit()
- end]),
- stop_node(Node),
- ok.
-
-test_dirty_scheduler_exit() ->
- process_flag(trap_exit,true),
- test_dse(10,[]).
-test_dse(0,Pids) ->
- timer:sleep(100),
- kill_dse(Pids,[]);
-test_dse(N,Pids) ->
- Pid = spawn_link(fun dirty_sleeper/0),
- test_dse(N-1,[Pid|Pids]).
-kill_dse([],Killed) ->
- wait_dse(Killed);
-kill_dse([Pid|Pids],AlreadyKilled) ->
- exit(Pid,kill),
- kill_dse(Pids,[Pid|AlreadyKilled]).
-wait_dse([]) ->
- ok;
-wait_dse([Pid|Pids]) ->
- receive
- {'EXIT',Pid,killed} ->
- ok
- end,
- wait_dse(Pids).
-
-dirty_sleeper() ->
- erlang:nif_error({error,?MODULE}).
-
scheduler_suspend_basic(Config) when is_list(Config) ->
case erlang:system_info(multi_scheduling) of
disabled ->
diff --git a/erts/emulator/test/scheduler_SUITE_data/Makefile.src b/erts/emulator/test/scheduler_SUITE_data/Makefile.src
deleted file mode 100644
index 859112cf19..0000000000
--- a/erts/emulator/test/scheduler_SUITE_data/Makefile.src
+++ /dev/null
@@ -1,8 +0,0 @@
-
-SCHEDULER_LIBS = scheduler_SUITE@dll@
-
-all: $(SCHEDULER_LIBS)
-
-@SHLIB_RULES@
-
-$(SCHEDULER_LIBS): scheduler_SUITE.c
diff --git a/erts/emulator/test/scheduler_SUITE_data/scheduler_SUITE.c b/erts/emulator/test/scheduler_SUITE_data/scheduler_SUITE.c
deleted file mode 100644
index ab4863337f..0000000000
--- a/erts/emulator/test/scheduler_SUITE_data/scheduler_SUITE.c
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef __WIN32__
-#include <unistd.h>
-#endif
-#include "erl_nif.h"
-
-static int
-load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info)
-{
- ErlNifSysInfo sys_info;
- enif_system_info(&sys_info, sizeof(ErlNifSysInfo));
- if (!sys_info.smp_support || !sys_info.dirty_scheduler_support)
- return 1;
- return 0;
-}
-
-static ERL_NIF_TERM
-dirty_sleeper(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
-{
-#ifdef ERL_NIF_DIRTY_SCHEDULER_SUPPORT
-#ifdef __WIN32__
- Sleep(3000);
-#else
- sleep(3);
-#endif
-#endif
- return enif_make_atom(env, "ok");
-}
-
-static ErlNifFunc funcs[] = {
-#ifdef ERL_NIF_DIRTY_SCHEDULER_SUPPORT
- {"dirty_sleeper", 0, dirty_sleeper, ERL_NIF_DIRTY_JOB_IO_BOUND}
-#else
- {"dirty_sleeper", 0, dirty_sleeper, 0}
-#endif
-};
-
-ERL_NIF_INIT(scheduler_SUITE, funcs, &load, NULL, NULL, NULL);
diff --git a/erts/emulator/test/trace_bif_SUITE.erl b/erts/emulator/test/trace_bif_SUITE.erl
index 8c3ffccc45..491b37ae46 100644
--- a/erts/emulator/test/trace_bif_SUITE.erl
+++ b/erts/emulator/test/trace_bif_SUITE.erl
@@ -232,6 +232,7 @@ do_trace_bif_return(TsType, TsFlags) ->
{?MODULE, bif_process,0}},
Ts11, TsType),
check_ts(TsType, Ts12, make_ts(TsType)),
+ erlang:trace_pattern({erlang,'_','_'}, false, [local]),
ok.
diff --git a/erts/emulator/test/tracer_SUITE.erl b/erts/emulator/test/tracer_SUITE.erl
index de44d6656a..20fb7e475e 100644
--- a/erts/emulator/test/tracer_SUITE.erl
+++ b/erts/emulator/test/tracer_SUITE.erl
@@ -44,6 +44,8 @@ groups() ->
gc_start, gc_end]}].
init_per_suite(Config) ->
+ erlang:trace_pattern({'_','_','_'}, false, [local]),
+ erlang:trace_pattern({'_','_','_'}, false, []),
purge(),
Config.
@@ -119,23 +121,24 @@ unload(_Config) ->
end,
1 = erlang:trace(Pid, true, [{tracer, tracer_test,
- {#{ call => trace}, self(), []}},
+ {#{ call => trace }, self(), []}},
call]),
1 = erlang:trace_pattern({?MODULE, all, 0}, [], []),
Tc(1),
- receive _ -> ok after 0 -> ct:fail(timeout) end,
+ receive _M -> ok after 0 -> ct:fail(timeout) end,
+ receive M0 -> ct:fail({unexpected_message0, M0}) after 0 -> ok end,
code:purge(tracer_test),
code:delete(tracer_test),
Tc(1),
- receive M1 -> ct:fail({unexpected_message, M1}) after 0 -> ok end,
+ receive M1 -> ct:fail({unexpected_message1, M1}) after 0 -> ok end,
code:purge(tracer_test),
Tc(1),
- receive M2 -> ct:fail({unexpected_message, M2}) after 0 -> ok end,
+ receive M2 -> ct:fail({unexpected_message2, M2}) after 0 -> ok end,
ok.
@@ -167,13 +170,19 @@ reload(_Config) ->
false = code:purge(tracer_test),
true = code:delete(tracer_test),
- false = code:purge(tracer_test)
+ false = code:purge(tracer_test),
+ timer:sleep(10)
end || _ <- lists:seq(1,15)],
ok.
reload_loop() ->
?MODULE:all(),
+ ?MODULE:all(),
+ ?MODULE:all(),
+ ?MODULE:all(),
+ ?MODULE:all(),
+ timer:sleep(1),
reload_loop().
invalid_tracers(_Config) ->
@@ -214,7 +223,7 @@ send(_Config) ->
Expect = fun(Pid, State, EOpts) ->
receive
Msg ->
- {Pid, send, State, Pid, ok, Self, Opts} = Msg,
+ {send, State, Pid, ok, Self, Opts} = Msg,
check_opts(EOpts, Opts)
end
end,
@@ -230,7 +239,7 @@ recv(_Config) ->
Expect = fun(Pid, State, EOpts) ->
receive
Msg ->
- {undefined, 'receive', State, Pid, ok, undefined, Opts} = Msg,
+ {'receive', State, Pid, ok, undefined, Opts} = Msg,
check_opts(EOpts, Opts)
end
end,
@@ -247,14 +256,14 @@ spawn(_Config) ->
fun(Pid, State, EOpts) ->
receive
Msg ->
- {Pid, spawn, State, Pid, NewPid,
+ {spawn, State, Pid, NewPid,
{lists,seq,[1,10]}, Opts} = Msg,
check_opts(EOpts, Opts),
true = is_pid(NewPid) andalso NewPid /= Pid
end
end,
- test(spawn, procs, Tc, Expect, true).
+ test(spawn, procs, Tc, Expect, false).
exit(_Config) ->
Tc = fun(Pid) ->
@@ -265,7 +274,7 @@ exit(_Config) ->
fun(Pid, State, EOpts) ->
receive
Msg ->
- {Pid, exit, State, Pid, normal, undefined, Opts} = Msg,
+ {exit, State, Pid, normal, undefined, Opts} = Msg,
check_opts(EOpts, Opts)
end
end,
@@ -286,13 +295,13 @@ link(_Config) ->
fun(Pid, State, EOpts) ->
receive
Msg ->
- {Pid, link, State, Pid, NewPid, undefined, Opts} = Msg,
+ {link, State, Pid, NewPid, undefined, Opts} = Msg,
check_opts(EOpts, Opts),
true = is_pid(NewPid) andalso NewPid /= Pid
end
end,
- test(link, procs, Tc, Expect, true).
+ test(link, procs, Tc, Expect, false).
unlink(_Config) ->
@@ -309,13 +318,13 @@ unlink(_Config) ->
fun(Pid, State, EOpts) ->
receive
Msg ->
- {Pid, unlink, State, Pid, NewPid, undefined, Opts} = Msg,
+ {unlink, State, Pid, NewPid, undefined, Opts} = Msg,
check_opts(EOpts, Opts),
true = is_pid(NewPid) andalso NewPid /= Pid
end
end,
- test(unlink, procs, Tc, Expect, true).
+ test(unlink, procs, Tc, Expect, false).
getting_linked(_Config) ->
@@ -331,7 +340,7 @@ getting_linked(_Config) ->
fun(Pid, State, EOpts) ->
receive
Msg ->
- {NewPid, getting_linked, State, Pid, NewPid, undefined, Opts} = Msg,
+ {getting_linked, State, Pid, NewPid, undefined, Opts} = Msg,
check_opts(EOpts, Opts),
true = is_pid(NewPid) andalso NewPid /= Pid
end
@@ -355,7 +364,7 @@ getting_unlinked(_Config) ->
fun(Pid, State, EOpts) ->
receive
Msg ->
- {NewPid, getting_unlinked, State, Pid, NewPid, undefined, Opts} = Msg,
+ {getting_unlinked, State, Pid, NewPid, undefined, Opts} = Msg,
check_opts(EOpts, Opts),
true = is_pid(NewPid) andalso NewPid /= Pid
end
@@ -377,12 +386,12 @@ register(_Config) ->
fun(Pid, State, EOpts) ->
receive
Msg ->
- {Pid, register, State, Pid, ?MODULE, undefined, Opts} = Msg,
+ {register, State, Pid, ?MODULE, undefined, Opts} = Msg,
check_opts(EOpts, Opts)
end
end,
- test(register, procs, Tc, Expect, true).
+ test(register, procs, Tc, Expect, false).
unregister(_Config) ->
@@ -398,18 +407,18 @@ unregister(_Config) ->
fun(Pid, State, EOpts) ->
receive
Msg ->
- {Pid, unregister, State, Pid, ?MODULE, undefined, Opts} = Msg,
+ {unregister, State, Pid, ?MODULE, undefined, Opts} = Msg,
check_opts(EOpts, Opts)
end
end,
- test(unregister, procs, Tc, Expect, true).
+ test(unregister, procs, Tc, Expect, false).
in(_Config) ->
Tc = fun(Pid) ->
Self = self(),
- Pid ! fun() -> receive after 1 -> Self ! ok end end,
+ Pid ! fun() -> receive after 10 -> Self ! ok end end,
receive ok -> ok end
end,
@@ -418,7 +427,7 @@ in(_Config) ->
N = (fun F(N) ->
receive
Msg ->
- {Pid, in, State, Pid, _,
+ {in, State, Pid, _,
undefined, Opts} = Msg,
check_opts(EOpts, Opts),
F(N+1)
@@ -428,7 +437,7 @@ in(_Config) ->
true = N > 0
end,
- test(in, running, Tc, Expect, true).
+ test(in, running, Tc, Expect, false).
out(_Config) ->
Tc = fun(Pid) ->
@@ -443,7 +452,7 @@ out(_Config) ->
N = (fun F(N) ->
receive
Msg ->
- {Pid, out, State, Pid, _,
+ {out, State, Pid, _,
undefined, Opts} = Msg,
check_opts(EOpts, Opts),
F(N+1)
@@ -453,7 +462,7 @@ out(_Config) ->
true = N > 0
end,
- test(out, running, Tc, Expect, true, true).
+ test(out, running, Tc, Expect, false, true).
gc_start(_Config) ->
@@ -468,12 +477,12 @@ gc_start(_Config) ->
fun(Pid, State, EOpts) ->
receive
Msg ->
- {Pid, gc_major_start, State, Pid, _, undefined, Opts} = Msg,
+ {gc_major_start, State, Pid, _, undefined, Opts} = Msg,
check_opts(EOpts, Opts)
end
end,
- test(gc_major_start, garbage_collection, Tc, Expect, true).
+ test(gc_major_start, garbage_collection, Tc, Expect, false).
gc_end(_Config) ->
@@ -488,20 +497,20 @@ gc_end(_Config) ->
fun(Pid, State, EOpts) ->
receive
Msg ->
- {Pid, gc_major_end, State, Pid, _, undefined, Opts} = Msg,
+ {gc_major_end, State, Pid, _, undefined, Opts} = Msg,
check_opts(EOpts, Opts)
end
end,
- test(gc_major_end, garbage_collection, Tc, Expect, true).
+ test(gc_major_end, garbage_collection, Tc, Expect, false).
test(Event, Tc, Expect) ->
- test(Event, Tc, Expect, true).
+ test(Event, Tc, Expect, false).
test(Event, Tc, Expect, Removes) ->
test(Event, Event, Tc, Expect, Removes).
test(Event, TraceFlag, Tc, Expect, Removes) ->
test(Event, TraceFlag, Tc, Expect, Removes, false).
-test(Event, TraceFlag, Tc, Expect, Removes, Dies) ->
+test(Event, TraceFlag, Tc, Expect, _Removes, Dies) ->
ComplexState = {fun() -> ok end, <<0:(128*8)>>},
Opts = #{ timestamp => undefined,
@@ -557,25 +566,6 @@ test(Event, TraceFlag, Tc, Expect, Removes, Dies) ->
ok
end,
- %% Test that remove works
- Pid3 = start_tracee(),
- State3 = {#{ Event => remove }, self(), ComplexState},
- 1 = erlang:trace(Pid3, true, [TraceFlag, {tracer, tracer_test, State3}]),
- Tc(Pid3),
- ok = trace_delivered(Pid3),
- receive M3 -> ct:fail({unexpected, M3}) after 0 -> ok end,
- if not Dies ->
- if Removes ->
- {flags, []} = erlang:trace_info(Pid3, flags),
- {tracer, []} = erlang:trace_info(Pid3, tracer);
- true ->
- {flags, [TraceFlag]} = erlang:trace_info(Pid3, flags),
- {tracer, {tracer_test, State3}} = erlang:trace_info(Pid3, tracer)
- end,
- erlang:trace(Pid3, false, [TraceFlag]);
- true ->
- ok
- end,
ok.
check_opts(#{ scheduler_id := number } = E, #{ scheduler_id := N } = O)
diff --git a/erts/emulator/test/tracer_SUITE_data/tracer_test.c b/erts/emulator/test/tracer_SUITE_data/tracer_test.c
index 8b4be1345d..908f35da9c 100644
--- a/erts/emulator/test/tracer_SUITE_data/tracer_test.c
+++ b/erts/emulator/test/tracer_SUITE_data/tracer_test.c
@@ -104,16 +104,10 @@ static ERL_NIF_TERM trace(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
enif_get_tuple(env, argv[1], &state_arity, &state_tuple);
- tuple = enif_alloc(sizeof(ERL_NIF_TERM)*(argc+1));
- memcpy(tuple+1,argv,sizeof(ERL_NIF_TERM)*argc);
+ tuple = enif_alloc(sizeof(ERL_NIF_TERM)*(argc));
+ memcpy(tuple,argv,sizeof(ERL_NIF_TERM)*argc);
- if (enif_self(env, &self)) {
- tuple[0] = enif_make_pid(env, &self);
- } else {
- tuple[0] = enif_make_atom(env, "undefined");
- }
-
- msg = enif_make_tuple_from_array(env, tuple, argc + 1);
+ msg = enif_make_tuple_from_array(env, tuple, argc);
enif_get_local_pid(env, state_tuple[1], &to);
enif_send(env, &to, NULL, msg);
enif_free(tuple);