diff options
author | Björn Gustavsson <bjorn@erlang.org> | 2023-02-17 12:39:00 +0100 |
---|---|---|
committer | Björn Gustavsson <bjorn@erlang.org> | 2023-02-17 12:39:00 +0100 |
commit | 27a4de60666b786ecb3e11644c16626b2ffdd9ae (patch) | |
tree | 20858374a4072d3b65039b1191d8239cd697966c /erts/emulator/test/process_SUITE.erl | |
parent | 265f8d15ec4f94262908d1b5a9c7ca69427367aa (diff) | |
parent | d60625283288c09a24631ad8c3b923c605a0c5c5 (diff) | |
download | erlang-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.erl | 107 |
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}. |