erlang的替代方案:get_stacktrace/0获取函数调用方的信息?

erlang的替代方案:get_stacktrace/0获取函数调用方的信息?,erlang,Erlang,我正在研究一个函数,该函数是从我们现有代码库中相对热门的代码路径调用的。该函数要做的第一件事是在try-catch块内调用erlang:get_stacktrace/0,以便我们可以获得stacktrace: the_function() -> [_|Trace] = try error(x) of _ -> error(impossible) catch error:x -> erlang:get_stacktrace() end,

我正在研究一个函数,该函数是从我们现有代码库中相对热门的代码路径调用的。该函数要做的第一件事是在try-catch块内调用
erlang:get_stacktrace/0
,以便我们可以获得stacktrace:

the_function() ->  
  [_|Trace] = try error(x) of
     _ -> error(impossible)
  catch 
     error:x -> erlang:get_stacktrace()
  end,
  ...

我们保留stacktrace,以便获得函数调用方的信息。我已经读到,erlang:get_stacktrace/0调用起来并不总是一个便宜的函数()。因为这是一个热门的代码路径,我想用更简单的东西来代替它。是否有其他方法可以获取调用函数的信息,如模块和函数名、行号等。。。如果您需要知道从何处被调用,则不必调用
get\u stacktrace

那么
get\u stacktrace
可能不够,因为调用方可能已在堆栈外进行了优化

相反,我会考虑这样的事情:

the_function(Normal, Args, {Module, Line}) ->
  try something(Normal, Args)
  catch error:x -> print_error(Module, Line).

-define(?the_function(Normal, Args), the_function(Normal, Args, {?MODULE, ?LINE})).
现在,您可以将所有对_函数的调用更改为_函数,并在编译时为您添加第三个参数


您可以通过解析转换来实现更复杂的版本。

问题假设获取有关调用方的信息是绝对必要的。你为什么需要它?您是在任何时候都需要它,还是仅在发生错误时才需要它?你到底想完成什么?您是否考虑过要求调用方仅将所需信息作为参数传递?@SteveVinoski我正在使用现有的代码库,是的,关于调用方的信息是一项要求。我可以更新代码,使所需的调用方信息可以作为另一个参数传递。这将涉及更新多个调用函数,这是我希望避免的。我听说erlang:process\u info/2可能会给我相同的信息,而且打电话可能比获取跟踪便宜。有什么想法吗?如果它是一个看起来很热门的函数,我建议尽可能地简化它,即使这意味着调用方必须做额外的工作来调用它。我不知道改为调用
process\u info/2
是否会更好;您必须对此进行测量以确保。@SteveVinoski它看起来确实比
get\u stacktrace/0
更有效,至少在我的测试中是这样。@SteveVinoski我认为您的第一个建议可能是最好的解决方案。我会让打电话的人再传一个论点。谢谢我做了一些跟踪来验证调用方实际上是stacktrace的一部分。看起来在所有情况下,调用函数都存在于stacktrace中。使用宏会使调用函数的更改更简单,但这仍然是一个我不愿做的更改。根据我的测试,现在看起来流程信息可能足够了,而且速度稍微快一点。