aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2019-06-19 16:25:49 +0200
committerSverker Eriksson <[email protected]>2019-06-19 16:27:12 +0200
commit7d1058ed7de3c04055feb62108a78e29c33c5ddb (patch)
tree42801fc1314ff3c99d2fdec790cebb067e7c7b86
parent7fe7fa3dde556b5b92522f8279d465bb52baf1f6 (diff)
downloadotp-7d1058ed7de3c04055feb62108a78e29c33c5ddb.tar.gz
otp-7d1058ed7de3c04055feb62108a78e29c33c5ddb.tar.bz2
otp-7d1058ed7de3c04055feb62108a78e29c33c5ddb.zip
Fix fatal bug in erts_proc_sig_signal_size
called by erlang:process_info(memory) erlang:system_info(procs) crash dump break menu Will crash VM if process has a pending monitor DOWN signal in its queue.
-rw-r--r--erts/emulator/beam/erl_proc_sig_queue.c1
-rw-r--r--erts/emulator/test/system_info_SUITE.erl53
2 files changed, 54 insertions, 0 deletions
diff --git a/erts/emulator/beam/erl_proc_sig_queue.c b/erts/emulator/beam/erl_proc_sig_queue.c
index d475a0a634..60060cb092 100644
--- a/erts/emulator/beam/erl_proc_sig_queue.c
+++ b/erts/emulator/beam/erl_proc_sig_queue.c
@@ -3865,6 +3865,7 @@ erts_proc_sig_signal_size(ErtsSignal *sig)
case ERTS_MON_TYPE_DIST_PROC:
case ERTS_MON_TYPE_NODE:
size = erts_monitor_size((ErtsMonitor *) sig);
+ break;
default:
ERTS_INTERNAL_ERROR("Unexpected sig type");
break;
diff --git a/erts/emulator/test/system_info_SUITE.erl b/erts/emulator/test/system_info_SUITE.erl
index 4e663fed7f..da2c0ef8ac 100644
--- a/erts/emulator/test/system_info_SUITE.erl
+++ b/erts/emulator/test/system_info_SUITE.erl
@@ -37,10 +37,13 @@
-export([process_count/1, system_version/1, misc_smoke_tests/1,
heap_size/1, wordsize/1, memory/1, ets_limit/1, atom_limit/1,
+ procs_bug/1,
ets_count/1, atom_count/1, system_logger/1]).
-export([init/1, handle_event/2, handle_call/2]).
+-export([init_per_testcase/2, end_per_testcase/2]).
+
suite() ->
[{ct_hooks,[ts_install_cth]},
{timetrap, {minutes, 2}}].
@@ -48,8 +51,20 @@ suite() ->
all() ->
[process_count, system_version, misc_smoke_tests,
ets_count, heap_size, wordsize, memory, ets_limit, atom_limit, atom_count,
+ procs_bug,
system_logger].
+
+init_per_testcase(procs_bug, Config) ->
+ procs_bug(init_per_testcase, Config);
+init_per_testcase(_, Config) ->
+ Config.
+
+end_per_testcase(procs_bug, Config) ->
+ procs_bug(end_per_testcase, Config);
+end_per_testcase(_, _) ->
+ ok.
+
%%%
%%% The test cases -------------------------------------------------------------
%%%
@@ -649,3 +664,41 @@ handle_call(Msg, State) ->
handle_event(Event, State) ->
State ! {report_handler, Event},
{ok, State}.
+
+
+%% OTP-15909: Provoke bug that would cause VM crash
+%% if doing system_info(procs) when process have queued exit/down signals.
+procs_bug(init_per_testcase, Config) ->
+ %% Use single scheduler and process prio to starve monitoring processes
+ %% from handling their received DOWN signals.
+ OldSchedOnline = erlang:system_flag(schedulers_online,1),
+ [{schedulers_online, OldSchedOnline} | Config];
+procs_bug(end_per_testcase, Config) ->
+ erlang:system_flag(schedulers_online,
+ proplists:get_value(schedulers_online, Config)),
+ ok.
+
+procs_bug(Config) when is_list(Config) ->
+ {Monee,_} = spawn_opt(fun () -> receive die -> ok end end,
+ [monitor,{priority,max}]),
+ Papa = self(),
+ Pids = [begin
+ P = spawn_opt(fun () ->
+ erlang:monitor(process, Monee),
+ Papa ! {self(),ready},
+ receive "nada" -> no end
+ end,
+ [link, {priority,normal}]),
+ {P, ready} = receive M -> M end,
+ P
+ end
+ || _ <- lists:seq(1,10)],
+ process_flag(priority,high),
+ Monee ! die,
+ {'DOWN',_,process,Monee,normal} = receive M -> M end,
+
+ %% This call did crash VM as Pids have pending DOWN signals.
+ erlang:system_info(procs),
+ process_flag(priority,normal),
+ [begin unlink(P), exit(P, kill) end || P <- Pids],
+ ok.