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

Macos 为什么我的dtruss跟踪中没有任何execve调用?,macos,dtrace,dtruss,Macos,Dtrace,Dtruss,我有这样一个脚本: script.sh #!/bin/bash clang -v 如果我对它执行dtruss,那么我会看到execve调用clang $ sudo dtruss -f -a -e ./script.sh 但是,跟踪不包含execve。而是出现了一个错误: ... 1703/0x16931: 856 4 0 sigaction(0x15, 0x7FFEE882A3B8, 0x7FFEE882A3F8) = 0 0 1703/0

我有这样一个脚本:

script.sh

#!/bin/bash

clang -v
如果我对它执行
dtruss
,那么我会看到
execve
调用
clang

$ 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
    命令显示,以便查看调用的程序及其参数
      这意味着
      dtruss
      内部使用的DTrace脚本正在访问无效的内存地址,这是在它试图跟踪您感兴趣的
      execve
      调用时发生的。因此,基本上,
      dtrus
      (或者可能是DTrace本身)似乎有一个bug,阻止您获取所需的信息。不幸的是,苹果在保持DTrace和依赖它的工具在macOS上正常运行方面并不是最好的

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

      如果您愿意,您也可以尝试直接使用DTrace——这是一个非常简单的单行程序(我自己还没有尝试过运行它,因此如果出现拼写错误,请道歉):

      其工作方式是:

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

      (如果失败并出现类似的错误,则可能是macOS的
      curpsinfo
      实现中的某个地方出现了错误。)

      回答得好。我认为,这里问题的实际原因是,
      dtruss
      在进入
      execve
      系统调用时抓取
      execve
      arg0
      (路径指针),然后在退出
      execve
      系统调用时尝试将其打印为字符串指针。但是由于
      execve
      完全替换了进程的地址空间,因此在系统调用后指针不再有效。由于指针在成功的
      execve
      中无效,
      dtrus
      需要(但缺少)一个针对
      execve
      系统调用的特殊情况。啊,真的!我一直认为这是一个编译过的程序,不是脚本,所以我不知道你能读懂源代码。作为参考,我也在这里在线找到了它:。
      sudo dtrace -n 'proc:::exec-success /ppid == $target/ { trace(curpsinfo->pr_psargs); }' -c './script.sh'