How to get the call stack/stack trace at any point in code?

Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the code got to that point. It will be super helpful to learn how some of the frameworks/libraries work that way.

7 Likes

You could use :erlang.get_stacktrace/0.

5 Likes

doesn’t this only get the stack trace of the last exception? I’d like to way to get the stack trace of any arbitrary line of code.

Process.info(self(), :current_stacktrace)

28 Likes

In my case, I do this:

defmodule Foo do
  require Logger

  defp log_this do
    stacktrace = Process.info(self(), :current_stacktrace) |> elem(1)
    Logger.warn "IMEDIATE CALLER: #{stacktrace |> Enum.at(2) |> Exception.format_stacktrace_entry}"
    Logger.warn "    NEXT CALLER: #{stacktrace |> Enum.at(3) |> Exception.format_stacktrace_entry}"
    "do something"
  end

  def do_something do
    log_this()
    "do something"
  end
  def execute_something do
    do_something()
    "execute_something"
  end
end
iex(1)> Foo.execute_something
10:24:16.528 [warn]  IMEDIATE CALLER: .iex.exs:12: Foo.do_something/0
10:24:16.529 [warn]      NEXT CALLER: .iex.exs:16: Foo.execute_something/0
"execute_something"
6 Likes