Skip to content

Commit

Permalink
Merge pull request #28 from stritzinger/otp-21-stacktrace-compatibility
Browse files Browse the repository at this point in the history
Add compatibility for OTP 21+ stack traces
  • Loading branch information
ThomasArts authored Oct 30, 2019
2 parents d12dec6 + 6281fcf commit 18ed572
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 8 deletions.
10 changes: 6 additions & 4 deletions src/cluster_info.erl
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
%% Really useful but ugly hack.
-export([capture_io/2]).

-include("stacktrace.hrl").

-type dump_option() :: {'modules', [atom()]}.
-type dump_return() :: 'ok' | 'error'.
-type filename() :: string().
Expand Down Expand Up @@ -125,9 +127,9 @@ dump_node(Node, Path, Opts) when is_atom(Node), is_list(Path) ->
MRef = monitor(process, Remote),
try
ok = collect_remote_info(Remote, FH)
catch X:Y ->
catch ?_exception_(X, Y, StackToken) ->
io:format("Error: ~P ~P at ~p\n",
[X, 20, Y, 20, erlang:get_stacktrace()]),
[X, 20, Y, 20, ?_get_stacktrace_(StackToken)]),
error
after
demonitor(MRef, [flush]),
Expand Down Expand Up @@ -272,9 +274,9 @@ dump_local_info(CPid, Opts) ->
[Name, node()]),
format_noescape(CPid, "<pre>\n", []),
Fun(CPid)
catch X:Y ->
catch ?_exception_(X, Y, StackToken) ->
format(CPid, "Error in ~p: ~p ~p at ~p\n",
[Name, X, Y, erlang:get_stacktrace()])
[Name, X, Y, ?_get_stacktrace_(StackToken)])
after
format_noescape(CPid, "</pre>\n", []),
format_noescape(CPid, "\n",[])
Expand Down
10 changes: 6 additions & 4 deletions src/cluster_info_basic.erl
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
loaded_modules/1, memory_hogs/2, non_zero_mailboxes/1, port_info/1,
registered_names/1, time_and_date/1, timer_status/1]).

-include("stacktrace.hrl").

-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
-endif.
Expand Down Expand Up @@ -84,9 +86,9 @@ application_info(C) ->
cluster_info:format(C, " ~p\n\n", [application:get_all_key(App)]),
cluster_info:format(C, " Application:get_all_env(~p):\n", [App]),
cluster_info:format(C, " ~p\n\n", [application:get_all_env(App)])
catch X:Y ->
catch ?_exception_(X, Y, StackToken) ->
cluster_info:format(C, "Error for ~p: ~p ~p at ~p\n",
[App, X, Y, erlang:get_stacktrace()])
[App, X, Y, ?_get_stacktrace_(StackToken)])
end || App <- lists:sort([A || {A, _, _} <- application:which_applications()])].

capture_ets_i(C) ->
Expand Down Expand Up @@ -174,9 +176,9 @@ loaded_modules(C) ->
[try
cluster_info:format(C, " Module ~p:\n", [Mod]),
cluster_info:format(C, " ~p\n\n", [Mod:module_info()])
catch X:Y ->
catch ?_exception_(X, Y, StackToken) ->
cluster_info:format(C, "Error for ~p: ~p ~p at ~p\n",
[Mod, X, Y, erlang:get_stacktrace()])
[Mod, X, Y, ?_get_stacktrace_(StackToken)])
end || Mod <- lists:sort([M || {M, _} <- code:all_loaded()])].

memory_hogs(C, Num) ->
Expand Down
33 changes: 33 additions & 0 deletions src/stacktrace.hrl
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
%% Originating from Quviq AB
%% Fix to make Erlang programs compile on both OTP20 and OTP21.
%%
%% Get the stack trace in a way that is backwards compatible. Luckily
%% OTP_RELEASE was introduced in the same version as the new preferred way of
%% getting the stack trace. A _catch_/2 macro is provided for consistency in
%% cases where the stack trace is not needed.
%%
%% Example use:
%% try f(...)
%% catch
%% ?_exception_(_, Reason, StackToken) ->
%% case Reason of
%% {fail, Error} -> ok;
%% _ -> {'EXIT', Reason, ?_get_stacktrace_(StackToken)}
%% end
%% end,

-ifdef(OTP_RELEASE). %% This implies 21 or higher
-define(_exception_(Class, Reason, StackToken), Class:Reason:StackToken).
-define(_get_stacktrace_(StackToken), StackToken).
-define(_current_stacktrace_(),
try
exit('$get_stacktrace')
catch
exit:'$get_stacktrace':__GetCurrentStackTrace ->
__GetCurrentStackTrace
end).
-else.
-define(_exception_(Class, Reason, _), Class:Reason).
-define(_get_stacktrace_(_), erlang:get_stacktrace()).
-define(_current_stacktrace_(), erlang:get_stacktrace()).
-endif.

0 comments on commit 18ed572

Please sign in to comment.