如何在LXC容器中准确测量存在后台fork子进程的二进制样本运行时间?
准确测量后台持续运行的二进制样本运行时间
你的问题核心在于这个样本会fork出调用setsid()的子进程脱离父进程组,导致普通time只能跟踪快速退出的父进程,无法覆盖后台持续运行的子进程。下面提供几个基于Linux内置工具的简洁方案,解决精度和复杂度问题:
方案1:用timeout + time实现带超时的全生命周期测量
这是最简洁的方法,利用timeout控制最大运行时间,time测量从启动到所有相关进程被终止的总时长:
time timeout 10s bash -c '/home/runner/samples/VirusShare_00238010bb86fd0bf4014c3d19f114b2; pkill -f VirusShare_00238010bb86fd0bf4014c3d19f114b2'
原理说明:
timeout 10s:强制10秒后终止整个bash命令进程,避免无限等待bash -c:把启动样本和后续杀死进程的操作封装在同一个shell进程中,让time能跟踪整个操作的总时间pkill -f:确保所有包含样本文件名的进程都被终止,覆盖fork出的后台子进程
方案2:高精度时间测量(纳秒级精度)
如果需要更高的时间精度,可以用clock_gettime替代date,同时优化循环检查逻辑减少精度损失:
#!/bin/bash # 获取纳秒级起始时间 start=$(clock_gettime -nano seconds) # 启动样本进程 /home/runner/samples/VirusShare_00238010bb86fd0bf4014c3d19f114b2 & # 设置超时时间(10秒,转换为纳秒) timeout_ns=$((start + 10 * 1000000000)) # 循环检查进程,无sleep忙等(精度最高,CPU占用稍高) while pgrep -f VirusShare_00238010bb86fd0bf4014c3d19f114b2 >/dev/null; do current=$(clock_gettime -nano seconds) if (( current >= timeout_ns )); then echo "[!] Timeout reached, killing all VirusShare processes" pkill -f VirusShare_00238010bb86fd0bf4014c3d19f114b2 break fi done # 获取结束时间并计算运行时长(转换为毫秒) end=$(clock_gettime -nano seconds) runtime_ms=$(( (end - start) / 1000000 )) echo "runtime=${runtime_ms} ms"
优化点:
clock_gettime -nano seconds:提供纳秒级时间戳,比date +%s%3N的毫秒精度高得多- 无sleep的忙等循环:避免了
sleep系统调用的精度误差,代价是会占用一定CPU资源(如果需要平衡,可替换为usleep 10000即10ms休眠,精度损失很小)
方案3:利用进程组跟踪(仅适用于未调用setsid()的子进程)
如果样本的子进程没有调用setsid()脱离进程组,可以直接用time跟踪整个进程组:
time bash -c '/home/runner/samples/VirusShare_00238010bb86fd0bf4014c3d19f114b2; wait'
但从你的strace输出看,子进程调用了setsid(),所以这个方案不适用,不过可以作为通用场景的参考。
对你原有脚本的改进建议:
- 替换时间获取方式:用
clock_gettime替代date,提升精度 - 优化休眠逻辑:用
usleep(微秒级)替代sleep,减少精度损失 - 简化流程:利用
timeout内置命令替代手动超时判断,减少代码复杂度
内容的提问来源于stack exchange,提问作者Robert
相关产品推荐
相关产品推荐

