0

我有一个带有函数的模块 my_api,它是牛仔请求句柄/2 的回调,所以当我发出一些这样的 http 请求时:

curl http://localhost/test

对于我的应用程序,此函数被调用并且它工作正常,因为我在终端中得到了响应。

但是在另一个终端中,我使用 remsh 附加到我的应用程序,并尝试使用这样的 dbg 模块跟踪对该函数的调用:

dbg:tracer().
dbg:tp(my_api, handle, 2, []).
dbg:p(all, c).

我希望在另一个终端向我的 api 发出 http 请求后,调用函数 my_api:handle/2 并在附加到节点终端中获得有关此调用的一些信息(至少是函数参数),但我什么也没得到在那里。我错过了什么?

4

1 回答 1

1

当您调用dbg:tracer/0时,类型的跟踪器将process使用消息处理程序启动,该消息处理程序将所有跟踪消息发送到userI/O 设备。您的远程 shell 的组长独立于userI/O 设备,因此您的 shell 不会接收发送到user.

允许您查看跟踪输出的一种方法是在服务器上设置跟踪端口,在单独的节点中设置跟踪客户端。如果你想从 node 跟踪foo,首先 remsh 到它:

$ erl -sname bar -remsh foo

然后设置一个跟踪端口。在这里,我们在主机端口 50000 上设置了一个 TCP/IP 跟踪端口(使用您喜欢的任何端口,只要它对您可用):

1> dbg:tracer(port, dbg:trace_port(ip, 50000)).

接下来,像以前一样设置跟踪参数:

2> dbg:tp(my_api, handle, 2, []).
{ok, ...}
3> dbg:p(all, c).
{ok, ...}

然后退出remsh,启动一个没有remsh的节点:

$ erl -sname bar

在此节点上,启动连接到主机端口 50000 的 TCP/IP 跟踪客户端:

1> dbg:trace_client(ip, {"localhost", 50000}).

此 shell 现在将接收dbg来自foo. 在这里,我们用作"localhost"主机名,因为该节点与服务器节点在同一主机上运行,​​但如果您的客户端在单独的主机上运行,​​则需要使用不同的主机名。

另一种方法更简单,但依赖于未记录的函数,因此将来可能会中断,即 remsh 到要跟踪的节点,就像您最初所做的那样,然后用于dbg:tracer/2dbg输出发送到远程 shell 的组长:

1> dbg:tracer(process, {fun dbg:dhandler/2, group_leader()}).
{ok, ...}
2> dbg:tp(my_api, handle, 2, []).
{ok, ...}
3> dbg:p(all, c).
{ok, ...}

由于这依赖于dbg:dhandler/2已导出但未记录的函数,因此无法保证它始终有效。

最后,由于您正在跟踪所有进程,请注意dbg手册页中描述的潜在问题,并确保dbg:stop_clear().在完成跟踪后调用。

于 2022-01-30T19:12:03.207 回答