使用命令行工具确定阻止OSX进程的内容?

时间:2012-10-26 07:59:02

标签: macos instruments blocking strace dtrace

标题说得最多,真的。在Linux上,它easy strace,可能lsof/proc,在OSX Leopard中删除truss之前,它在OSX上很容易,以及基础系统调用(afaik)。

显而易见的方法是使用dtrace来解决这个问题,但据我所知,dtrace不会这样做,因为它会在事件发生时捕获事件 - 在我的情况下,阻塞系统电话已经开始。如果可以通过dtrace解决这个问题,我很乐意纠正。

我看到Xcode的仪器有一个监视器,通过定期处理进程堆栈的样本来实现类似的东西(不确定系统调用它依赖于这样做!),也许在命令行上类似的东西就足够了(因为它会一直显示堆栈到包含系统调用的库调用。为了对我的用例有用,这个“采样命令行工具”必须找到并解析它在堆栈上找到的参数,以便确定我们阻止了哪些文件/文件描述符。

最后一件事 - 在Linux上,你通常可以做普通用户(假设没有ptrace_scope技巧)。如果OSX解决方案也不需要root,那就太好了。

2 个答案:

答案 0 :(得分:5)

您可以使用samplesample PID -e

E.g。对于nc -l localhost 5999,您将获得一个包含调用图的文件:

Call graph:
    9046 Thread_242504   DispatchQueue_1: com.apple.main-thread  (serial)
      9046 start  (in libdyld.dylib) + 1  [0x7fff90a847e1]
        9046 ???  (in nc)  load address 0x102453000 + 0x166c  [0x10245466c]
          9046 __accept  (in libsystem_kernel.dylib) + 10  [0x7fff94445996]

以及其他有用的信息,例如加载的二进制图像。

答案 1 :(得分:2)

我建议采用以下假设的解决方案:

  1. 可以发出信号。
  2. 进程是单线程的(可能无法在阻塞线程中处理信号)。
  3. 您拥有root权限。
  4. dtruss 支持为每个系统调用打印完整的堆栈跟踪(-s参数)。

    示例:

    终端1:

    $ python
    >>> import socket
    >>> s = socket.socket()
    >>> s.bind(('', 1234))
    >>> s.listen(1)
    >>> s.accept() # blocking!
    

    终端2:

    $ dtruss -s -p `pgrep python` # or your python pid if you don't have pgrep (port install proctools)
    

    极小1:

    press Ctrl-C
    

    终端2:

    sigreturn(0x7FFF5FBFD660, 0x1E, 0x10031B3D0)             = 0 Err#-2
              libsystem_kernel.dylib`__accept+0xa # HERE IT IS!
              libpython2.7.dylib`PyEval_EvalFrameEx+0x42bf
              libpython2.7.dylib`fast_function+0xb3
    ...
    

    堆栈中的第一帧(如果是sigreturn)(信号处理程序的拆解代码:http://linux.die.net/man/2/sigreturn)。

    第二帧是我们系统调用的标准库包装器:accept。