Macos 您能否在DTrace中以多CPU安全的方式比较探测器之间的值?
我正在尝试编写一个DTrace脚本,它执行以下操作:Macos 您能否在DTrace中以多CPU安全的方式比较探测器之间的值?,macos,dtrace,Macos,Dtrace,我正在尝试编写一个DTrace脚本,它执行以下操作: 每当新线程启动时,递增一个计数 每当其中一个线程退出时,减小计数,如果计数现在为零,则退出脚本 我有这样的想法: BEGIN { threads_alive = 0; } proc:::lwp-start /execname == $$1/ { self->started = timestamp; threads_alive += 1; } proc:::lwp-exit /self->started/ { t
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\u alive
是一个标量变量,因此它不是多cpu安全的。因此,多个线程将覆盖彼此对变量的更改
我还尝试使用聚合变量:
@thread_count = sum(1)
//or
@threads_entered = count();
@threads_exitted = count();
不幸的是,我还没有发现语法能够像
@thread\u count==0
或@threads\u start==@threads\u stopped
DTrace没有实现您建议的线程安全数据共享的功能,但是您有一些选项,具体取决于您尝试执行的操作
如果可执行文件名是唯一的,则可以分别使用proc:::start
和proc:::exit
探测第一个线程的开始和最后一个线程的退出:
proc:::start
/execname == $$1/
{
my_pid = pid;
}
proc:::exit
/pid == my_pid/
{
exit(0);
}
如果您正在使用-c
选项来dtrace
,则BEGIN
探测会在相应的proc:::start
后很快触发。在内部,dtrace-c
启动指定的fork和指定的命令,然后在以下四点之一开始跟踪:exec
(在新程序的第一条指令之前)、preinit
(在ld加载所有库之后)、postinit
(在每个库的\u init
运行之后),或main
(就在程序的main
功能的第一条指令之前,尽管macOS不支持该功能)
如果使用dtrace-x evaltime=exec-c
BEGIN
将在程序的第一条指令执行之前立即触发:
# dtrace -xevaltime=exec -c /usr/bin/true -n 'BEGIN{ts = timestamp}' -n 'pid$target:::entry{printf("%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是由于在macOS上通过
/proc
或ptrace(2)
恢复过程所需的时间。您可以使用BEGIN
,pid$target::\u dyld\u start:entry
,而不是proc:::start
或pid$target::main:entryDTrace没有实现此处建议的线程安全数据共享的功能。你能提供一点关于你想做什么的背景吗?proc:exit/execname=$$1/{exit(0)}
是否有效?-c
或-p
选项是否已经满足了您的要求?@ahl谢谢,这很有意义。我希望在进程启动之前有dtrace start,这样它就可以捕获该进程的lwp启动探测(至少在MacOS上使用-c
时似乎不会发生这种情况)。然后我开始这个过程,观察它直到结束,在这一点上我希望dtrace退出。似乎proc:::exit可以工作,只要我不多次运行该进程(我不打算这么做)。如果你愿意,写下来作为答案,我会接受,或者我会写一个答案。