shell脚本在执行期间执行的分叉数
有没有办法计算shell脚本在执行时执行的fork数?我一直在考虑使用shell脚本在执行期间执行的分叉数,shell,fork,Shell,Fork,有没有办法计算shell脚本在执行时执行的fork数?我一直在考虑使用getrusage(2)编写一个C包装器,并分析 struct rusage { struct timeval ru_utime; /* user time used */ struct timeval ru_stime; /* system time used */ long ru_maxrss; /* max resident set size */
getrusage(2)
编写一个C包装器,并分析
struct rusage {
struct timeval ru_utime; /* user time used */
struct timeval ru_stime; /* system time used */
long ru_maxrss; /* max resident set size */
long ru_ixrss; /* integral shared text memory size */
long ru_idrss; /* integral unshared data size */
long ru_isrss; /* integral unshared stack size */
long ru_minflt; /* page reclaims */
long ru_majflt; /* page faults */
long ru_nswap; /* swaps */
long ru_inblock; /* block input operations */
long ru_oublock; /* block output operations */
long ru_msgsnd; /* messages sent */
long ru_msgrcv; /* messages received */
long ru_nsignals; /* signals received */
long ru_nvcsw; /* voluntary context switches */
long ru_nivcsw; /* involuntary context switches */
};
但是这里没有叉子的数量。下一个想法是扫射贝壳和孩子们,寻找叉子。有没有更简单、开销更小的方法?是否有一些外壳带有非标准选项/变量/机制来显示叉子的数量?有几个选项:
- 最好的多平台方法可能是
或其等效物(strace
,truss
),或ktrace
)。见下文。这还允许您附加到正在运行的进程dtrace
- 一种可行的、尽管有点棘手的多平台方法是使用您自己版本的
等创建一个动态库,记录调用,然后调用真正的C库函数。搜索fork/execve
以获得一些想法。但这在静态链接的二进制文件上不起作用LD\u PRELOAD
- 在Linux和Solaris上,您可以设置环境变量
,动态链接器将在加载可执行文件和库时发出各种诊断,这对于这样一个简单的步骤应该是有启发的。在Linux上,每个新进程都应该输出一些或大部分“initialize”、“init”和“fini”条目以及PID。但这在静态链接的二进制文件上不起作用LD_DEBUG=files
- 如果您在Linux或*BSD或Solaris上,并且具有root访问权限,并且进程记帐可用,则可以运行命令,然后检查
或lastcomm
的输出。这可能需要启动记帐(如果尚未运行)。这可能无法提供某些平台上所需的详细信息。它可以在RH/CentOS 6上轻松完成,并提供了所需的所有详细信息。其他系统也有过程会计dump acct
- 如果您在Linux上并且拥有
支持,则可以使用auditd
记录系统调用。(autrace myscript.sh
应为此运行,以便将内核数据记录到审核文件)auditd
- 完整性:您可以使用调试器,但这是我能想到的最乏味的方法;-)李>
.trace
文件。参数-e trace=process
筛选只显示与流程相关的系统调用
在Solaris上,您可以通过以下方式进行跟踪:
truss -f -o /tmp/myscript.trace \
-u libc:fork,execl,execv,execle,execve,execlp,execvp ./myscript.sh
Solaristruss
允许您跟踪用户区库和内核系统调用。您也可以使用dtrace
,有关一些想法,请参见此处:
其他平台的变量类似于LD\u DEBUG
或LD\u VERBOSE
,请参阅链接器文档(例如man LD.so
)
在上述情况下,您应该了解程序(通常)调用的是C库函数,例如
fork()
,对内核的请求至少取决于操作系统,它可能导致系统调用vfork
,execve
或clone
,更简单,开销更小,这是一个很难解决的问题。您可以尝试插入一个非常简单的叉计数垫片。可能很快,可能不比strace简单。
truss -f -o /tmp/myscript.trace \
-u libc:fork,execl,execv,execle,execve,execlp,execvp ./myscript.sh