Elixir stacktraces是否包含所有输入的功能?

Elixir stacktraces是否包含所有输入的功能?,elixir,Elixir,我正在研究一个问题,一个长生不老药博士后司机 然而,我被下面的跟踪弄糊涂了。(为了便于阅读,我只删除了msg\u recv/4的冗长参数) 16:52:54.323[错误]GenServer#PID终止 **(FunctionClauseError)Postgrex.Protocol.msg_recv/4中没有匹配的函数子句 (postgrex 0.15.5)lib/postgrex/protocol.ex:2837:postgrex.protocol.msg_recv(…SNIP) (post

我正在研究一个问题,一个长生不老药博士后司机

然而,我被下面的跟踪弄糊涂了。(为了便于阅读,我只删除了
msg\u recv/4
的冗长参数)

16:52:54.323[错误]GenServer#PID终止
**(FunctionClauseError)Postgrex.Protocol.msg_recv/4中没有匹配的函数子句
(postgrex 0.15.5)lib/postgrex/protocol.ex:2837:postgrex.protocol.msg_recv(…SNIP)
(postgrex 0.15.5)lib/postgrex/protocol.ex:816:postgrex.protocol.bootstrap_recv/4
(postgrex 0.15.5)lib/postgrex/protocol.ex:579:postgrex.protocol.handshake/2
(db_connection 2.1.0)lib/db_connection/connection.ex:69:DBConnection.connection.connection/2
(连接1.0.4)lib/connection.ex:622:connection.enter_connect/5
(stdlib 3.12.1)proc_lib.erl:249::proc_lib.init_p_do_apply/3
最后信息:无
国家:Postgrex.协议
stacktrace显示为
handshake/2
调用
bootstrap\u recv/4
,但
handshake/2
中没有直接调用
bootstrap\u recv/4

实际上是在
handshake/2
中,是对
do\u handshake/2
的调用,其中有一些本身调用
ssl/2
startup/2

我找不到此代码路径中调用
bootstrap\u recv/4
的位置

为什么
握手/2
ssl/2
startup/2
(以及任何后续调用导致
bootstrap\u recv/4
并最终导致
msg\u recv/4
)不在堆栈跟踪中


大概是我误解了Elixir stacktraces。

编辑:对于一般问题,提出这样一个详细的问题是很遗憾的,但我会留下这个问题,以防有人通过调试遇到这种情况

不,由于Erlang VM,Elixir中的stacktraces不包含所有输入的函数。我在长生不老药论坛的一篇文章中发现了这一点。这篇文章也提到了这一点

erlang问题
邮件列表中,Joe Armstrong提到erlang将其称为“”,并给出了解释

下面的代码用几行简单的代码来防止尾部调用,说明了这一区别

defmodule Demo do
  def first() do
    second()

    # Uncomment to prevent tail-call, and `first` appears in the stacktrace.
    # case second() do
    #   _ -> {:ok, 0}
    # end
  end

  # Elixir knows third() is still a tail-call.
  def second() do
    r = third()
    _ = 1 + 1
    # dummy() # Uncomment to prevent tail-call, and `second` appears in the stacktrace.
    r
  end

  def third() do
    IO.inspect(Process.info(self(), :current_stacktrace))
    {:ok, 0}
  end

  defp dummy, do: nil
end

IO.inspect(Demo.first)
stacktrace中的结果:

{:current_stacktrace,
 [
   {Process, :info, 2, [file: 'lib/process.ex', line: 765]},
   {Demo, :third, 0, [file: 'demo.exs', line: 21]},
   {:elixir_compiler_0, :__FILE__, 1, [file: 'demo.exs', line: 30]},
   {:elixir_compiler, :dispatch, 4, [file: 'src/elixir_compiler.erl', line: 75]},
   {:elixir_compiler, :compile, 3, [file: 'src/elixir_compiler.erl', line: 60]},
   {:elixir_lexical, :run, 3, [file: 'src/elixir_lexical.erl', line: 15]},
   {:elixir_compiler, :quoted, 3, [file: 'src/elixir_compiler.erl', line: 18]}
 ]}
{:ok, 0}
{:current_stacktrace,
 [
   {Process, :info, 2, [file: 'lib/process.ex', line: 765]},
   {Demo, :third, 0, [file: 'demo.exs', line: 20]},
   {Demo, :second, 0, [file: 'demo.exs', line: 13]},
   {Demo, :first, 0, [file: 'demo.exs', line: 6]},
   {:elixir_compiler_0, :__FILE__, 1, [file: 'demo.exs', line: 29]},
   {:elixir_compiler, :dispatch, 4, [file: 'src/elixir_compiler.erl', line: 75]},
   {:elixir_compiler, :compile, 3, [file: 'src/elixir_compiler.erl', line: 60]}
 ]}
{:ok, 0}
在同一代码中调整注释行(如上所述)会导致stacktrace:

