diff options
author | Björn Gustavsson <[email protected]> | 2016-03-23 07:00:34 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2016-03-24 15:44:20 +0100 |
commit | afff8b0fd74fda09ba8dc5f7bfe95b5cb345872e (patch) | |
tree | 3f1c23166a61dbc82b5e1287e7af91a73ec4be45 | |
parent | 41d29391df8857a9645bd5b5889f5db5f5a7529c (diff) | |
download | otp-afff8b0fd74fda09ba8dc5f7bfe95b5cb345872e.tar.gz otp-afff8b0fd74fda09ba8dc5f7bfe95b5cb345872e.tar.bz2 otp-afff8b0fd74fda09ba8dc5f7bfe95b5cb345872e.zip |
Fix compile:forms/1,2 crash when not in an existing directory
compile:forms/1,2 will crash when the current working directory has
been deleted. Fix that problem, and while we are at it, also stop
including {source,""} in module_info() when no source code file is
given.
Reported-at: http://bugs.erlang.org/browse/ERL-113
Reported-by: Adam Lindberg
-rw-r--r-- | lib/compiler/src/beam_asm.erl | 6 | ||||
-rw-r--r-- | lib/compiler/src/compile.erl | 12 | ||||
-rw-r--r-- | lib/compiler/test/compile_SUITE.erl | 42 |
3 files changed, 51 insertions, 9 deletions
diff --git a/lib/compiler/src/beam_asm.erl b/lib/compiler/src/beam_asm.erl index 95be471de3..28fd061bdc 100644 --- a/lib/compiler/src/beam_asm.erl +++ b/lib/compiler/src/beam_asm.erl @@ -225,10 +225,14 @@ flatten_imports(Imps) -> list_to_binary(map(fun({M,F,A}) -> <<M:32,F:32,A:32>> end, Imps)). build_attributes(Opts, SourceFile, Attr, MD5) -> + Misc0 = case SourceFile of + [] -> []; + [_|_] -> [{source,SourceFile}] + end, Misc = case member(slim, Opts) of false -> {{Y,Mo,D},{H,Mi,S}} = erlang:universaltime(), - [{time,{Y,Mo,D,H,Mi,S}},{source,SourceFile}]; + [{time,{Y,Mo,D,H,Mi,S}}|Misc0]; true -> [] end, Compile = [{options,Opts},{version,?COMPILER_VSN}|Misc], diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl index 332bc0bdf9..65566df025 100644 --- a/lib/compiler/src/compile.erl +++ b/lib/compiler/src/compile.erl @@ -1328,7 +1328,7 @@ save_core_code(St) -> beam_asm(#compile{ifile=File,code=Code0, abstract_code=Abst,mod_options=Opts0}=St) -> - Source = filename:absname(File), + Source = paranoid_absname(File), Opts1 = lists:map(fun({debug_info_key,_}) -> {debug_info_key,'********'}; (Other) -> Other end, Opts0), @@ -1337,6 +1337,16 @@ beam_asm(#compile{ifile=File,code=Code0, {ok,Code} -> {ok,St#compile{code=Code,abstract_code=[]}} end. +paranoid_absname(""=File) -> + File; +paranoid_absname(File) -> + case file:get_cwd() of + {ok,Cwd} -> + filename:absname(File, Cwd); + _ -> + File + end. + test_native(#compile{options=Opts}) -> %% This test is done late, in case some other option has turned off native. %% 'native' given on the command line can be overridden by diff --git a/lib/compiler/test/compile_SUITE.erl b/lib/compiler/test/compile_SUITE.erl index fc04c9a60a..f1e75771bf 100644 --- a/lib/compiler/test/compile_SUITE.erl +++ b/lib/compiler/test/compile_SUITE.erl @@ -127,13 +127,39 @@ forms_2(Config) when is_list(Config) -> Src = "/foo/bar", AbsSrc = filename:absname(Src), Anno = erl_anno:new(1), - {ok,simple,Binary} = compile:forms([{attribute,Anno,module,simple}], - [binary,{source,Src}]), - code:load_binary(simple, Src, Binary), - Info = simple:module_info(compile), + SimpleCode = [{attribute,Anno,module,simple}], + {ok,simple,Bin1} = compile:forms(SimpleCode, [binary,{source,Src}]), - %% Test that the proper source is returned. - AbsSrc = proplists:get_value(source, Info), + %% Load and test that the proper source is returned. + AbsSrc = forms_load_code(simple, Src, Bin1), + + %% Work in a deleted directory. + PrivDir = proplists:get_value(priv_dir, Config), + WorkDir = filename:join(PrivDir, ?FUNCTION_NAME), + ok = file:make_dir(WorkDir), + ok = file:set_cwd(WorkDir), + case os:type() of + {unix,_} -> os:cmd("rm -rf " ++ WorkDir); + _ -> ok + end, + {ok,simple,Bin2} = compile:forms(SimpleCode), + undefined = forms_load_code(simple, "ignore", Bin2), + + {ok,simple,Bin3} = compile:forms(SimpleCode, [{source,Src},report]), + case forms_load_code(simple, "ignore", Bin3) of + Src -> %Unix. + ok; + AbsSrc -> %Windows. + ok + end, + + ok. + + +forms_load_code(Mod, Src, Bin) -> + {module,Mod} = code:load_binary(Mod, Src, Bin), + Info = Mod:module_info(compile), + SourceOption = proplists:get_value(source, Info), %% Ensure that the options are not polluted with 'source'. [] = proplists:get_value(options, Info), @@ -141,7 +167,9 @@ forms_2(Config) when is_list(Config) -> %% Cleanup. true = code:delete(simple), false = code:purge(simple), - ok. + + SourceOption. + module_mismatch(Config) when is_list(Config) -> DataDir = proplists:get_value(data_dir, Config), |