summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMagnus Lång <margnus1@telia.com>2016-11-19 14:26:01 +0100
committerMagnus Lång <margnus1@telia.com>2016-11-19 16:13:36 +0100
commite7250092945c7d15063d7b2f8ab50070b2a30786 (patch)
tree9ffa2dce8d3786405d0d54a6749bffccb8aef8b7
parent4683b5c227a238ee27f658bdfe2981c4b69acf09 (diff)
downloaderlang-e7250092945c7d15063d7b2f8ab50070b2a30786.tar.gz
hipe: Improve error message on internal crashes
Print the MFA/module being compiled, and pretty-print the backtrace with lib:format_stacktrace/4. Additionally, make the error_msg/2 macro in hipe.hrl respect the HIPE_LOGGING define, since messages produced by this macro just before runtime shutdown were sometimes lost (since code_server:error_msg/2 is asynchronous).
-rw-r--r--lib/hipe/main/hipe.erl89
-rw-r--r--lib/hipe/main/hipe.hrl.src10
2 files changed, 62 insertions, 37 deletions
diff --git a/lib/hipe/main/hipe.erl b/lib/hipe/main/hipe.erl
index 6c525dd143..38a5a64398 100644
--- a/lib/hipe/main/hipe.erl
+++ b/lib/hipe/main/hipe.erl
@@ -635,44 +635,51 @@ run_compiler(Name, DisasmFun, IcodeFun, Opts0) ->
Opts = expand_basic_options(Opts0 ++ ?COMPILE_DEFAULTS),
?when_option(verbose, Opts, ?debug_msg("Compiling: ~p\n",[Name])),
?option_start_time("Compile", Opts),
- Res = run_compiler_1(DisasmFun, IcodeFun, Opts),
+ Res = run_compiler_1(Name, DisasmFun, IcodeFun, Opts),
?option_stop_time("Compile", Opts),
Res.
-run_compiler_1(DisasmFun, IcodeFun, Options) ->
+run_compiler_1(Name, DisasmFun, IcodeFun, Options) ->
Parent = self(),
{trap_exit,TrapExit} = process_info(Parent, trap_exit),
%% Spawn a compilation process CompProc. In case this process gets
%% killed, the trap_exit flag is restored to that of the Parent process.
process_flag(trap_exit, true),
- CompProc = spawn_link(fun () ->
- %% Compiler process
- set_architecture(Options),
- pre_init(Options),
- %% The full option expansion is not done
- %% until the DisasmFun returns.
- {Code, CompOpts} = DisasmFun(Options),
- Opts0 = expand_options(Options ++ CompOpts,
- get(hipe_target_arch)),
- Opts =
- case proplists:get_bool(to_llvm, Opts0) andalso
- not llvm_support_available() of
- true ->
- ?error_msg("No LLVM version 3.4 or greater "
- "found in $PATH; aborting "
- "native code compilation.\n", []),
- ?EXIT(cant_find_required_llvm_version);
- false ->
- Opts0
- end,
- check_options(Opts),
- ?when_option(verbose, Options,
- ?debug_msg("Options: ~p.\n",[Opts])),
- init(Opts),
- {Icode, WholeModule} = IcodeFun(Code, Opts),
- CompRes = compile_finish(Icode, WholeModule, Opts),
- compiler_return(CompRes, Parent)
- end),
+ CompProc =
+ spawn_link(
+ fun () ->
+ try
+ %% Compiler process
+ set_architecture(Options),
+ pre_init(Options),
+ %% The full option expansion is not done
+ %% until the DisasmFun returns.
+ {Code, CompOpts} = DisasmFun(Options),
+ Opts0 = expand_options(Options ++ CompOpts,
+ get(hipe_target_arch)),
+ Opts =
+ case proplists:get_bool(to_llvm, Opts0) andalso
+ not llvm_support_available() of
+ true ->
+ ?error_msg("No LLVM version 3.4 or greater "
+ "found in $PATH; aborting "
+ "native code compilation.\n", []),
+ ?EXIT(cant_find_required_llvm_version);
+ false ->
+ Opts0
+ end,
+ check_options(Opts),
+ ?when_option(verbose, Options,
+ ?debug_msg("Options: ~p.\n",[Opts])),
+ init(Opts),
+ {Icode, WholeModule} = IcodeFun(Code, Opts),
+ CompRes = compile_finish(Icode, WholeModule, Opts),
+ compiler_return(CompRes, Parent)
+ catch error:Error ->
+ print_crash_message(Name, Error),
+ exit(Error)
+ end
+ end),
Timeout = case proplists:get_value(timeout, Options) of
N when is_integer(N), N >= 0 -> N;
undefined -> ?DEFAULT_TIMEOUT;
@@ -691,7 +698,7 @@ run_compiler_1(DisasmFun, IcodeFun, Options) ->
exit(CompProc, kill),
receive {'EXIT', CompProc, _} -> ok end,
flush(),
- ?error_msg("ERROR: Compilation timed out.\n",[]),
+ ?error_msg("ERROR: Compilation of ~w timed out.\n",[Name]),
exit(timed_out)
end,
Result = receive {CompProc, Res} -> Res end,
@@ -844,11 +851,25 @@ finalize_fun_sequential({MFA, Icode}, Opts, Servers) ->
catch
error:Error ->
?when_option(verbose, Opts, ?debug_untagged_msg("\n", [])),
- ErrorInfo = {Error, erlang:get_stacktrace()},
- ?error_msg("ERROR: ~p~n", [ErrorInfo]),
- ?EXIT(ErrorInfo)
+ print_crash_message(MFA, Error),
+ exit(Error)
end.
+print_crash_message(What, Error) ->
+ StackFun = fun(_,_,_) -> false end,
+ FormatFun = fun (Term, _) -> io_lib:format("~p", [Term]) end,
+ StackTrace = lib:format_stacktrace(1, erlang:get_stacktrace(),
+ StackFun, FormatFun),
+ WhatS = case What of
+ {M,F,A} -> io_lib:format("~w:~w/~w", [M,F,A]);
+ Mod -> io_lib:format("~w", [Mod])
+ end,
+ ?error_msg("INTERNAL ERROR~n"
+ "while compiling ~s~n"
+ "crash reason: ~p~n"
+ "~s~n",
+ [WhatS, Error, StackTrace]).
+
pp_server_start(Opts) ->
set_architecture(Opts),
garbage_collect(),
diff --git a/lib/hipe/main/hipe.hrl.src b/lib/hipe/main/hipe.hrl.src
index 53b59f88f0..08bfd17f30 100644
--- a/lib/hipe/main/hipe.hrl.src
+++ b/lib/hipe/main/hipe.hrl.src
@@ -1,4 +1,4 @@
-%% -*- erlang-indent-level: 2 -*-
+%% -*- mode: erlang; erlang-indent-level: 2 -*-
%%
%% %CopyrightBegin%
%%
@@ -70,20 +70,24 @@
code_server:info_msg(?MSGTAG ++ Msg, Args)).
-define(untagged_msg(Msg, Args),
code_server:info_msg(Msg, Args)).
+-define(untagged_error_msg(Msg, Args),
+ code_server:error_msg(Msg, Args)).
-else.
-define(msg(Msg, Args),
io:format(?MSGTAG ++ Msg, Args)).
-define(untagged_msg(Msg, Args),
io:format(Msg, Args)).
+-define(untagged_error_msg(Msg, Args),
+ io:format(Msg, Args)).
-endif.
%%
%% Define error and warning messages.
%%
-define(error_msg(Msg, Args),
- code_server:error_msg(?MSGTAG ++
+ ?untagged_error_msg(?MSGTAG ++
"Error: [~s:~w]: " ++ Msg,
- [?MODULE,?LINE|Args])).
+ [?MODULE,?LINE|Args])).
-define(WARNING_MSG(Msg, Args),
?msg("Warning: [~s:~w]: " ++ Msg, [?MODULE,?LINE|Args])).