使用erlang跟踪事件消息:trace_delivered / 1

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用erlang跟踪事件消息:trace_delivered / 1相关的知识,希望对你有一定的参考价值。

我试图理解erlang:trace_delivered/1的确切语义,以确定此函数是否适合用于解决我目前面临的问题。问题如下。

假设有一个跟踪过程X,跟踪Y的示踪剂X和第三个过程Z。 Tracer Y最初追踪X。进程Z的任务是通过调用Y来阻止X跟踪erlang:trace(X, false)。当Z正在运行时,这个调用由X任意影响。此后,Z也将向追踪者stopped发出特别消息Y,向Y发出信号表明Z确实阻止了Y追踪X

我想保证在将所有其他跟踪消息发送到stopped之后,特殊的Y消息被发送到Y的邮箱。据我所知,Erlang不保证将不同进程发送的消息排序到单个进程。具体来说,在我的情况下,这意味着示踪剂Y可以,例如,由于tracee stopped在跟踪事件消息之前接收Z发布的X。我读了关于erlang:trace_delivered/1,并计划在Z的实现中使用以下代码来解决我的问题:

...
erlang:trace(X, false),
Ref = erlang:trace_delivered(X),
receive
  {trace_delivered, X, Ref} ->
    Y ! stopped
end.
...

docs中提供了一个类似的例子(引用如下):

示例:处理A是Tracee,端口B是跟踪器,并且进程CB的端口所有者。当C退出时,B想要关闭A。为确保跟踪不被截断,C可以在erlang:trace_delivered(A)退出时调用A,并在关闭{trace_delivered, A, Ref}之前等待消息B

我的例子与文档中的例子有两个不同之处:

  1. 在调用C之前,进程A知道erlang:trace_delivered(A)的确切执行点;在我的情况下,我不知道当X调用erlang:trace_delivered(X)Z的意思。
  2. 与处理C相比,我的进程Z在调用X之前关闭了erlang:trace_delivered(X)上的跟踪。

在这种情况下,erlang:trace_delivered/1的语义是什么?

  1. 在将所有跟踪消息传递给跟踪器{trace_delivered, X, Ref}之后,它是否仍然保证Z被进程Y接收?
  2. erlang:trace_delivered/1是否会自动跟踪tracee X的执行点,以便能够提供上述保证?

非常感谢您的帮助!

答案

你对消息的排序是正确的。如果进程A发送多条消息来处理B,它们将保证按顺序到达。如果A向进程BC发送多条消息,则只能保证每个进程的消息顺序。例如:

  • A发送B消息1
  • A发送C消息2
  • A发送B消息3
  • A发送C消息4

在这种情况下唯一的保证是B将在消息3之前接收消息1,并且C将在消息4之前接收消息2。

回答你的问题:

  1. 不,如果在生成其他跟踪事件之前调用erlang:trace_delivered/1,则这些消息将在稍后到达。文档仅保证先前跟踪消息在{trace_delivered, ...}之前传递: 当保证所有跟踪消息都被传递到跟踪器,直到Tracee在调用erlang:trace_delivered(Tracee)时到达的点,然后将{trace_delivered,Tracee,Ref}消息发送给调用者。 erlang:trace_delivered(Tracee)。
  2. erlang:trace_delivered/1周围的保证总是适用。但它并不能保证{trace_delivered, ...}永远是最后的信息。

以上是关于使用erlang跟踪事件消息:trace_delivered / 1的主要内容,如果未能解决你的问题,请参考以下文章

Erlang Tracing:因果一致性?

对讲跟踪事件自动发送自动消息

如何在 Erlang 中使用 trace 和 dbg 来调试和跟踪我的程序?

Erlang堆栈跟踪中包含多少条目?

ini Logstash配置使用编解码器多线解析Scala / Java日志,以将异常和堆栈跟踪消息连接到单个事件和gro中

ini Logstash配置使用编解码器多线解析Scala / Java日志,以将异常和堆栈跟踪消息连接到单个事件和gro中