#include #include #include #include #include #include #include #include #include #include #include char childstack[ 8*1024]; int my_getpid() { long res; __asm__ volatile (" int $0x80\n\t" : "=a" (res) : "0" (__NR_getpid)); return res; } void parent_fn( pid_t child) { int status; printf("Parent: childs PID is %d\n", child); if ( waitpid( child, &status, 0) != child ) { fprintf( stderr, "Parent: "); perror("waitpid"); exit(1); } if ( !WIFSTOPPED(status) || WSTOPSIG(status) != SIGTRAP ) { printf("Unexpected status %04x received\n", status); exit(1); } *(char *)0x12345678 = 'A'; } int child_fn( void * unused) { printf("Child: my PID is %d\n", my_getpid()); if ( ptrace( PTRACE_TRACEME, 0, (void *)0, (void *)0) ) { fprintf( stderr, " Child: "); perror("ptrace( PTRACE_TRACEME, 0, 0, 0)"); exit(1); } kill( my_getpid(), SIGTRAP); printf("You should never read this text!!!!\n"); return 0; } int main( void) { pid_t child; printf("Parent: my PID is %d\n", my_getpid()); child = clone( child_fn, childstack+8*1024-4, CLONE_VM|SIGCHLD, (void *)NULL); if ( child < 0 ) { perror("clone"); exit(1); } parent_fn( child); return 0; }