Мониторинг приложений Какао для выполнения внешних утилит (например, ffmpeg) в Mac OS X? - PullRequest
4 голосов
/ 20 января 2009

Существуют приложения Mac с графическим интерфейсом, которые предоставляют интерфейс для более увлекательных инструментов командной строки (часто включаемых в пакет приложений). Я хотел бы взглянуть на то, что происходит под капотом таких графических интерфейсов.

Как «прикрепить» приложение, отследить его на предмет обращений к утилитам командной строки и записать имя файла и параметры командной строки этих вызовов?

Решением также может быть приложение, которое регистрирует выполнение всех приложений в Mac OS X (отфильтровывая наиболее распространенные системные вызовы).

Пример внешнего интерфейса GUI: http://xact.sourceforge.net/ (поскольку это открытый исходный код, его можно просто отладить, но xACT - всего лишь пример. Давайте представим, что у нас есть только готовый * .app для мониторинга).

Обновление: dtrace может отслеживать вызовы exec и выводить имя вызываемой команды. это половина решения, другая половина получает аргументы командной строки. это еще не решено (пока кто-то не подтвердит, что у него есть dtrace, чтобы сделать это).

Ответы [ 4 ]

6 голосов
/ 11 октября 2010

DTrace может сделать эту работу. Основываясь на обсуждении, которое я провел с Джои Хагедорном в комментариях к этому вопросу в других местах, сценарий, который идет с 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
5 голосов
/ 27 января 2013

newproc.d - это еще один сценарий dtrace, который делает и выводит аргументы командной строки процессов в именах процессов. Запуск это просто:

sudo newproc.d

Это работает для меня на OS X Mountain Lion. Старые версии могут иметь различные проблемы; см. ветку комментариев на этом ответе ServerFault для обсуждения newproc.d на Leopard и Snow Leopard.

Кроме того, вы должны знать о некоторых незначительных ограничениях. Если вы посмотрите на исходный код скрипта, это означает, что он не будет отображать более 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;
3 голосов
/ 20 января 2009

Вы можете использовать dtrace для мониторинга системных вызовов exec * () и отображения аргументов при их вызове. Dtrace задокументирована здесь: https://wikis.oracle.com/display/DTrace/Documentation

2 голосов
/ 20 января 2009

Грэхем: здесь будет идеально. Не могли бы вы (или кто-нибудь еще здесь) показать скрипт dtrace, который бы печатал командную строку процесса?

Этот oneliner печатает имена выполняемых процессов:

dtrace -qn 'syscall::exec*:return { printf("%Y %s\n",walltimestamp,curpsinfo->pr_psargs); }' 

Но как получить / напечатать их аргументы командной строки?

...