Sba*_*ila 4 c linux ptrace qemu instructions
我编写了以下代码,它逐步遍历/bin/ls并计算其指令:
#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;
}
Run Code Online (Sandbox Code Playgroud)
运行此代码可以执行大约 500.000 条指令。据我所知,这些指令大部分应该来自动态链接器。当我使用 QEMU 和qemu-x86_64 -singlestep -D log -d in_asm /bin /ls跟踪 /bin/ls 时,我执行了大约 17.000 条指令。我需要调整什么才能在 QEMU 相同的点开始和停止计数?(又名:计算相同的指令)。
我用 QEMU 跟踪了一个“return null”程序,它产生了 7840 条指令,而我的代码给了我 109025 条指令,因此 QEMU 似乎跟踪的内容多于主程序,但少于我的代码。
我的目标是稍后比较这些指令,这就是为什么我想迭代 QEMU 等相同指令。
QEMU 的“in_asm”日志记录不是执行指令的日志。每次翻译指令时(即当 QEMU 生成与其对应的主机代码位时),它都会记录。然后,该翻译会被缓存,如果来宾循环并再次执行相同的指令,QEMU 将简单地重新使用相同的翻译,因此 in_asm 不会记录它。因此,“in_asm 报告的指令要少得多”。
通过 -d 选项记录每个执行的指令有点棘手 - 您需要查看“cpu”和“exec”跟踪,以使用 -d 的“nochain”子选项禁用 QEMU 优化,否则会导致一些块没有被记录,使用“-singlestep”强制每个块一条指令,并且还考虑了一些我们打印执行跟踪但实际上不执行指令的极端情况。这是因为 -d 选项并不是让用户反思其程序行为的一种方式——它是一个调试选项,旨在允许调试 QEMU 和来宾程序一起执行的操作,因此它会打印以下信息:需要对 QEMU 内部结构有一点了解才能正确解释。
您可能会发现编写 QEMU“插件”更简单: https: //qemu.readthedocs.io/en/latest/devel/tcg-plugins.html ——这是一个 API,旨在相当简单地编写仪器,例如“计算执行的指令数”。如果您幸运的话,那么示例插件之一甚至可能足以满足您的目的。
| 归档时间: |
|
| 查看次数: |
2712 次 |
| 最近记录: |