diff options
-rw-r--r-- | erts/emulator/beam/beam_load.c | 2 | ||||
-rw-r--r-- | erts/preloaded/src/init.erl | 52 | ||||
-rw-r--r-- | lib/kernel/test/init_SUITE.erl | 19 |
3 files changed, 57 insertions, 16 deletions
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index 85beba57ee..c7c0a715b5 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -47,7 +47,7 @@ Uint erts_total_code_size; static int load_code(LoaderState *stp); -#define PLEASE_RECOMPILE "please re-compile this module with an Erlang/OTP " ERLANG_OTP_RELEASE " compiler" +#define PLEASE_RECOMPILE "please re-compile this module with an Erlang/OTP " ERLANG_OTP_RELEASE " compiler or update your Erlang/OTP version" /**********************************************************************/ diff --git a/erts/preloaded/src/init.erl b/erts/preloaded/src/init.erl index a95df3741e..96e0ec1dd6 100644 --- a/erts/preloaded/src/init.erl +++ b/erts/preloaded/src/init.erl @@ -396,8 +396,8 @@ boot_loop(BootPid, State) -> loop(State#state{status = {started,PS}, subscribed = []}); {'EXIT',BootPid,Reason} -> - erlang:display({"init terminating in do_boot",Reason}), - crash("init terminating in do_boot", [Reason]); + % erlang:display({"init terminating in do_boot",Reason}), + crash("Runtime terminating during boot", [Reason]); {'EXIT',Pid,Reason} -> Kernel = State#state.kernel, terminate(Pid,Kernel,Reason), %% If Pid is a Kernel pid, halt()! @@ -462,9 +462,9 @@ new_kernelpid({_Name,ignore},BootPid,State) -> BootPid ! {self(),ignore}, State; new_kernelpid({Name,What},BootPid,State) -> - erlang:display({"could not start kernel pid",Name,What}), + % erlang:display({"could not start kernel pid",Name,What}), clear_system(false,BootPid,State), - crash("could not start kernel pid", [Name, What]). + crash("Could not start kernel pid", [Name, What]). %% Here is the main loop after the system has booted. @@ -834,7 +834,7 @@ terminate(Pid,Kernel,Reason) -> case kernel_pid(Pid,Kernel) of {ok,Name} -> sleep(500), %% Flush error printouts! - erlang:display({"Kernel pid terminated",Name,Reason}), + % erlang:display({"Kernel pid terminated",Name,Reason}), crash("Kernel pid terminated", [Name, Reason]); _ -> false @@ -1235,18 +1235,44 @@ start_it({eval,Bin}) -> {value, _Value, _Bs} = erl_eval:exprs(Expr, erl_eval:new_bindings()), ok catch E:R:ST -> - erlang:display_string( - binary_to_list( - iolist_to_binary(["Failed to eval: ",Bin,"\n"]))), + Message = [<<"Error! Failed to eval: ">>, Bin, <<"\r\n\r\n">>], + erlang:display_string(binary_to_list(iolist_to_binary(Message))), erlang:raise(E,R,ST) end; -start_it([_|_]=MFA) -> - case MFA of - [M] -> M:start(); - [M,F] -> M:F(); - [M,F|Args] -> M:F(Args) % Args is a list +start_it([M|FA]) -> + case code:ensure_loaded(M) of + {module, M} -> + case FA of + [] -> M:start(); + [F] -> M:F(); + [F|Args] -> M:F(Args) % Args is a list + end; + + {error, Reason} -> + Message = [explain_ensure_loaded_error(M, Reason), <<"\r\n\r\n">>], + erlang:display_string(binary_to_list(iolist_to_binary(Message))), + erlang:error(undef) end. +explain_ensure_loaded_error(M, badfile) -> + S = [<<"it requires a more recent Erlang/OTP version " + "or its .beam file was corrupted.\r\n" + "(You are running Erlang/OTP ">>, + erlang:system_info(otp_release), <<".)">>], + explain_add_head(M, S); +explain_ensure_loaded_error(M, nofile) -> + S = <<"it cannot be found. Make sure that the module name is correct and\r\n", + "that its .beam file is in the code path.">>, + explain_add_head(M, S); +explain_ensure_loaded_error(M, Other) -> + [<<"Error! Failed to load module '", (atom_to_binary(M))/binary, + "'. Reason: ">>, + atom_to_binary(Other)]. + +explain_add_head(M, S) -> + [<<"Error! Failed to load module '", (atom_to_binary(M))/binary, + "' because ">>, S]. + %% Load a module. do_load_module(Mod, BinCode) -> diff --git a/lib/kernel/test/init_SUITE.erl b/lib/kernel/test/init_SUITE.erl index bc3882b862..ea75f040f2 100644 --- a/lib/kernel/test/init_SUITE.erl +++ b/lib/kernel/test/init_SUITE.erl @@ -29,7 +29,7 @@ many_restarts/0, many_restarts/1, restart_with_mode/1, get_plain_arguments/1, reboot/1, stop_status/1, stop/1, get_status/1, script_id/1, - dot_erlang/1, + dot_erlang/1, unknown_module/1, find_system_processes/0]). -export([boot1/1, boot2/1]). @@ -48,7 +48,7 @@ all() -> [get_arguments, get_argument, boot_var, many_restarts, restart_with_mode, get_plain_arguments, restart, stop_status, get_status, script_id, - dot_erlang, {group, boot}]. + dot_erlang, unknown_module, {group, boot}]. groups() -> [{boot, [], [boot1, boot2]}]. @@ -689,6 +689,21 @@ dot_erlang(Config) -> ok. +unknown_module(Config) when is_list(Config) -> + Port = open_port({spawn, "erl -s unknown_module"}, + [exit_status, use_stdio, stderr_to_stdout]), + Error = "Error! Failed to load module 'unknown_module' because it cannot be found.", + [_ | _] = string:find(collect_until_exit_one(Port), Error), + ok. + +collect_until_exit_one(Port) -> + receive + {Port, {data, Msg}} -> Msg ++ collect_until_exit_one(Port); + {Port, {exit_status, 1}} -> [] + after + 30_000 -> ct:fail(erl_timeout) + end. + %% ------------------------------------------------ %% Start the slave system with -boot flag. %% ------------------------------------------------ |