#include #include #include #include #include #include #include #include #include #include #include #include #if defined __x86_64__ || defined __i386__ #define LOOP 10 static pid_t child; static void cleanup (void) { if (child != 0) kill (child, SIGKILL); } static void handler_fail (int signo) { cleanup (); signal (SIGABRT, SIG_DFL); assert (0); } int main(int argc, char **argv) { int status, j; long l; pid_t pid; setbuf (stdout, NULL); atexit (cleanup); signal (SIGABRT, handler_fail); child = fork(); switch (child) { case -1: assert(0); case 0: { l = ptrace(PTRACE_TRACEME, 0, 0, 0); assert(l==0); raise(SIGSTOP); while (1) { l = access(".",R_OK); assert(l==0); } assert(0); //not reached } //end child default: break; } pid = waitpid(child, &status, 0); assert(pid==child); assert(WIFSTOPPED(status)); assert(WSTOPSIG(status) == SIGSTOP); l = ptrace(PTRACE_SYSCALL,child, 0, 0); assert(l==0); j = 0; while (j < LOOP){ pid = waitpid(child, &status, 0); assert(child==pid); assert(WIFSTOPPED(status)); assert(WSTOPSIG(status) == SIGTRAP); l = ptrace(PTRACE_SYSCALL, child, 0, 0); assert(l==0); j++; } //end loop l = ptrace(PTRACE_CONT, child, 0, SIGKILL); //if the following statement, always successful //l = ptrace(PTRACE_KILL, child, 0,0); if (l < 0) { error (0, errno,"PTRACE_CONT, pid %ld, retvalue %ld",(long)child,l); return 1; } else assert(l==0); pid = waitpid(child, &status, 0); assert(child==pid); if (WIFEXITED(status) && WTERMSIG(status)!=SIGKILL) return 1; return 0; } //end main #else int main(int argc, char **argv) { return 77; } #endif