本文主要分析ptrace的单步调试功能
单步调试的含义相信大家已经非常清楚了,PTRACE_SINGLESTEP参数就能够使被跟踪的程序单步执行。
PTRACE_SINGLESTEP重新启动被停止的程序,让其执行一条指令之后又停止。我们用下面的代码加以验证。
list11.c
#include "ptrace.h"
void main(int argc,char *argv[])
{
pid_t child;
int status,data;
int trace_process;
trace_process=atoi(argv[1]);
//对目标进程进行跟踪,ATTACH使得被跟踪进程停止(stopped)
ptrace(PTRACE_ATTACH,trace_process,0,0);
wait(&status);
//打印出使得被跟踪进程停止的信号信息
if(WIFSTOPPED(status)){
printf("the child is stopped by the attach!\n");
fprintf(stderr,"%s\n",strsignal(WSTOPSIG(status)));
}
//以单步模式唤醒被跟踪进程,即被跟踪进程执行一条指令之后又停止。
ptrace(PTRACE_SINGLESTEP,trace_process,0,0);
while(1){
//printf("just to see 1!\n");
//被跟踪进程单步运行时,被跟踪进程停止,该wait被唤醒
wait(&status);
//被跟踪进程退出时,跳出循环
if(WIFEXITED(status)){
fprintf(stderr,"%s",strsignal(WEXITSTATUS(status)));
printf("the child is exit!\n");
break;
}
else{
//单步执行,知道i=10这条语句执行,然后将i换成245.
data=ptrace(PTRACE_PEEKDATA,trace_process,0x08049764,0);
if(data==10){
printf("the data now is %d\n",data);
data=245;
ptrace(PTRACE_POKEDATA,trace_process,0x08049764,data);
ptrace(PTRACE_CONT,trace_process,0,0);
break;
}
}
ptrace(PTRACE_SINGLESTEP,trace_process,0,0);
}
//子进程结束时该wait唤醒。
wait(&status);
if(WIFEXITED(status)){
printf("the child is over!\n");
}
}
#include "ptrace.h"
int i;
void main()
{
sleep(20);
printf("the child is start!\n");
i=10;
printf("child5:i=%d\n",i);
}
1、编译两个源文件
2、在一个终端运行child5.o
3、在另一个终端运行list11.o(也可以在同一个终端上)
运行结果如下