I've asked a couple others places but no one yet has been able to get my program to work correctly. So please hear me out!

I'm writing a simple linux tracing debugger that will trace a child application and catch any signals it receives. If it receives a signal and stops or crashes, I want to print out the registers of the child at that point.

I have tried using PTRACE_TRACEME and PTRACE_ATTACH, so far PTRACE_TRACEME seems to be the one I should use.

I can run the program in GNU debugger and see that some registers are modified if I put too much data into a variable and it changes some of the registers to match the data I use to overflow it. When I run my test program the registers look quite normal and I run it through other tracing tools such as ltrace and strace to check for things too.

ptrace.c
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <sys/user.h>

#define BIN "/tmp/test"

int main(int ac, char *ag[])
{

char buf[64];
int eax, ebx, ecx, edx, esi, edi, esp, eip;
pid_t child;
struct user_regs_struct r;

memset(buf, 'p', sizeof(buf));

	child = fork();

if(child == 0)
{

        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
	execl(BIN, BIN, buf, NULL);

}

else
{

int sig, stat;

if(WIFSIGNALED(stat))
{

     wait(&stat);

     ptrace(PTRACE_GETREGS, child, 0, &r);

eax = r.eax;
ebx = r.ebx;
ecx = r.ecx;
edx = r.edx;
esi = r.esi;
edi = r.edi;
esp = r.esp;
eip = r.eip;

printf("eax 0x%x\nebx 0x%x\necx 0x%x\nedx 0x%x\nesi 0x%x\nedi 0x%x\nesp 0x%x\neip 0x%x\n", eax, ebx, ecx, edx, esi, edi, esp, eip);

}
}

	ptrace(PTRACE_DETACH, child, 0, 0);
        return 0;

}
ice.c
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{

char buf[32];

strcpy(buf, argv[1]);

return 0;

}
gnu debugger output:
Code:
tommy@otto:/tmp$  gdb /tmp/test
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...
(gdb) run `perl -e 'print "p" x 64'`
Starting program: /tmp/test `perl -e 'print "p" x 64'`

Program received signal SIGSEGV, Segmentation fault.
0x70707070 in ?? ()
(gdb) info registers
eax            0x0	0
ecx            0xbfa2470f	-1079884017
edx            0x41	65
ebx            0xb7ee9ff4	-1209098252
esp            0xbfa24740	0xbfa24740
ebp            0x70707070	0x70707070
esi            0x80483a0	134513568
edi            0x80482d0	134513360
eip            0x70707070	0x70707070
eflags         0x10246	[ PF ZF IF RF ]
cs             0x73	115
ss             0x7b	123
ds             0x7b	123
es             0x7b	123
fs             0x0	0
gs             0x33	51
(gdb) q
The program is running.  Exit anyway? (y or n) y
tommy@otto:/tmp$
ptrace program output:
Code:
tommy@otto:/tmp$ ./pt
eax 0x0
ebx 0x0
ecx 0x0
edx 0x0
esi 0x0
edi 0x0
esp 0xbffd9580
eip 0xb7fbc810
tommy@otto:/tmp$
Now you see what I'm looking for as output and you see what I've got?

I've tried using PTRACE_SINGLESTEP but maybe I'm just not putting it in the right places in the code.. that is why I defiantly need help with this code.

I am trying to...

1) Execute a program (fork() and make it a child) and trace it with ptrace()
2) Catch any signals the child receives
3) Display the extended registers of the child process when the signal is received

I have read all the documentation supplied but if you all know how to do this I would appreciate a clear cut answer for myself and everyone else.. I'm sure we're not the only ones even to attempt this small feat.

Much appreciated all, TIA!