9

dtruss手册页说:

       -f     follow children as they are forked

这听起来正是我想要的。但是,请注意以下行为:

WhiteAndNerdy% uname -a
Darwin WhiteAndNerdy.local 13.4.0 Darwin Kernel Version 13.4.0: Wed Dec 17 19:05:52 PST 2014; root:xnu-2422.115.10~1/RELEASE_X86_64 x86_64
WhiteAndNerdy% sudo dtruss -f -t writev /bin/echo hello world
hello world
    PID/THRD  SYSCALL(args)          = return
37273/0x90e264:  writev(0x1, 0x7F8832D00000, 0x4)        = 12 0

WhiteAndNerdy% sudo dtruss -f -t writev sh -c '/bin/echo hello world'
    PID/THRD  SYSCALL(args)          = return

WhiteAndNerdy% sudo dtruss -f -t writev bash -c '/bin/echo hello world'
    PID/THRD  SYSCALL(args)          = return

WhiteAndNerdy% sudo dtruss -f -t writev zsh -c '/bin/echo hello world'
    PID/THRD  SYSCALL(args)          = return
37295/0x90e39b:  fork()      = 0 0

WhiteAndNerdy% sudo dtruss -f -t writev env /bin/echo hello world
    PID/THRD  SYSCALL(args)          = return

WhiteAndNerdy%

请注意,除了第一种情况,不打印“hello world”。(这不仅仅是看不到输出的问题;如果我运行一个需要很长时间的过程,在sh -c类似情况下它不会花费任何时间。在我所做的所有实验中,它似乎执行只是在第一个停止exec。)

所以,我很困惑到底做了什么dtruss -f。我怎样才能让它像strace -f在 Linux 上一样运行,它可以满足我的需求?

动机:我正在 OS X 上进行一些 Haskell 开发,并想跟踪运行期间发生的情况cabal(Haskell 的构建系统)。在 cabal 上运行dtruss -f什么都不做就返回了,因为在 OS X 版本的 Haskell 平台中,/usr/bin/cabal是一个 shell 脚本,它exec是 s /Library/Haskell/bin/cabal.real。当然,我可以通过直接运行来解决这个问题/Library/Haskell/bin/cabal.real,但这仍然对我没有多大帮助,因为cabal.real只是要转身和exec一堆其他东西。(想想make如果你不熟悉 Haskell。)

4

1 回答 1

-4

鉴于 dtruss 只是一个高级 dtrace 脚本,您可以轻松编写自己的脚本并捕获所有 fork/exec 调用,在这些新分叉的进程上生成新的 dtrace 脚本并跟踪它们。另一个选项是 -W 选项检查 man dtrace。

于 2018-06-08T07:45:48.287 回答