ptrace API を使用して小さなプログラムをトレースしようとしています。トレーサーが実行されるたびに、悪い結果が生じることがわかりました。これは、トレースしたい短いプログラムの逆アセンブリです。
$ objdump -d -M intel inc_reg16
inc_reg16: file format elf32-i386
Disassembly of section .text:
08048060 <.text>:
8048060: b8 00 00 00 00 mov eax,0x0
8048065: 66 40 inc ax
8048067: 75 fc jne 0x8048065
8048069: 89 c3 mov ebx,eax
804806b: b8 01 00 00 00 mov eax,0x1
8048070: cd 80 int 0x80
トレーサー自体のコードは次のとおりです。
// ezptrace.c
#include <sys/user.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
int main() {
pid_t child;
child = fork();
if (child == 0) {
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
execv("inc_reg16", NULL);
}
else {
int status;
wait(&status);
struct user_regs_struct regs;
while (1) {
ptrace(PTRACE_GETREGS, child, NULL, ®s);
printf("eip: %x\n", (unsigned int) regs.eip);
ptrace(PTRACE_SINGLESTEP, child, NULL, NULL);
waitpid(child, &status, 0);
if(WIFEXITED(status)) break;
}
printf("end\n");
}
return 0;
}
トレーサの仕事は、inc_reg16 プログラムをシングル ステップし、遭遇した各プロセッサ命令のアドレスをログに記録することです。命令「inc ax」が何回発生したかを実行して確認すると、トレーサーが実行されるたびに数値が異なることが発生します。
$ gcc ezptrace.c -Wall -o ezptrace
$ ./ezptrace > inc_reg16.log
$ grep '8048065' inc_reg16.log | wc -l
65498
2 番目のチェック:
$ ./ezptrace > inc_reg16.log
$ grep '8048065' inc_reg16.log | wc -l
65494
問題は、命令「inc ax」が正確に 65536 回実行されるため、上記の結果が両方とも 65536 になることです。問題は、私のコードに誤りがあるのか、それとも ptrace のバグの問題なのかということです。よろしくお願いいたします。