From ec91a1fabe82e063b970b64574c7beafe99c148a Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Mon, 26 Aug 2024 10:28:40 +0200 Subject: [PATCH] kernel: Don't load group history when in noshell mode Loading of group_history synchornizes with kernel_sup in order to use disk_log. Doing that when in the user process can lead to a deadlock if logger (or anything really) tries to write to standard out at the same time. Normally the deadlock will solve itself when the kernel application is started, but if it should fail to start for some reason user is terminated before it can print anything and logger will print the log messages to standard error instead. --- lib/kernel/src/group.erl | 11 ++++++++++- lib/kernel/test/init_SUITE.erl | 16 ++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/lib/kernel/src/group.erl b/lib/kernel/src/group.erl index 1792ffe2fb25..5d40ca9a7d20 100644 --- a/lib/kernel/src/group.erl +++ b/lib/kernel/src/group.erl @@ -46,7 +46,6 @@ server(Ancestors, Drv, Shell, Options) -> process_flag(trap_exit, true), _ = [put('$ancestors', Ancestors) || Shell =/= {}], edlin:init(), - put(line_buffer, proplists:get_value(line_buffer, Options, group_history:load())), put(read_mode, list), put(user_drv, Drv), ExpandFun = normalize_expand_fun(Options, fun edlin_expand:expand/2), @@ -57,6 +56,16 @@ server(Ancestors, Drv, Shell, Options) -> put(dumb, Dumb), put(expand_below, proplists:get_value(expand_below, Options, true)), + DefaultGroupHistory = + case not get(echo) of + true -> + []; + false -> + group_history:load() + end, + + put(line_buffer, proplists:get_value(line_buffer, Options, DefaultGroupHistory)), + server_loop(Drv, start_shell(Shell), []). whereis_shell() -> diff --git a/lib/kernel/test/init_SUITE.erl b/lib/kernel/test/init_SUITE.erl index ea75f040f232..f273a039aca6 100644 --- a/lib/kernel/test/init_SUITE.erl +++ b/lib/kernel/test/init_SUITE.erl @@ -27,7 +27,7 @@ -export([get_arguments/1, get_argument/1, boot_var/1, restart/1, many_restarts/0, many_restarts/1, restart_with_mode/1, - get_plain_arguments/1, + get_plain_arguments/1, init_group_history_deadlock/1, reboot/1, stop_status/1, stop/1, get_status/1, script_id/1, dot_erlang/1, unknown_module/1, find_system_processes/0]). @@ -47,7 +47,8 @@ suite() -> all() -> [get_arguments, get_argument, boot_var, many_restarts, restart_with_mode, - get_plain_arguments, restart, stop_status, get_status, script_id, + get_plain_arguments, init_group_history_deadlock, + restart, stop_status, get_status, script_id, dot_erlang, unknown_module, {group, boot}]. groups() -> @@ -223,6 +224,17 @@ get_plain_arguments(Config) when is_list(Config) -> ok. +init_group_history_deadlock(_Config) -> + Output = os:cmd(ct:get_progname() ++ " -noshell -eval \"logger:warning(\\\"testing\\\")\" " + "-inets services crashme -eval \"application:start(inets, permanent).\" "), + + io:format("Got output: ~ts~n",[Output]), + + case string:find(Output, "removed_failing_handler") of + nomatch -> ok; + _ -> ct:fail("Found unexpected printout in log") + end. + %% ------------------------------------------------ %% Use -boot_var flag to set $TEST_VAR in boot script. %% ------------------------------------------------