diff options
author | José Valim <jose.valim@plataformatec.com.br> | 2017-05-21 11:13:28 +0200 |
---|---|---|
committer | José Valim <jose.valim@plataformatec.com.br> | 2017-05-21 11:13:28 +0200 |
commit | 8ae596cef52eae2c22af8008aac835229541000d (patch) | |
tree | 81d6d87676a3674796a387bbb1088e34aecda50a | |
parent | 1930bb62ecb73761e57bbfa138a11b172feaf67a (diff) | |
download | elixir-8ae596cef52eae2c22af8008aac835229541000d.tar.gz |
Ensure safe stacktrace use in Exception
-rw-r--r-- | lib/elixir/lib/exception.ex | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/lib/elixir/lib/exception.ex b/lib/elixir/lib/exception.ex index 343e89036..315fad931 100644 --- a/lib/elixir/lib/exception.ex +++ b/lib/elixir/lib/exception.ex @@ -140,7 +140,6 @@ defmodule Exception do Note that `{:EXIT, pid}` do not generate a stacktrace though (as they are retrieved as messages without stacktraces). """ - @spec format(kind, any, stacktrace | nil) :: String.t def format(kind, payload, stacktrace \\ nil) @@ -883,7 +882,7 @@ defmodule ErlangError do def normalize({:badkey, key}, stacktrace) do term = - case stacktrace || :erlang.get_stacktrace do + case stacktrace(stacktrace) do [{Map, :get_and_update!, [map, _, _], _} | _] -> map [{Map, :update!, [map, _, _], _} | _] -> map [{:maps, :update, [_, _, map], _} | _] -> map @@ -910,13 +909,13 @@ defmodule ErlangError do end def normalize(:undef, stacktrace) do - stacktrace = stacktrace || :erlang.get_stacktrace + stacktrace = stacktrace(stacktrace) {mod, fun, arity} = from_stacktrace(stacktrace) %UndefinedFunctionError{module: mod, function: fun, arity: arity} end def normalize(:function_clause, stacktrace) do - {mod, fun, arity} = from_stacktrace(stacktrace || :erlang.get_stacktrace) + {mod, fun, arity} = from_stacktrace(stacktrace(stacktrace)) %FunctionClauseError{module: mod, function: fun, arity: arity} end @@ -928,6 +927,18 @@ defmodule ErlangError do %ErlangError{original: other} end + defp stacktrace(nil) do + try do + :erlang.get_stacktrace() + rescue + _ -> [] + end + end + + defp stacktrace(stacktrace) do + stacktrace + end + defp from_stacktrace([{module, function, args, _} | _]) when is_list(args) do {module, function, length(args)} end |