summaryrefslogtreecommitdiff
path: root/erts/emulator/test/process_SUITE.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <bjorn@erlang.org>2023-02-17 12:39:00 +0100
committerBjörn Gustavsson <bjorn@erlang.org>2023-02-17 12:39:00 +0100
commit27a4de60666b786ecb3e11644c16626b2ffdd9ae (patch)
tree20858374a4072d3b65039b1191d8239cd697966c /erts/emulator/test/process_SUITE.erl
parent265f8d15ec4f94262908d1b5a9c7ca69427367aa (diff)
parentd60625283288c09a24631ad8c3b923c605a0c5c5 (diff)
downloaderlang-27a4de60666b786ecb3e11644c16626b2ffdd9ae.tar.gz
Merge branch 'bjorn/erts/max_heap_size/25/OTP-18463' into maint
* bjorn/erts/max_heap_size/25/OTP-18463: Exit process immediately when the max heap size is exceeded
Diffstat (limited to 'erts/emulator/test/process_SUITE.erl')
-rw-r--r--erts/emulator/test/process_SUITE.erl107
1 files changed, 107 insertions, 0 deletions
diff --git a/erts/emulator/test/process_SUITE.erl b/erts/emulator/test/process_SUITE.erl
index 9ab2366c58..89d37d4f3e 100644
--- a/erts/emulator/test/process_SUITE.erl
+++ b/erts/emulator/test/process_SUITE.erl
@@ -60,6 +60,7 @@
process_flag_fullsweep_after/1, process_flag_heap_size/1,
command_line_max_heap_size/1,
spawn_opt_heap_size/1, spawn_opt_max_heap_size/1,
+ more_spawn_opt_max_heap_size/1,
processes_large_tab/1, processes_default_tab/1, processes_small_tab/1,
processes_this_tab/1, processes_apply_trap/1,
processes_last_call_trap/1, processes_gc_trap/1,
@@ -118,6 +119,7 @@ all() ->
process_flag_fullsweep_after, process_flag_heap_size,
command_line_max_heap_size,
spawn_opt_heap_size, spawn_opt_max_heap_size,
+ more_spawn_opt_max_heap_size,
spawn_huge_arglist,
otp_6237,
{group, spawn_request},
@@ -2713,6 +2715,111 @@ flush() ->
ok
end.
+%% Make sure that when maximum allowed heap size is exceeded, the
+%% process will actually terminate.
+%%
+%% Despite the timetrap and limit of number of iterations, bugs
+%% provoked by the test case can cause the runtime system to hang in
+%% this test case.
+more_spawn_opt_max_heap_size(_Config) ->
+ ct:timetrap({minutes,1}),
+ Funs = [fun build_and_bif/0,
+ fun build_bin_and_bif/0,
+ fun build_and_recv_timeout/0,
+ fun build_and_recv_msg/0,
+ fun bif_and_recv_timeout/0,
+ fun bif_and_recv_msg/0
+ ],
+ _ = [begin
+ {Pid,Ref} = spawn_opt(F, [{max_heap_size,
+ #{size => 233, kill => true,
+ error_logger => false}},
+ monitor]),
+ io:format("~p ~p\n", [Pid,F]),
+ receive
+ {'DOWN',Ref,process,Pid,Reason} ->
+ killed = Reason
+ end
+ end || F <- Funs],
+ ok.
+
+%% This number should be greater than the default heap size.
+-define(MANY_ITERATIONS, 10_000).
+
+build_and_bif() ->
+ build_and_bif(?MANY_ITERATIONS, []).
+
+build_and_bif(0, Acc0) ->
+ Acc0;
+build_and_bif(N, Acc0) ->
+ Acc = [0|Acc0],
+ _ = erlang:crc32(Acc),
+ build_and_bif(N-1, Acc).
+
+build_bin_and_bif() ->
+ build_bin_and_bif(?MANY_ITERATIONS, <<>>).
+
+build_bin_and_bif(0, Acc0) ->
+ Acc0;
+build_bin_and_bif(N, Acc0) ->
+ Acc = <<0, Acc0/binary>>,
+ _ = erlang:crc32(Acc),
+ build_bin_and_bif(N-1, Acc).
+
+build_and_recv_timeout() ->
+ build_and_recv_timeout(?MANY_ITERATIONS, []).
+
+build_and_recv_timeout(0, Acc0) ->
+ Acc0;
+build_and_recv_timeout(N, Acc0) ->
+ Acc = [0|Acc0],
+ receive
+ after 1 ->
+ ok
+ end,
+ build_and_recv_timeout(N-1, Acc).
+
+build_and_recv_msg() ->
+ build_and_recv_msg(?MANY_ITERATIONS, []).
+
+build_and_recv_msg(0, Acc0) ->
+ Acc0;
+build_and_recv_msg(N, Acc0) ->
+ Acc = [0|Acc0],
+ receive
+ _ ->
+ ok
+ after 0 ->
+ ok
+ end,
+ build_and_recv_msg(N-1, Acc).
+
+bif_and_recv_timeout() ->
+ Bin = <<0:?MANY_ITERATIONS/unit:8>>,
+ bif_and_recv_timeout(Bin).
+
+bif_and_recv_timeout(Bin) ->
+ List = binary_to_list(Bin),
+ receive
+ after 1 ->
+ ok
+ end,
+ List.
+
+bif_and_recv_msg() ->
+ Bin = <<0:?MANY_ITERATIONS/unit:8>>,
+ bif_and_recv_msg(Bin).
+
+bif_and_recv_msg(Bin) ->
+ List = binary_to_list(Bin),
+ receive
+ _ ->
+ ok
+ after 0 ->
+ ok
+ end,
+ List.
+
%% error_logger report handler proxy
init(Pid) ->
{ok, Pid}.