{:current_stacktrace,
 [
   {Process, :info, 2, [file: 'lib/process.ex', line: 765]},
   {Demo, :third, 0, [file: 'demo.exs', line: 21]},
   {:elixir_compiler_0, :__FILE__, 1, [file: 'demo.exs', line: 30]},
   {:elixir_compiler, :dispatch, 4, [file: 'src/elixir_compiler.erl', line: 75]},
   {:elixir_compiler, :compile, 3, [file: 'src/elixir_compiler.erl', line: 60]},
   {:elixir_lexical, :run, 3, [file: 'src/elixir_lexical.erl', line: 15]},
   {:elixir_compiler, :quoted, 3, [file: 'src/elixir_compiler.erl', line: 18]}
 ]}
{:ok, 0}
{:current_stacktrace,
 [
   {Process, :info, 2, [file: 'lib/process.ex', line: 765]},
   {Demo, :third, 0, [file: 'demo.exs', line: 20]},
   {Demo, :second, 0, [file: 'demo.exs', line: 13]},
   {Demo, :first, 0, [file: 'demo.exs', line: 6]},
   {:elixir_compiler_0, :__FILE__, 1, [file: 'demo.exs', line: 29]},
   {:elixir_compiler, :dispatch, 4, [file: 'src/elixir_compiler.erl', line: 75]},
   {:elixir_compiler, :compile, 3, [file: 'src/elixir_compiler.erl', line: 60]}
 ]}
{:ok, 0}

编辑:对于一般问题来说,这样一个详细的问题是很遗憾的,但我会留下这个问题,以防有人通过调试遇到这种情况

不,由于Erlang VM,Elixir中的stacktraces不包含所有输入的函数。我在长生不老药论坛的一篇文章中发现了这一点。这篇文章也提到了这一点

erlang问题
邮件列表中,Joe Armstrong提到erlang将其称为“”,并给出了解释

下面的代码用几行简单的代码来防止尾部调用,说明了这一区别

defmodule Demo do
  def first() do
    second()

    # Uncomment to prevent tail-call, and `first` appears in the stacktrace.
    # case second() do
    #   _ -> {:ok, 0}
    # end
  end

  # Elixir knows third() is still a tail-call.
  def second() do
    r = third()
    _ = 1 + 1
    # dummy() # Uncomment to prevent tail-call, and `second` appears in the stacktrace.
    r
  end

  def third() do
    IO.inspect(Process.info(self(), :current_stacktrace))
    {:ok, 0}
  end

  defp dummy, do: nil
end

IO.inspect(Demo.first)
stacktrace中的结果:

{:current_stacktrace,
 [
   {Process, :info, 2, [file: 'lib/process.ex', line: 765]},
   {Demo, :third, 0, [file: 'demo.exs', line: 21]},
   {:elixir_compiler_0, :__FILE__, 1, [file: 'demo.exs', line: 30]},
   {:elixir_compiler, :dispatch, 4, [file: 'src/elixir_compiler.erl', line: 75]},
   {:elixir_compiler, :compile, 3, [file: 'src/elixir_compiler.erl', line: 60]},
   {:elixir_lexical, :run, 3, [file: 'src/elixir_lexical.erl', line: 15]},
   {:elixir_compiler, :quoted, 3, [file: 'src/elixir_compiler.erl', line: 18]}
 ]}
{:ok, 0}
{:current_stacktrace,
 [
   {Process, :info, 2, [file: 'lib/process.ex', line: 765]},
   {Demo, :third, 0, [file: 'demo.exs', line: 20]},
   {Demo, :second, 0, [file: 'demo.exs', line: 13]},
   {Demo, :first, 0, [file: 'demo.exs', line: 6]},
   {:elixir_compiler_0, :__FILE__, 1, [file: 'demo.exs', line: 29]},
   {:elixir_compiler, :dispatch, 4, [file: 'src/elixir_compiler.erl', line: 75]},
   {:elixir_compiler, :compile, 3, [file: 'src/elixir_compiler.erl', line: 60]}
 ]}
{:ok, 0}
在同一代码中调整注释行(如上所述)会导致stacktrace:

{:current_stacktrace,
 [
   {Process, :info, 2, [file: 'lib/process.ex', line: 765]},
   {Demo, :third, 0, [file: 'demo.exs', line: 21]},
   {:elixir_compiler_0, :__FILE__, 1, [file: 'demo.exs', line: 30]},
   {:elixir_compiler, :dispatch, 4, [file: 'src/elixir_compiler.erl', line: 75]},
   {:elixir_compiler, :compile, 3, [file: 'src/elixir_compiler.erl', line: 60]},
   {:elixir_lexical, :run, 3, [file: 'src/elixir_lexical.erl', line: 15]},
   {:elixir_compiler, :quoted, 3, [file: 'src/elixir_compiler.erl', line: 18]}
 ]}
{:ok, 0}
{:current_stacktrace,
 [
   {Process, :info, 2, [file: 'lib/process.ex', line: 765]},
   {Demo, :third, 0, [file: 'demo.exs', line: 20]},
   {Demo, :second, 0, [file: 'demo.exs', line: 13]},
   {Demo, :first, 0, [file: 'demo.exs', line: 6]},
   {:elixir_compiler_0, :__FILE__, 1, [file: 'demo.exs', line: 29]},
   {:elixir_compiler, :dispatch, 4, [file: 'src/elixir_compiler.erl', line: 75]},
   {:elixir_compiler, :compile, 3, [file: 'src/elixir_compiler.erl', line: 60]}
 ]}
{:ok, 0}