Re: [LIP] ptrace problems

From: Mike Coleman (mkc@kc.net)
Date: Tue Feb 29 2000 - 03:46:58 EST


> I am giving below the souce codes of the two programs and a typescript
> showing strace debug and the output. Note how strace debug shows weird
> stuff for the second ptrace.

The probable reason you're getting an error when doing the PTRACE_GETREGS is
that the parent can only do this when the child is stopped. You have to
SIGSTOP it first, or otherwise arrange for it to be stopped. (Actually, the
PTRACE_ATTACH will send a SIGSTOP to the child, but the child won't
necessarily stop before your second ptrace call. See wait4(2).)

The 'strace' output is weird because 'strace' will effectively block the use
of ptrace by the child processes it's following. The reason for this is that
'strace' uses ptrace itself to trace the child processes, and a given process
can only be traced by one parent at a time.

[Actually, this isn't completely true. Lars Brinkhoff (lars@nocrew.org) has a
nifty ptrace proxy program which will fake allowing two parents to ptrace the
same child. Someday my pet project (subterfugue.org) will allow the same by a
similar mechanism.]

Also, you only need one of { PTRACE_ATTACH, PTRACE_TRACEME } here. See the
rewritten ptrace(2) man page in a recent version of the dev manpages.

--Mike

> /*
> Debugger, father , debug1.c
> */
>
> #include <stdio.h>
> #include <sys/ptrace.h>
> #include <fcntl.h>
> #include <stdlib.h>
> #include <unistd.h>
> #include <string.h>
> #include <asm/ptrace.h>
> #include <sys/user.h>
>
>
> void fatal_error(const char* s)
> {
> printf("%s\n",s);
> exit(-1);
> }
>
> pid_t fork_child()
> {
> /*
> Fork a child and return PID
> Take care of errors
> */
> pid_t child_pid;
>
> child_pid=fork();
> if (child_pid==-1)
> {
> fatal_error("Could not fork in file");
> }
>
> /* If I am the child ... */
> if (child_pid==0)
> {
> printf("I am the child !\n");
> execv("./new",NULL);
> }
> getchar();
> return child_pid;
> }
>
> int main()
> {
> int child_pid,err;
> //struct user q;
>
> unsigned long* gpregs=(unsigned long*)malloc(sizeof(long)*17);
>
> bzero((char*)gpregs,sizeof(long)*17);
> child_pid=fork_child();
>
> err=ptrace(PTRACE_ATTACH,child_pid,0,0);
> if (err<0)
> fatal_error("Invalid Ptrace in PTRACE_ATTACH");
> else
> printf("Successful ptrace ATTACH\n");
>
> /*Get the regs */
> err=ptrace(PT_GETREGS,child_pid,NULL,gpregs);
> printf ("Err = %d\n",err);
> if (err<0) fatal_error("Invalid Ptrace in GETREGS");
> printf("EAX : 0x%lx\n",gpregs[EAX]);
> printf("CS : 0x%lx\n",gpregs[CS]);
> printf("EIP : 0x%lx\n",gpregs[EIP]);
>
>
>
> return 0;
> }
>
> -------------------------------------------
> /*
> * new.c, child
> */
>
>
> #include <unistd.h>
> #include <stdio.h>
> #include <sys/ptrace.h>
>
>
> int main()
> {
> //int ch;
> int i;
> printf("I am the new image : PID = %d .. Entering loop !\n",getpid());
> /*
> ch=ptrace(PTRACE_TRACEME,0,0,0);
> if(ch==-1) {
> printf ("No tracing !\n");
> return 1;
> }
> else
> {
> printf("Tracing on \n");
> }
> */
>
> for (i=0;i<1000000000L;i+=5);
> printf("Program new stopped\n");
>
> return 0;
> }
>
> ------------------------------------------
> Script started on Mon Feb 28 22:53:19 2000
> [sarcar@localhost progs]$ gcc -o debug debug1.c -Wall -g
> [sarcar@localhost progs]$ gcc -o new new.c -Wall -g
> [sarcar@localhost progs]$ debug
> I am the child !
> I am the new image : PID = 1145 .. Entering loop !
>
> Successful ptrace ATTACH
> Err = -1
> Invalid Ptrace in GETREGS

> [sarcar@localhost progs]$ ma strace debug|more
> execve("./debug", ["debug"], [/* 24 vars */]) = 0
> brk(0) = 0x80498fc
> open("/etc/ld.so.preload", O_RDONLY) = -1 ENOENT (No such file or directory)
> open("/etc/ld.so.cache", O_RDONLY) = 3
> fstat(3, {st_mode=0, st_size=0, ...}) = 0
> mmap(0, 17006, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40014000
> close(3) = 0
> open("/lib/libc.so.6", O_RDONLY) = 3
> fstat(3, {st_mode=0, st_size=0, ...}) = 0
> read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3"..., 4096) = 4096
> mmap(0, 974392, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x40019000
> mprotect(0x400ff000, 32312, PROT_NONE) = 0
> mmap(0x400ff000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0xe5000) = 0x400ff000
> mmap(0x40104000, 11832, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x40104000
> close(3) = 0
> munmap(0x40014000, 17006) = 0
> personality(PER_LINUX) = 0
> getpid() = 1148
> brk(0) = 0x80498fc
> brk(0x8049954) = 0x8049954
> brk(0x804a000) = 0x804a000
> fork() = 1149
> fstat(0, {st_mode=S_ISVTX|0401, st_size=0, ...}) = 0
> mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40014000
> ioctl(0, TCGETS, {B38400 opost isig -icanon -echo ...}) = 0
> read(0, "\n", 4096) = 1
> ptrace(PTRACE_ATTACH, 1149, 0, 0) = 0
> fstat(1, {st_mode=0, st_size=0, ...}) = 0
> mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40015000
> ptrace(PTRACE_???, 1149, 0, 0x8049908) = -1 ESRCH (No such process)
> write(1, "Successful ptrace ATTACH\nErr = "..., 60) = 60
> munmap(0x40015000, 4096) = 0
> _exit(-1) = ?
> Successful ptrace ATTACH
> Err = -1
> Invalid Ptrace in GETREGS
>
> [sarcar@localhost progs]$
> Script done on Mon Feb 28 22:54:43 2000

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue Mar 07 2000 - 21:00:09 EST