Как записать все команды, запущенные системой () Системный вызов - PullRequest
1 голос
/ 18 августа 2010

Я пытаюсь отладить приложение C ++, которое вызывает много приложений командной строки, таких как grep и т. Д., Через системный вызов system ().Мне нужно увидеть все команды, которые приложение выполняет с помощью вызова system ().

Я попытался просмотреть эти команды, включив историю и просмотр файла .history.Но эти команды не выполняются через терминал.Файл истории содержит только команды, выполненные в интерактивном режиме.

Есть идеи, как это можно сделать?

Ответы [ 3 ]

5 голосов
/ 18 августа 2010

Определить новый макрос с похожим именем:

#define system(_x) std::cout << _x << std::endl; (system)(_x);

Макрос system заменяет функцию system и:

  1. Он выводит команду на стандартный вывод(или в другом месте).
  2. Вызывает функцию system.

Благодаря предложению Hasturkun лучше следующее:

#define system(_x) (std::cout << (_x) << std::endl, system(_x))

Возвращает также результат вызова функции system; -)

3 голосов
/ 19 августа 2010

Чтобы проследить каждую команду, выполняемую yourProgram:

truss -s!all -daDf -t exec yourProgram

например:

$ truss -s!all -daDf -t exec sh -c "/bin/echo hello world;/bin/date" 
Base time stamp:  1282164973.7245  [ Wed Aug 18 22:56:13 CEST 2010 ]
5664:    0.0000  0.0000 execve("/usr/bin/i86/ksh93", 0x080471DC, 0x080471EC)  argc = 3
5664:    argv: sh -c /bin/echo hello world;/bin/date
5665:    0.0106  0.0106 execve("/bin/echo", 0x08067484, 0x080674F8)  argc = 3
5665:    argv: /bin/echo hello world
hello world
5664:    0.0126  0.0126 execve("/bin/date", 0x080674E0, 0x080674F8)  argc = 1
5664:    argv: /bin/date
Wed Aug 18 22:56:13 CEST 2010

Если вы хотите соотнести эти execs с вызовами system (), вы можете использовать этокоманда:

truss -t execve -f -u 'libc:system' yourProgram

например:

$ cat a.c
main()
{
system("echo a b c");
system("pwd");
}

$ truss -t execve -f -u 'libc:system' ./a
20073:  execve("a", 0x08047240, 0x08047248)  argc = 1
20073/1@1:  -> libc:system(0x8050a5c, 0x0)
20074/1:    execve("/bin/sh", 0x080471BC, 0x08047248)  argc = 3
a b c
20073/1@1:  <- libc:system() = 0
20073/1@1:  -> libc:system(0x8050a68, 0x0)
20076/1:    execve("/bin/sh", 0x080471BC, 0x08047248)  argc = 3
/tmp
20073/1@1:  <- libc:system() = 0

Наконец, если вы используете Solaris 10 или более новую версию, вы можете использовать Dtrace для этой задачи, например:

dtrace -Z -q -c yourProgram -n ' pid$target:libc:system:entry { printf("system(\"%s\")\n", copyinstr(arg0)); } '

, который выдаст этот вывод с тем же кодом "a":

a b c
/tmp
system("echo a b c")
system("pwd")

PS: Кстати, system () - это не системный вызов, а стандартная библиотечная функция.

2 голосов
/ 18 августа 2010

Вы можете использовать truss или strace (не уверен, какой из них поставляется с Solaris) для запуска программы и отслеживания вызовов системы.

Для фермы соответствующая команда будет выглядеть примерно так: truss -caf program_name

...