【发布时间】:2011-03-31 12:40:56
【问题描述】:
我正在尝试调试一个 C++ 应用程序,该应用程序通过 system() 系统调用调用许多命令行应用程序,例如 grep 等。我需要通过 system() 调用查看应用程序正在执行的所有命令。
我尝试通过启用历史记录来查看这些命令并查看 .history 文件。但是这些命令不是通过终端执行的。历史文件只有交互执行的命令。
知道如何做到这一点吗?
【问题讨论】:
我正在尝试调试一个 C++ 应用程序,该应用程序通过 system() 系统调用调用许多命令行应用程序,例如 grep 等。我需要通过 system() 调用查看应用程序正在执行的所有命令。
我尝试通过启用历史记录来查看这些命令并查看 .history 文件。但是这些命令不是通过终端执行的。历史文件只有交互执行的命令。
知道如何做到这一点吗?
【问题讨论】:
定义一个具有相似名称的新宏:
#define system(_x) std::cout << _x << std::endl; (system)(_x);
system 宏替换了system 函数并且:
system函数。感谢Hasturkun的建议,以下更好:
#define system(_x) (std::cout << (_x) << std::endl, system(_x))
这也返回了system函数调用的结果;-)
【讨论】:
#define system(_x) (std::cout << (_x) << std::endl, system(_x)) 这样它仍然返回一个值。
system函数调用的结果可以在代码中请求。
system宏的定义中,system函数调用应该用括号括起来,以防止system宏递归调用自身。
system 宏。
跟踪“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
如果您想将这些 exec 与 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() 不是系统调用,而是标准库函数。
【讨论】:
您可以使用 truss 或 strace(不确定 Solaris 自带哪一个)来运行程序并跟踪对系统的调用。
对于 truss,相关命令类似于 truss -caf program_name
【讨论】:
system() 调用本身,还是会像 Linux 的 strace 一样显示组成系统调用(例如,fork() 和 exec() )?