From cc59f962511733c5dfcb1be27a274f9298736006 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Mon, 16 May 2016 14:56:03 +0200 Subject: Tolerate bad directories in the code path A bad directory in the path would prevent the run-time system from starting: $ echo >foobar $ erl -pa foobar {"init terminating in do_boot",{load_failed,[supervisor,kernel,gen_server,file_io_server,filename,file,erl_parse,error_logger,code_server,erl_lint,proc_lib,code,application_controller,application_master,gen_event,application,error_handler,lists,heart,gen,file_server,ets,erl_eval]}} Crash dump is being written to: erl_crash.dump...done init terminating in do_boot () The reason is that when attempting to read each of the BEAM files, there would be an 'enotdir' error which erl_prim_load:get_modules/2,3 assumed was a fatal error. Update erl_prim_load:get_modules/2,3 to ignore any error and try the next directory in the path. Reported-by: http://bugs.erlang.org/browse/ERL-142 Reported-by: Michael Truog --- lib/kernel/test/erl_prim_loader_SUITE.erl | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'lib/kernel/test') diff --git a/lib/kernel/test/erl_prim_loader_SUITE.erl b/lib/kernel/test/erl_prim_loader_SUITE.erl index 4f3881d27e..b6417210b9 100644 --- a/lib/kernel/test/erl_prim_loader_SUITE.erl +++ b/lib/kernel/test/erl_prim_loader_SUITE.erl @@ -108,13 +108,18 @@ get_file(Config) when is_list(Config) -> error = erl_prim_loader:get_file({dummy}), ok. -get_modules(_Config) -> +get_modules(Config) -> case test_server:is_cover() of - false -> do_get_modules(); + false -> do_get_modules(Config); true -> {skip,"Cover"} end. -do_get_modules() -> +do_get_modules(Config) -> + PrivDir = proplists:get_value(priv_dir, Config), + NotADir = atom_to_list(?FUNCTION_NAME) ++ "_not_a_dir", + ok = file:write_file(filename:join(PrivDir, NotADir), <<>>), + ok = file:set_cwd(PrivDir), + MsGood = lists:sort([lists,gen_server,gb_trees,code_server]), Ms = [certainly_not_existing|MsGood], SuccExp = [begin @@ -129,8 +134,10 @@ do_get_modules() -> Path = code:get_path(), Process = fun(_, F, Code) -> {ok,{F,erlang:md5(Code)}} end, - {ok,{Succ,FailExp}} = erl_prim_loader:get_modules(Ms, Process, Path), - SuccExp = lists:sort(Succ), + {ok,{SuccExp,FailExp}} = get_modules_sorted(Ms, Process, Path), + + %% Test that an 'enotdir' error can be handled. + {ok,{SuccExp,FailExp}} = get_modules_sorted(Ms, Process, [NotADir|Path]), Name = inet_get_modules, {ok, Node, BootPid} = complete_start_node(Name), @@ -147,6 +154,13 @@ do_get_modules() -> ok. +get_modules_sorted(Ms, Process, Path) -> + case erl_prim_loader:get_modules(Ms, Process, Path) of + {ok,{Succ,FailExp}} -> + {ok,{lists:sort(Succ),lists:sort(FailExp)}}; + Other -> + Other + end. normalize_and_backslash(Config) -> %% Test OTP-11170 -- cgit v1.2.3