aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/test/dump_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/test/dump_SUITE.erl')
-rw-r--r--erts/emulator/test/dump_SUITE.erl138
1 files changed, 122 insertions, 16 deletions
diff --git a/erts/emulator/test/dump_SUITE.erl b/erts/emulator/test/dump_SUITE.erl
index d0237b78cc..6133b82756 100644
--- a/erts/emulator/test/dump_SUITE.erl
+++ b/erts/emulator/test/dump_SUITE.erl
@@ -24,7 +24,7 @@
-export([all/0, suite/0, init_per_testcase/2, end_per_testcase/2]).
--export([signal_abort/1]).
+-export([signal_abort/1, exiting_dump/1, free_dump/1]).
-export([load/0]).
@@ -35,7 +35,7 @@ suite() ->
{timetrap, {minutes, 2}}].
all() ->
- [signal_abort].
+ [signal_abort, exiting_dump, free_dump].
init_per_testcase(signal_abort, Config) ->
SO = erlang:system_info(schedulers_online),
@@ -48,7 +48,10 @@ init_per_testcase(signal_abort, Config) ->
{skip, "the platform does not support scheduler dump"};
Dump ->
Config
- end.
+ end;
+init_per_testcase(_, Config) ->
+ Config.
+
end_per_testcase(_, Config) ->
Config.
@@ -65,12 +68,14 @@ signal_abort(Config) ->
{ok, Node} = start_node(Config),
- _P1 = spawn(Node, ?MODULE, load, []),
- _P2 = spawn(Node, ?MODULE, load, []),
- _P3 = spawn(Node, ?MODULE, load, []),
- _P4 = spawn(Node, ?MODULE, load, []),
- _P5 = spawn(Node, ?MODULE, load, []),
- _P6 = spawn(Node, ?MODULE, load, []),
+ SO = rpc:call(Node, erlang, system_info, [schedulers_online]),
+
+ _P1 = spawn_opt(Node, ?MODULE, load, [], [{scheduler, (0 rem SO) + 1}]),
+ _P2 = spawn_opt(Node, ?MODULE, load, [], [{scheduler, (1 rem SO) + 1}]),
+ _P3 = spawn_opt(Node, ?MODULE, load, [], [{scheduler, (2 rem SO) + 1}]),
+ _P4 = spawn_opt(Node, ?MODULE, load, [], [{scheduler, (3 rem SO) + 1}]),
+ _P5 = spawn_opt(Node, ?MODULE, load, [], [{scheduler, (4 rem SO) + 1}]),
+ _P6 = spawn_opt(Node, ?MODULE, load, [], [{scheduler, (5 rem SO) + 1}]),
timer:sleep(500),
@@ -79,8 +84,6 @@ signal_abort(Config) ->
{ok, Bin} = get_dump_when_done(Dump),
- ct:log("~s",[Bin]),
-
{match, Matches} = re:run(Bin,"Current Process: <",[global]),
ct:log("Found ~p",[Matches]),
@@ -91,6 +94,111 @@ signal_abort(Config) ->
ok.
+load() ->
+ lists:seq(1,10000),
+ load().
+
+
+%% Test that crash dumping when a process is in the state EXITING works
+exiting_dump(Config) when is_list(Config) ->
+ Dump = filename:join(proplists:get_value(priv_dir, Config),"signal_abort.dump"),
+
+ {ok, Node} = start_node(Config),
+
+ Self = self(),
+
+ Pid = spawn_link(Node,
+ fun() ->
+ [begin
+ T = ets:new(hej,[]),
+ [ets:insert(T,{I,I}) || I <- lists:seq(1,1000)]
+ end || _ <- lists:seq(1,1000)],
+ Self ! ready,
+ receive ok -> ok end
+ end),
+
+ true = rpc:call(Node, os, putenv, ["ERL_CRASH_DUMP",Dump]),
+
+ receive ready -> unlink(Pid), Pid ! ok end,
+
+ rpc:call(Node, erlang, halt, ["dump"]),
+
+ {ok, Bin} = get_dump_when_done(Dump),
+
+ {match, Matches} = re:run(Bin,"^State: Exiting", [global, multiline]),
+
+ ct:log("Found ~p",[Matches]),
+
+ true = length(Matches) == 1,
+
+ file:delete(Dump),
+
+ ok.
+
+%% Test that crash dumping when a process is in the state FREE works
+free_dump(Config) when is_list(Config) ->
+ Dump = filename:join(proplists:get_value(priv_dir, Config),"signal_abort.dump"),
+
+ {ok, NodeA} = start_node(Config),
+ {ok, NodeB} = start_node(Config),
+
+ Self = self(),
+
+ PidA = spawn_link(
+ NodeA,
+ fun() ->
+ Self ! ready,
+ Reason = lists:duplicate(1000000,100),
+ receive
+ ok ->
+ spawn(fun() ->
+ erlang:system_monitor(self(), [busy_dist_port]),
+ timer:sleep(5),
+ receive
+ M ->
+ io:format("~p",[M])
+%% We may want to add this timeout here in-case no busy condition is triggered
+%% after 60 * 1000 ->
+%% io:format("Timeout")
+ end,
+ erlang:halt("dump")
+ end),
+ exit(Reason)
+ end
+ end),
+
+ PidB = spawn_link(NodeB,
+ fun() ->
+ [erlang:monitor(process, PidA) || _ <- lists:seq(1,10000)],
+ Self ! done,
+ receive _ -> ok end
+ end),
+
+ receive done -> ok end,
+ true = rpc:call(NodeA, os, putenv, ["ERL_CRASH_DUMP",Dump]),
+ %% Make the node busy towards NodeB for 10 seconds.
+ BusyPid = rpc:call(NodeA, distribution_SUITE, make_busy, [NodeB,10000]),
+ ct:pal("~p",[BusyPid]),
+
+ receive ready -> unlink(PidA), PidA ! ok end,
+
+ {ok, Bin} = get_dump_when_done(Dump),
+
+ {match, Matches} = re:run(Bin,"^State: Non Existing", [global, multiline]),
+
+ ct:log("Found ~p",[Matches]),
+
+ true = length(Matches) == 1,
+
+ file:delete(Dump),
+
+ unlink(PidB),
+
+ rpc:call(NodeB, erlang, halt, [0]),
+
+ ok.
+
+
get_dump_when_done(Dump) ->
case file:read_file_info(Dump) of
{ok, #file_info{ size = Sz }} ->
@@ -104,15 +212,13 @@ get_dump_when_done(Dump, Sz) ->
timer:sleep(1000),
case file:read_file_info(Dump) of
{ok, #file_info{ size = Sz }} ->
- file:read_file(Dump);
+ {ok, Bin} = file:read_file(Dump),
+ ct:log("~s",[Bin]),
+ {ok, Bin};
{ok, #file_info{ size = NewSz }} ->
get_dump_when_done(Dump, NewSz)
end.
-load() ->
- lists:seq(1,10000),
- load().
-
start_node(Config) when is_list(Config) ->
Pa = filename:dirname(code:which(?MODULE)),
Name = list_to_atom(atom_to_list(?MODULE)