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