在Mac OS X上监控Cocoa应用程序以执行外部实用程序(例如,ffmpeg)?

Cap*_*olo 4 debugging macos cocoa trace dtrace

Mac GUI应用程序为更加令人讨厌的命令行工具提供了前端(通常作为应用程序包的一部分包含在内).我想看看这些GUI的内幕发生了什么.

如何"附加"到应用程序,监视它以调用命令行实用程序并记录这些调用的文件名和命令行参数?

解决方案也可以是记录Mac OS X上所有应用程序执行的应用程序(过滤掉最常见的系统调用).

示例GUI前端:http://xact.sourceforge.net/(因为它是开源的,可以调试它,但是xACT只是一个例子.让我们假设我们只有一个现成的*.app来监控).

更新: dtrace可以监视exec调用并打印所调用命令的名称.这是解决方案的一半,另一半是获得命令行参数.这还没有解决(直到有人确认他们已经有dtrace这样做).

Bar*_*lly 6

DTrace可以完成这项工作.根据我在这个问题的其他地方的评论中与Joey Hagedorn的讨论,10.6附带的脚本可以改进以使用合理数量的参数(50+).因为脚本有很多重复,所以我将在这里包含一个输出DTrace脚本的脚本,该脚本运行良好.这一个最多可以提出50个论点; 您可能希望通过更改for循环来扩展参数的数量.

#!/bin/bash

cat <<HEADER
#!/usr/sbin/dtrace -s
/*
 * newproc.d - snoop new processes as they are executed. DTrace OneLiner.
 *
 * This is a DTrace OneLiner from the DTraceToolkit.
 *
 * 15-May-2005  Brendan Gregg   Created this.
 */

/*
 * Updated to capture arguments in OS X. Unfortunately this isn't straight forward...
 */

#pragma D option quiet

this unsigned long long argv_ptr; /* Wide enough for 64 bit user procs */

proc:::exec-success
{
    print_pid[pid] = 1; /* This pid emerged from an exec, make a note of that. */
}

/*
 * The "this" variables are local to (all) of the following syscall::mmap:return probes,
 * and only those probes. They must be initialized before use in each new firing.
 */
syscall::mmap:return
{
    this->argc = 0; /* Disable argument collection until we notice an exec-success */
}

syscall::mmap:return
/ print_pid[pid] /
{
    print_pid[pid] = 0;

    this->is64Bit = curpsinfo->pr_dmodel == PR_MODEL_ILP32 ? 0 : 1;
    this->wordsize = this->is64Bit ? 8 : 4;

    this->argc = curpsinfo->pr_argc; 
    this->argc = (this->argc < 0) ? 0 : this->argc; /* Safety */

    this->argv_ptr = curpsinfo->pr_argv;

    printf("%d %s ", pid, this->is64Bit ? "64b" : "32b");
}

HEADER

for ((i=0;i<50;++i)); do

cat <<REPEAT
syscall::mmap:return
/ this->argc /
{
    this->here_argv = copyin(this->argv_ptr, this->wordsize);
    this->arg = this->is64Bit ? *(unsigned long long*)(this->here_argv) : *(unsigned long*)(this->here_argv);
    printf("%s ", copyinstr(this->arg));
    this->argv_ptr += this->wordsize;
    this->argc--;
}

REPEAT
done

cat <<FOOTER
syscall::mmap:return
/ this->argv_ptr /
{
    printf("%s\n", this->argc > 0 ? "(...)" : "");
    this->argc = 0;
    this->argv_ptr = 0;
}
FOOTER
Run Code Online (Sandbox Code Playgroud)


Mik*_*rty 5

newproc.d是又一DTrace脚本,其确实也过程的输出的命令行参数在给进程名.运行它很简单:

sudo newproc.d
Run Code Online (Sandbox Code Playgroud)

这适用于OS X Mountain Lion.旧版本可能存在各种问题; 有关Leopard和Snow Leopard上newproc.d的一些讨论,请参阅 ServerFault答案的评论主题.

此外,您应该了解一些小的限制.如果你看一下脚本的源代码,它表明它不会显示超过5个参数,并且它不会显示长度超过128个字符的参数:

/*
 * Updated to capture arguments in OS X. Unfortunately this isn't straight forward... nor inexpensive ...
 * Bound the size of copyinstr()'s and printf incrementally to prevent "out of scratch space errors"
 * print "(...)" if the length of an argument exceeds COPYINSTRLIMIT.
 * print "<...>" if argc exceeds 5.
 */

inline int COPYINSTRLIMIT = 128;
Run Code Online (Sandbox Code Playgroud)