summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@plataformatec.com.br>2017-05-21 11:13:28 +0200
committerJosé Valim <jose.valim@plataformatec.com.br>2017-05-21 11:13:28 +0200
commit8ae596cef52eae2c22af8008aac835229541000d (patch)
tree81d6d87676a3674796a387bbb1088e34aecda50a
parent1930bb62ecb73761e57bbfa138a11b172feaf67a (diff)
downloadelixir-8ae596cef52eae2c22af8008aac835229541000d.tar.gz
Ensure safe stacktrace use in Exception
-rw-r--r--lib/elixir/lib/exception.ex19
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