【发布时间】:2021-02-25 18:40:56
【问题描述】:
我想统计运行 /bin/ls 时执行的指令总数。 我使用了 3 种结果差异很大的方法,但我不知道为什么。
1.使用 ptrace 进行指令计数
我编写了一段代码,它调用 ls 的一个实例并使用 ptrace 单步执行:
#include <stdio.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/user.h>
#include <sys/reg.h>
#include <sys/syscall.h>
int main()
{
pid_t child;
child = fork(); //create child
if(child == 0) {
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
char* child_argv[] = {"/bin/ls", NULL};
execv("/bin/ls", child_argv);
}
else {
int status;
long long ins_count = 0;
while(1)
{
//stop tracing if child terminated successfully
wait(&status);
if(WIFEXITED(status))
break;
ins_count++;
ptrace(PTRACE_SINGLESTEP, child, NULL, NULL);
}
printf("\n%lld Instructions executed.\n", ins_count);
}
return 0;
}
运行这段代码会给我 516.678 条指令。
2。 QEMU 单步执行
我在单步模式下使用 qemu 模拟了 ls,并使用以下命令将所有传入指令记录到日志文件中: qemu-x86_64 -singlestep -D 日志文件 -d in_asm /bin/ls
根据qemuls执行16.836条指令。
3.性能
sudo perf stat ls
这个命令让我执行了 8.162.180 条指令。
我知道这些指令中的大多数来自动态链接器,它们可以被计算在内。但为什么这些数字相差如此之大?他们不应该都一样吗?
【问题讨论】:
-
你自己的程序会统计
ld-linux.so的指令,但不统计系统调用的指令(syscall算作一条指令)。我猜(我不知道)perf会计算 Linux 内核中的指令(所以一个syscall是数千条指令)而“qemu”不计算ld-linux.so。 -
谢谢!所以如果我的代码跳过“ld-linux.so”的指令,我应该得到与 qemu 相同的计数?