您可以在 DTrace 中以多 CPU 安全的方式比较探针之间的值吗?
Posted
技术标签:
【中文标题】您可以在 DTrace 中以多 CPU 安全的方式比较探针之间的值吗?【英文标题】:Can you compare values across probes in a multi-CPU safe way in DTrace? 【发布时间】:2020-05-28 15:26:29 【问题描述】:我正在尝试编写一个执行以下操作的 DTrace 脚本:
-
每当启动一个新线程时,就增加一个计数。
每当这些线程之一退出时,减少计数,如果计数现在为零,则退出脚本。
我有这样的事情:
BEGIN
threads_alive = 0;
proc:::lwp-start /execname == $$1/
self->started = timestamp;
threads_alive += 1;
proc:::lwp-exit /self->started/
threads_alive -= 1;
if (threads_alive == 0)
exit(0);
但是,这不起作用,因为threads_alive
是一个标量变量,因此它不是多 CPU 安全的。这样一来,多个线程会互相覆盖对方对变量的更改。
我也尝试过使用聚合变量:
@thread_count = sum(1)
//or
@threads_entered = count();
@threads_exitted = count();
不幸的是,我还没有找到能够执行 @thread_count == 0
或 @threads_started == @threads_stopped
之类的语法。
【问题讨论】:
DTrace 不具备执行您在此处提议的那种线程安全数据共享的设施。你能提供更多关于你想要做什么的背景吗?proc:exit/execname == $$1/ exit(0)
会工作吗? -c
或 -p
选项是否已经满足您的需求?
@ahl 谢谢,这是有道理的。我希望在进程启动之前启动 dtrace,以便它可以捕获该进程的 lwp-start 探测(当我使用-c
时似乎不会发生这种情况,至少在 MacOS 上是这样)。然后我开始这个过程,并观察它直到它结束,此时我希望 dtrace 退出。 proc:::exit 似乎有效,只要我不多次运行该进程(我不打算这样做)。如果您愿意,请将其写为答案,我会接受,或者我会写一个答案。
【参考方案1】:
DTrace 不具备执行您提议的那种线程安全数据共享的功能,但您有几个选项,具体取决于您要执行的操作。
如果可执行文件名是唯一的,可以使用proc:::start
和proc:::exit
分别探测第一个线程的开始和最后一个线程的退出:
proc:::start
/execname == $$1/
my_pid = pid;
proc:::exit
/pid == my_pid/
exit(0);
如果您对dtrace
使用-c
选项,则BEGIN
探测器会在相应的proc:::start
之后不久触发。在内部,dtrace -c
启动指定的 fork 指定命令,然后在以下四个点之一开始跟踪:exec
(在新程序的第一条指令之前),preinit
(在 ld 加载所有库之后),@987654331 @(在每个库的 _init
运行之后)或 main
(就在程序的 main
函数的第一条指令之前,尽管这在 macOS 中不受支持)。
如果你使用dtrace -x evaltime=exec -c <program>
BEGIN
将在程序的第一条指令执行之前触发:
# dtrace -xevaltime=exec -c /usr/bin/true -n 'BEGINts = timestamp' -n 'pid$target:::entryprintf("%dus", (timestamp - ts)/1000); exit(0); '
dtrace: description 'BEGIN' matched 1 probe
dtrace: description 'pid$target:::entry' matched 1767 probes
dtrace: pid 1848 has exited
CPU ID FUNCTION:NAME
10 16757 _dyld_start:entry 285us
285us 是由于 dtrace
在 macOS 上通过 /proc
或 ptrace(2)
恢复进程所花费的时间。您可以使用BEGIN
、pid$target::_dyld_start:entry
或pid$target::main:entry
,而不是proc:::start
或proc:::lwp-start
。
【讨论】:
以上是关于您可以在 DTrace 中以多 CPU 安全的方式比较探针之间的值吗?的主要内容,如果未能解决你的问题,请参考以下文章