summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--erts/emulator/beam/beam_load.c2
-rw-r--r--erts/preloaded/src/init.erl52
-rw-r--r--lib/kernel/test/init_SUITE.erl19
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.
%% ------------------------------------------------