aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Bolinder <[email protected]>2018-02-05 12:35:15 +0100
committerHans Bolinder <[email protected]>2018-02-05 14:45:37 +0100
commitf3c2cfda7f145d6ffd2fdd76659348056f1828c9 (patch)
treef484fb24671985a19a2b22c1b0047b5c68e2a4af
parentc8f9f79352f7da02f212848b9a854ca2f6b553d5 (diff)
downloadotp-f3c2cfda7f145d6ffd2fdd76659348056f1828c9.tar.gz
otp-f3c2cfda7f145d6ffd2fdd76659348056f1828c9.tar.bz2
otp-f3c2cfda7f145d6ffd2fdd76659348056f1828c9.zip
eunit: Do not call erlang:get_stacktrace()
-rw-r--r--lib/eunit/src/eunit_lib.erl4
-rw-r--r--lib/eunit/src/eunit_listener.erl3
-rw-r--r--lib/eunit/src/eunit_proc.erl2
-rw-r--r--lib/eunit/src/eunit_test.erl51
4 files changed, 31 insertions, 29 deletions
diff --git a/lib/eunit/src/eunit_lib.erl b/lib/eunit/src/eunit_lib.erl
index d1bd160ea1..771541354c 100644
--- a/lib/eunit/src/eunit_lib.erl
+++ b/lib/eunit/src/eunit_lib.erl
@@ -202,13 +202,13 @@ format_exception_test_() ->
"\nymmud:rorre"++_,
lists:reverse(lists:flatten(
format_exception(try erlang:error(dummy)
- catch C:R -> {C, R, erlang:get_stacktrace()}
+ catch C:R:S -> {C, R, S}
end)))),
?_assertMatch(
"\nymmud:rorre"++_,
lists:reverse(lists:flatten(
format_exception(try erlang:error(dummy, [a])
- catch C:R -> {C, R, erlang:get_stacktrace()}
+ catch C:R:S -> {C, R, S}
end))))].
-endif.
diff --git a/lib/eunit/src/eunit_listener.erl b/lib/eunit/src/eunit_listener.erl
index e652c5b2f6..75aa05c543 100644
--- a/lib/eunit/src/eunit_listener.erl
+++ b/lib/eunit/src/eunit_listener.erl
@@ -137,8 +137,7 @@ call(F, As, St) when is_atom(F) ->
try apply(St#state.callback, F, As) of
Substate -> St#state{state = Substate}
catch
- Class:Term ->
- Trace = erlang:get_stacktrace(),
+ Class:Term:Trace ->
if F =/= terminate ->
call(terminate, [{error, {Class, Term, Trace}},
St#state.state], St);
diff --git a/lib/eunit/src/eunit_proc.erl b/lib/eunit/src/eunit_proc.erl
index e075005238..96bdcf88b6 100644
--- a/lib/eunit/src/eunit_proc.erl
+++ b/lib/eunit/src/eunit_proc.erl
@@ -628,7 +628,7 @@ io_request({put_chars, M, F, As}, Buf) ->
try apply(M, F, As) of
Chars -> {ok, [Chars | Buf]}
catch
- C:T -> {{error, {C,T,erlang:get_stacktrace()}}, Buf}
+ C:T:S -> {{error, {C,T,S}}, Buf}
end;
io_request({put_chars, _Enc, Chars}, Buf) ->
io_request({put_chars, Chars}, Buf);
diff --git a/lib/eunit/src/eunit_test.erl b/lib/eunit/src/eunit_test.erl
index 6036537178..6fe85ae70a 100644
--- a/lib/eunit/src/eunit_test.erl
+++ b/lib/eunit/src/eunit_test.erl
@@ -39,11 +39,11 @@
%% somewhat, but you can't have everything.) Note that we assume that
%% this particular module is the boundary between eunit and user code.
-get_stacktrace() ->
- get_stacktrace([]).
+get_stacktrace(Trace) ->
+ get_stacktrace(Trace, []).
-get_stacktrace(Ts) ->
- eunit_lib:uniq(prune_trace(erlang:get_stacktrace(), Ts)).
+get_stacktrace(Trace, Ts) ->
+ eunit_lib:uniq(prune_trace(Trace, Ts)).
-dialyzer({no_match, prune_trace/2}).
prune_trace([{eunit_data, _, _} | Rest], Tail) ->
@@ -75,8 +75,8 @@ run_testfun(F) ->
{eunit_internal, Term} ->
%% Internally generated: re-throw Term (lose the trace)
throw(Term);
- Class:Reason ->
- {error, {Class, Reason, get_stacktrace()}}
+ Class:Reason:Trace ->
+ {error, {Class, Reason, Trace}}
end.
@@ -272,7 +272,7 @@ mf_wrapper(M, F) ->
fun () ->
try M:F()
catch
- error:undef ->
+ error:undef:Trace ->
%% Check if it was M:F/0 that was undefined
case erlang:module_loaded(M) of
false ->
@@ -282,14 +282,14 @@ mf_wrapper(M, F) ->
false ->
fail({no_such_function, {M,F,0}});
true ->
- rethrow(error, undef, [{M,F,0}])
+ rethrow(error, undef, Trace, [{M,F,0}])
end
end
end
end.
-rethrow(Class, Reason, Trace) ->
- erlang:raise(Class, Reason, get_stacktrace(Trace)).
+rethrow(Class, Reason, Trace, Ts) ->
+ erlang:raise(Class, Reason, get_stacktrace(Trace, Ts)).
fail(Term) ->
throw({eunit_internal, Term}).
@@ -332,12 +332,14 @@ enter_context(Setup, Cleanup, Instantiate, Callback) ->
T ->
case eunit_lib:is_not_test(T) of
true ->
- catch throw(error), % generate a stack trace
+ {_, Stacktrace} =
+ erlang:process_info(self(),
+ current_stacktrace),
{module,M} = erlang:fun_info(Instantiate, module),
{name,N} = erlang:fun_info(Instantiate, name),
{arity,A} = erlang:fun_info(Instantiate, arity),
context_error({bad_instantiator, {{M,N,A},T}},
- error, badarg);
+ error, Stacktrace, badarg);
false ->
ok
end,
@@ -346,21 +348,22 @@ enter_context(Setup, Cleanup, Instantiate, Callback) ->
%% Always run cleanup; client may be an idiot
try Cleanup(R)
catch
- Class:Term ->
- context_error(cleanup_failed, Class, Term)
+ Class:Term:Trace ->
+ context_error(cleanup_failed,
+ Class, Trace, Term)
end
end
catch
- Class:Term ->
- context_error(instantiation_failed, Class, Term)
+ Class:Term:Trace ->
+ context_error(instantiation_failed, Class, Trace, Term)
end
catch
- Class:Term ->
- context_error(setup_failed, Class, Term)
+ Class:Term:Trace ->
+ context_error(setup_failed, Class, Trace, Term)
end.
-context_error(Type, Class, Term) ->
- throw({context_error, Type, {Class, Term, get_stacktrace()}}).
+context_error(Type, Class, Trace, Term) ->
+ throw({context_error, Type, {Class, Term, get_stacktrace(Trace)}}).
%% This generates single setup/cleanup functions from a list of tuples
%% on the form {Tag, Setup, Cleanup}, where the setup function always
@@ -378,8 +381,8 @@ multi_setup([{Tag, S, C} | Es], CleanupPrev) ->
try C(R) of
_ -> CleanupPrev(Rs)
catch
- Class:Term ->
- throw({Tag, {Class, Term, get_stacktrace()}})
+ Class:Term:Trace ->
+ throw({Tag, {Class, Term, Trace}})
end
end,
{SetupRest, CleanupAll} = multi_setup(Es, Cleanup),
@@ -388,9 +391,9 @@ multi_setup([{Tag, S, C} | Es], CleanupPrev) ->
R ->
SetupRest([R|Rs])
catch
- Class:Term ->
+ Class:Term:Trace ->
CleanupPrev(Rs),
- throw({Tag, {Class, Term, get_stacktrace()}})
+ throw({Tag, {Class, Term, Trace}})
end
end,
CleanupAll};