为什么我的dtruss跟踪中没有任何execve调用?

时间:2018-11-15 19:49:16

标签: macos dtrace dtruss

我有一个像这样的脚本:

script.sh

#!/bin/bash

clang -v

如果我在其上执行dtruss,则希望看到execveclang的呼叫。

$ sudo dtruss -f -a -e ./script.sh 

但是,跟踪不包含execve。而是有一个错误:

...
 1703/0x16931:       856       4      0 sigaction(0x15, 0x7FFEE882A3B8, 0x7FFEE882A3F8)      = 0 0
 1703/0x16931:       858       4      0 sigaction(0x16, 0x7FFEE882A3C8, 0x7FFEE882A408)      = 0 0
 1703/0x16931:       874       4      0 sigaction(0x2, 0x7FFEE882A3C8, 0x7FFEE882A408)       = 0 0
 1703/0x16931:       881       4      0 sigaction(0x3, 0x7FFEE882A3C8, 0x7FFEE882A408)       = 0 0
 1703/0x16931:       883       4      0 sigaction(0x14, 0x7FFEE882A3C8, 0x7FFEE882A408)      = 0 0
dtrace: error on enabled probe ID 2149 (ID 280: syscall::execve:return): invalid address (0x7fc2b5502c30) in action #12 at DIF offset 12
 1703/0x16932:      2873:        0:       0 fork()       = 0 0
 1703/0x16932:      2879     138      5 thread_selfid(0x0, 0x0, 0x0)         = 92466 0
 1703/0x16932:      2958       8      0 issetugid(0x0, 0x0, 0x0)         = 0 0
 1703/0x16932:      2975       8      1 csrctl(0x0, 0x7FFEEE21DC3C, 0x4)         = 0 0
 1703/0x16932:      2985      12      6 csops(0x0, 0x0, 0x7FFEEE21E550)      = 0 0
 1703/0x16932:      3100      13      3 shared_region_check_np(0x7FFEEE21DA98, 0x0, 0x0)    
...
  • 是什么导致此错误?
  • 如何显示execve命令,以便可以看到所调用的程序及其参数?

1 个答案:

答案 0 :(得分:2)

这意味着dtruss内部使用的DTrace脚本正在访问无效的内存地址,这种情况是在尝试跟踪您好奇的execve调用时发生的。因此,基本上dtruss(或者可能是DTrace本身)似乎存在一个错误,阻止您获取所需的信息。不幸的是,Apple并不是保持DTrace及其依赖的工具在macOS上运行良好的最佳方式:-/。

特别是对于Bash / shell脚本,您可以通过在脚本顶部添加set -x(更多信息in this other answer)来使其打印运行的每个命令。

如果您愿意,也可以尝试直接使用DTrace-这是一个非常简单的单行代码(如果遇到错别字,请不要尝试自己运行此命令,因此表示歉意):

sudo dtrace -n 'proc:::exec-success /ppid == $target/ { trace(curpsinfo->pr_psargs); }' -c './script.sh'

工作方式是:

  • proc:::exec-success:跟踪系统中的所有exec-success事件,当exec*系列系统调用成功返回时,这些事件会在子进程中触发
  • /ppid == $target/:过滤器,这意味着仅当父流程的PID(ppid)与我们传递给{{1的-c选项启动的流程返回的PID匹配时才会触发}}命令($target)。
  • dtrace:这是事件触发并与我们的过滤器匹配时要采取的措施。我们只需打印({ trace(curpsinfo->pr_psargs); })传递给流程的参数,并将其存储在curpsinfo变量中。

(如果失败并显示类似错误,则该错误可能出在macOS的trace实现中)。