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
实际上做了些什么。我怎样才能让它在Linux上表现得像strace -f
,这就是我想做的事情?
动机:我正在OS X上进行一些Haskell开发,并希望跟踪cabal
(Haskell的构建系统)运行期间发生的事情。在cabal上运行dtruss -f
而不做任何事情,因为在Haskell平台的OS X版本中,/usr/bin/cabal
是exec
s /Library/Haskell/bin/cabal.real
的shell脚本。当然,我可以通过直接运行/Library/Haskell/bin/cabal.real
来解决这个问题,但这仍然不会给我带来太大的影响,因为cabal.real
只是转身而exec
一堆其他的东西。 (如果您不熟悉Haskell,请考虑make
。)
答案 0 :(得分:-2)
鉴于dtruss只是一个高级的dtrace脚本,您可以轻松编写自己的脚本并捕获所有fork / exec调用,在这些新分叉的进程上生成新的dtrace脚本并跟踪它们。另一个选项是-W option check man dtrace。