Re: [patch] really-ptrace-single-step

Fabiano Ramos
2004-05-12T02:17:12Z

On Tue, 2004-05-11 at 22:06, Davide Libenzi wrote:
> On Tue, 11 May 2004, Fabiano Ramos wrote:
>
> > Sorry for that.
> > By the way the email was sent in response to the first
> > patch, not for the second version.
>
> The second version works for me. Pls give it a spin.
>
>
> - Davide

Seems to be working just fine on 2.6.5 and 2.6.6. Tracing the following
code (tracer appended) would produce:

8050cd6: b8 c7 00 00 00 mov $0xc7,%eax
8050cdb: cd 80 int $0x80
8050cdd: 3d 00 f0 ff ff cmp $0xfffff000,%eax
8050ce2: 76 f0 jbe 8050cd4 <__getuid+0x14>

EIP = 0x08050cd6

EIP = 0x08050cdb

EIP = 0x08050cdd

EIP = 0x08050ce2

--------- TRACER -----------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <syscall.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <linux/user.h>
#include <unistd.h>
#include <errno.h>

extern char **environ;

int main(int argc, char **argv)
{

struct user_regs_struct regs;

int wait_val; /* child's return value */
int pid; /* child's process id */

long long totalinstr=0; /* # of intr executed */
unsigned char opcode; /* syscall opcode goes in one
byte */

int i;

/* printing options */
printf("\n\nPTRACE: Will execute \"");
for (i=1; i<argc; i++)
printf("%s ", argv[i]);

printf("\". Please wait (it may take long...)\n\n\n");

printf("***** SIMULATED PROGRAM OUTPUT *****\n\n");

switch (pid = fork()) {

case -1:
perror("fork");
break;

case 0: /* child process starts */
if ( ptrace(PTRACE_TRACEME, 0, NULL, NULL) < 0)
perror("\nError in ptrace PTRACE_TRACEME");
execv(argv[1],&argv[1]);
break;

default:/* parent process starts */
if (waitpid(pid,&wait_val,0) < 0)
perror("\nchild process EXITED");

if (ptrace(PTRACE_SINGLESTEP,pid,NULL,NULL) < 0)
perror("\nError in ptrace PTRACE_SINGLESTEP");

waitpid(pid,&wait_val,0);

while (1) {

totalinstr++;

/* get PC */
if (ptrace(PTRACE_GETREGS, pid, 0, (int)&regs) ==
-1){
perror("ptrace");
printf("Exiting on error ... \n");
}

printf("\nEIP = 0x%08lx\n", regs.eip);

// will stop after each instruction
if (ptrace(PTRACE_SINGLESTEP, pid, 0, 0) != 0)
perror("ptrace");

waitpid(pid,&wait_val,0);
if ( WIFEXITED(wait_val)) break;

}

}
printf("\n************************************\n\n");
printf("Number of machine instructions : %lld\n\n\n",
totalinstr);
return 0;
}