trace.c revision 8cc1b9d456c8f41e3a8cc0d3ec0d77eb779cb7bb
1#include <stdio.h> 2#include <string.h> 3#include <errno.h> 4#include <sys/types.h> 5#include <sys/ptrace.h> 6#include <asm/unistd.h> 7 8#include "ltrace.h" 9#include "options.h" 10 11/* Returns 1 if the sysnum may make a new child to be created 12 * (ie, with fork() or clone()) 13 * Returns 0 otherwise. 14 */ 15int 16fork_p(int sysnum) { 17 return 0 18#if defined(__NR_fork) 19 || (sysnum == __NR_fork) 20#endif 21#if defined(__NR_clone) 22 || (sysnum == __NR_clone) 23#endif 24#if defined(__NR_vfork) 25 || (sysnum == __NR_vfork) 26#endif 27 ; 28} 29 30/* Returns 1 if the sysnum may make the process exec other program 31 */ 32int 33exec_p(int sysnum) { 34 return (sysnum == __NR_execve); 35} 36 37void 38trace_me(void) { 39 if (ptrace(PTRACE_TRACEME, 0, 1, 0)<0) { 40 perror("PTRACE_TRACEME"); 41 exit(1); 42 } 43} 44 45int 46trace_pid(pid_t pid) { 47 if (ptrace(PTRACE_ATTACH, pid, 1, 0) < 0) { 48 return -1; 49 } 50 return 0; 51} 52 53void 54untrace_pid(pid_t pid) { 55 ptrace(PTRACE_DETACH, pid, 1, 0); 56} 57 58void 59continue_after_signal(pid_t pid, int signum) { 60 /* We should always trace syscalls to be able to control fork(), clone(), execve()... */ 61 ptrace(PTRACE_SYSCALL, pid, 0, signum); 62} 63 64void 65continue_process(pid_t pid) { 66 continue_after_signal(pid, 0); 67} 68 69void 70continue_enabling_breakpoint(pid_t pid, struct breakpoint * sbp) { 71 enable_breakpoint(pid, sbp); 72 continue_process(pid); 73} 74 75int 76umovestr(struct process * proc, void * addr, int len, void * laddr) { 77 long a; 78 int i; 79 int offset=0; 80 81 while(offset<len) { 82 a = ptrace(PTRACE_PEEKTEXT, proc->pid, addr+offset, 0); 83 for(i=0; i<sizeof(long); i++) { 84 if (((char*)&a)[i] && offset+i < len) { 85 *(char *)(laddr+offset+i) = ((char*)&a)[i]; 86 } else { 87 *(char *)(laddr+offset+i) = '\0'; 88 return 0; 89 } 90 } 91 offset += sizeof(long); 92 } 93 *(char *)(laddr+offset) = '\0'; 94 return 0; 95} 96