diff options
author | Fred Hebert <mononcqc@ferd.ca> | 2018-05-03 18:14:11 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-03 18:14:11 -0400 |
commit | 048dfad1e8e05aead68cdd062653d8f51d2eaf88 (patch) | |
tree | 5157ad3d51aa3765df04a226206441a07e95974f | |
parent | a908284b112ff77dbf0ae9b9f946bc7b739faf29 (diff) | |
parent | e321ca64981504f10a3be1715ce5d94c3cd10ae7 (diff) |
Merge pull request #1773 from ferd/otp-21-stacktrace-compat
Work around OTP-21 deprecation of get_stacktrace() and other incompatible changes
-rwxr-xr-x | bootstrap | 1 | ||||
-rw-r--r-- | rebar.config | 4 | ||||
-rw-r--r-- | rebar.lock | 4 | ||||
-rw-r--r-- | src/rebar.hrl | 6 | ||||
-rw-r--r-- | src/rebar3.erl | 21 | ||||
-rw-r--r-- | src/rebar_agent.erl | 4 | ||||
-rw-r--r-- | src/rebar_core.erl | 3 | ||||
-rw-r--r-- | src/rebar_dialyzer_format.erl | 4 | ||||
-rw-r--r-- | src/rebar_fetch.erl | 4 | ||||
-rw-r--r-- | src/rebar_plugins.erl | 4 | ||||
-rw-r--r-- | src/rebar_prv_shell.erl | 33 | ||||
-rw-r--r-- | src/rebar_prv_update.erl | 4 | ||||
-rw-r--r-- | src/rebar_state.erl | 6 | ||||
-rw-r--r-- | src/rebar_utils.erl | 11 |
14 files changed, 61 insertions, 48 deletions
@@ -571,6 +571,7 @@ additional_defines() -> [{d, D} || {Re, D} <- [{"^[0-9]+", namespaced_types}, {"^R1[4|5]", deprecated_crypto}, {"^2", unicode_str}, + {"^(R|1|20)", fun_stacktrace}, {"^((1[8|9])|2)", rand_module}], is_otp_release(Re)]. diff --git a/rebar.config b/rebar.config index d136334..09010e8 100644 --- a/rebar.config +++ b/rebar.config @@ -1,7 +1,7 @@ %% -*- mode: erlang;erlang-indent-level: 4;indent-tabs-mode: nil -*- %% ex: ts=4 sw=4 ft=erlang et -{deps, [{erlware_commons, "1.0.5"}, +{deps, [{erlware_commons, "1.1.0"}, {ssl_verify_fun, "1.1.3"}, {certifi, "2.0.0"}, {providers, "1.7.0"}, @@ -31,6 +31,7 @@ {erl_opts, [{platform_define, "^[0-9]+", namespaced_types}, {platform_define, "^(19|2)", rand_only}, {platform_define, "^2", unicode_str}, + {platform_define, "^(R|1|20)", fun_stacktrace}, warnings_as_errors]}. %% Use OTP 18+ when dialyzing rebar3 @@ -59,6 +60,7 @@ {platform_define, "^R1[4|5]", deprecated_crypto}, {platform_define, "^((1[8|9])|2)", rand_module}, {platform_define, "^2", unicode_str}, + {platform_define, "^(R|1|20)", fun_stacktrace}, no_debug_info, warnings_as_errors]}, {deps, []}, {plugins, []}]}, @@ -3,7 +3,7 @@ {<<"certifi">>,{pkg,<<"certifi">>,<<"2.0.0">>},0}, {<<"cf">>,{pkg,<<"cf">>,<<"0.2.2">>},0}, {<<"cth_readable">>,{pkg,<<"cth_readable">>,<<"1.3.4">>},0}, - {<<"erlware_commons">>,{pkg,<<"erlware_commons">>,<<"1.0.5">>},0}, + {<<"erlware_commons">>,{pkg,<<"erlware_commons">>,<<"1.1.0">>},0}, {<<"eunit_formatters">>,{pkg,<<"eunit_formatters">>,<<"0.5.0">>},0}, {<<"getopt">>,{pkg,<<"getopt">>,<<"1.0.1">>},0}, {<<"providers">>,{pkg,<<"providers">>,<<"1.7.0">>},0}, @@ -15,7 +15,7 @@ {<<"certifi">>, <<"A0C0E475107135F76B8C1D5BC7EFB33CD3815CB3CF3DEA7AEFDD174DABEAD064">>}, {<<"cf">>, <<"7F2913FFF90ABCABD0F489896CFEB0B0674F6C8DF6C10B17A83175448029896C">>}, {<<"cth_readable">>, <<"CB85DF77CEB7F05854AE241300DB36A72C371740EDD883D8BF75B5F652B7067D">>}, - {<<"erlware_commons">>, <<"FC23D8E304140B65A811F653A76B2FB10B0CE744608CAF86E9125CEB349C9442">>}, + {<<"erlware_commons">>, <<"F69F3D96044C2A9E735CCD76F469FEC5FC851797E5FE23115698B4EDC072191B">>}, {<<"eunit_formatters">>, <<"6A9133943D36A465D804C1C5B6E6839030434B8879C5600D7DDB5B3BAD4CCB59">>}, {<<"getopt">>, <<"C73A9FA687B217F2FF79F68A3B637711BB1936E712B521D8CE466B29CBF7808A">>}, {<<"providers">>, <<"BBF730563914328EC2511D205E6477A94831DB7297DE313B3872A2B26C562EAB">>}, diff --git a/src/rebar.hrl b/src/rebar.hrl index ca44283..f461c70 100644 --- a/src/rebar.hrl +++ b/src/rebar.hrl @@ -52,6 +52,12 @@ -type rebar_set() :: set(). -endif. +-ifdef(fun_stacktrace). +-define(WITH_STACKTRACE(T, R, S), T:R -> S = erlang:get_stacktrace(),). +-else. +-define(WITH_STACKTRACE(T, R, S), T:R:S ->). +-endif. + -define(GRAPH_VSN, 2). -type v() :: {digraph:vertex(), term()} | 'false'. -type e() :: {digraph:vertex(), digraph:vertex()}. diff --git a/src/rebar3.erl b/src/rebar3.erl index eb5ad58..8e9d4b1 100644 --- a/src/rebar3.erl +++ b/src/rebar3.erl @@ -67,10 +67,10 @@ main(Args) -> {ok, _State} -> erlang:halt(0); Error -> - handle_error(Error) + handle_error(Error, []) catch - _:Error -> - handle_error(Error) + ?WITH_STACKTRACE(_,Error,Stacktrace) + handle_error(Error, Stacktrace) end. %% @doc Erlang-API entry point @@ -299,15 +299,15 @@ global_option_spec_list() -> %% @private translate unhandled errors and internal return codes into proper %% erroneous program exits. --spec handle_error(term()) -> no_return(). -handle_error(rebar_abort) -> +-spec handle_error(term(), term()) -> no_return(). +handle_error(rebar_abort, _) -> erlang:halt(1); -handle_error({error, rebar_abort}) -> +handle_error({error, rebar_abort}, _) -> erlang:halt(1); -handle_error({error, {Module, Reason}}) -> +handle_error({error, {Module, Reason}}, Stacktrace) -> case code:which(Module) of non_existing -> - ?CRASHDUMP("~p: ~p~n~p~n~n", [Module, Reason, erlang:get_stacktrace()]), + ?CRASHDUMP("~p: ~p~n~p~n~n", [Module, Reason, Stacktrace]), ?ERROR("Uncaught error in rebar_core. Run with DEBUG=1 to stacktrace or consult rebar3.crashdump", []), ?DEBUG("Uncaught error: ~p ~p", [Module, Reason]), ?INFO("When submitting a bug report, please include the output of `rebar3 report \"your command\"`", []); @@ -315,13 +315,12 @@ handle_error({error, {Module, Reason}}) -> ?ERROR("~ts", [Module:format_error(Reason)]) end, erlang:halt(1); -handle_error({error, Error}) when is_list(Error) -> +handle_error({error, Error}, _) when is_list(Error) -> ?ERROR("~ts", [Error]), erlang:halt(1); -handle_error(Error) -> +handle_error(Error, StackTrace) -> %% Nothing should percolate up from rebar_core; %% Dump this error to console - StackTrace = erlang:get_stacktrace(), ?CRASHDUMP("Error: ~p~n~p~n~n", [Error, StackTrace]), ?ERROR("Uncaught error in rebar_core. Run with DEBUG=1 to see stacktrace or consult rebar3.crashdump", []), ?DEBUG("Uncaught error: ~p", [Error]), diff --git a/src/rebar_agent.erl b/src/rebar_agent.erl index b5dcfcf..8d0f9cf 100644 --- a/src/rebar_agent.erl +++ b/src/rebar_agent.erl @@ -114,8 +114,8 @@ run(Namespace, Command, StrArgs, RState, Cwd) -> {{error, cwd_changed}, RState} end catch - Type:Reason -> - ?DEBUG("Agent Stacktrace: ~p", [erlang:get_stacktrace()]), + ?WITH_STACKTRACE(Type, Reason, Stacktrace) + ?DEBUG("Agent Stacktrace: ~p", [Stacktrace]), {{error, {Type, Reason}}, RState} end. diff --git a/src/rebar_core.erl b/src/rebar_core.erl index 6132a5e..6a1cdbf 100644 --- a/src/rebar_core.erl +++ b/src/rebar_core.erl @@ -157,8 +157,7 @@ do([ProviderName | Rest], State) -> {error, Error} -> {error, Error} catch - error:undef -> - Stack = erlang:get_stacktrace(), + ?WITH_STACKTRACE(error,undef,Stack) case Stack of [{ProviderName, do, [_], _}|_] -> %% This should really only happen if a plugin provider doesn't export do/1 diff --git a/src/rebar_dialyzer_format.erl b/src/rebar_dialyzer_format.erl index 5583633..cb0e958 100644 --- a/src/rebar_dialyzer_format.erl +++ b/src/rebar_dialyzer_format.erl @@ -53,9 +53,9 @@ format_warning_(Opts, Warning = {_Tag, {SrcFile, Line}, Msg}, {_LastFile, Acc}) String = message_to_string(Msg), {SrcFile, [lists:flatten(fmt("~n~ts~n~!c~4w~!!: ~ts", [F, Line, String])) | Acc]} catch - Error:Reason -> + ?WITH_STACKTRACE(Error, Reason, Stacktrace) ?DEBUG("Failed to pretty format warning: ~p:~p~n~p", - [Error, Reason, erlang:get_stacktrace()]), + [Error, Reason, Stacktrace]), {SrcFile, [dialyzer:format_warning(Warning, fullpath) | Acc]} end. diff --git a/src/rebar_fetch.erl b/src/rebar_fetch.erl index f68a54d..d2c7706 100644 --- a/src/rebar_fetch.erl +++ b/src/rebar_fetch.erl @@ -32,8 +32,8 @@ download_source(AppDir, Source, State) -> Error -> throw(?PRV_ERROR(Error)) catch - C:T -> - ?DEBUG("rebar_fetch exception ~p ~p ~p", [C, T, erlang:get_stacktrace()]), + ?WITH_STACKTRACE(C,T,S) + ?DEBUG("rebar_fetch exception ~p ~p ~p", [C, T, S]), throw(?PRV_ERROR({fetch_fail, Source})) end. diff --git a/src/rebar_plugins.erl b/src/rebar_plugins.erl index 57c34bc..bc6a1e0 100644 --- a/src/rebar_plugins.erl +++ b/src/rebar_plugins.erl @@ -114,8 +114,8 @@ handle_plugin(Profile, Plugin, State, Upgrade) -> {plugin_providers(Plugin), State4} catch - C:T -> - ?DEBUG("~p ~p ~p", [C, T, erlang:get_stacktrace()]), + ?WITH_STACKTRACE(C,T,S) + ?DEBUG("~p ~p ~p", [C, T, S]), ?WARN("Plugin ~p not available. It will not be used.", [Plugin]), {[], State} end. diff --git a/src/rebar_prv_shell.erl b/src/rebar_prv_shell.erl index 2c48083..9a320ad 100644 --- a/src/rebar_prv_shell.erl +++ b/src/rebar_prv_shell.erl @@ -201,21 +201,28 @@ rewrite_leaders(OldUser, NewUser) -> lists:member(proplists:get_value(group_leader, erlang:process_info(Pid)), OldMasters)], try - %% enable error_logger's tty output - error_logger:swap_handler(tty), - %% disable the simple error_logger (which may have been added multiple - %% times). removes at most the error_logger added by init and the - %% error_logger added by the tty handler - remove_error_handler(3), - %% reset the tty handler once more for remote shells - error_logger:swap_handler(tty) + case erlang:function_exported(logger, module_info, 0) of + false -> + %% Old style logger had a lock-up issue and other problems related + %% to group leader handling. + %% enable error_logger's tty output + error_logger:swap_handler(tty), + %% disable the simple error_logger (which may have been added + %% multiple times). removes at most the error_logger added by + %% init and the error_logger added by the tty handler + remove_error_handler(3), + %% reset the tty handler once more for remote shells + error_logger:swap_handler(tty); + true -> + %% This is no longer a problem with the logger interface + ok + end catch - E:R -> % may fail with custom loggers - ?DEBUG("Logger changes failed for ~p:~p (~p)", [E,R,erlang:get_stacktrace()]), + ?WITH_STACKTRACE(E,R,S) % may fail with custom loggers + ?DEBUG("Logger changes failed for ~p:~p (~p)", [E,R,S]), hope_for_best end. - setup_paths(State) -> %% Add deps to path code:add_pathsa(rebar_state:code_paths(State, all_deps)), @@ -235,9 +242,9 @@ maybe_run_script(State) -> File = filename:absname(RelFile), try run_script_file(File) catch - C:E -> + ?WITH_STACKTRACE(C,E,S) ?ABORT("Couldn't run shell escript ~p - ~p:~p~nStack: ~p", - [File, C, E, erlang:get_stacktrace()]) + [File, C, E, S]) end end. diff --git a/src/rebar_prv_update.erl b/src/rebar_prv_update.erl index 6dde024..1744631 100644 --- a/src/rebar_prv_update.erl +++ b/src/rebar_prv_update.erl @@ -73,8 +73,8 @@ do(State) -> ?PRV_ERROR({package_parse_cdn, CDN}) end catch - _E:C -> - ?DEBUG("Error creating package index: ~p ~p", [C, erlang:get_stacktrace()]), + ?WITH_STACKTRACE(_E, C, S) + ?DEBUG("Error creating package index: ~p ~p", [C, S]), throw(?PRV_ERROR(package_index_write)) end. diff --git a/src/rebar_state.erl b/src/rebar_state.erl index dd1f43f..3586dd6 100644 --- a/src/rebar_state.erl +++ b/src/rebar_state.erl @@ -418,9 +418,9 @@ create_logic_providers(ProviderModules, State0) -> end end, State0, ProviderModules) catch - C:T -> - ?DEBUG("~p: ~p ~p", [C, T, erlang:get_stacktrace()]), - ?CRASHDUMP("~p: ~p~n~p~n~n~p", [C, T, erlang:get_stacktrace(), State0]), + ?WITH_STACKTRACE(C,T,S) + ?DEBUG("~p: ~p ~p", [C, T, S]), + ?CRASHDUMP("~p: ~p~n~p~n~n~p", [C, T, S, State0]), throw({error, "Failed creating providers. Run with DEBUG=1 for stacktrace or consult rebar3.crashdump."}) end. diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index a911cc2..604abb8 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -506,11 +506,10 @@ otp_release1(Rel) -> %% It's fine to rely on the binary module here because we can %% be sure that it's available when the otp_release string does %% not begin with $R. - Size = byte_size(Vsn), %% The shortest vsn string consists of at least two digits %% followed by "\n". Therefore, it's safe to assume Size >= 3. - case binary:part(Vsn, {Size, -3}) of - <<"**\n">> -> + case binary:match(Vsn, <<"**">>) of + {Pos, _} -> %% The OTP documentation mentions that a system patched %% using the otp_patch_apply tool available to licensed %% customers will leave a '**' suffix in the version as a @@ -519,9 +518,9 @@ otp_release1(Rel) -> %% drop the suffix, given for all intents and purposes, we %% cannot obtain relevant information from it as far as %% tooling is concerned. - binary:bin_to_list(Vsn, {0, Size - 3}); - _ -> - binary:bin_to_list(Vsn, {0, Size - 1}) + binary:bin_to_list(Vsn, {0, Pos}); + nomatch -> + rebar_string:trim(binary:bin_to_list(Vsn), trailing, "\n") end end. |