trace.c revision 504a385858a49352bcfceca444ba4f1a7bfd20cd
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 <sys/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->pid, sbp->addr); 81 if (sbp->enabled == 0) { 82 continue_process(proc->pid); 83 } else { 84 proc->breakpoint_being_enabled = sbp; 85 ptrace(PTRACE_SINGLESTEP, proc->pid, 0, 0); 86 } 87} 88 89int 90umovestr(struct process * proc, void * addr, int len, void * laddr) { 91 long a; 92 int i; 93 int offset=0; 94 95 while(offset<len) { 96 a = ptrace(PTRACE_PEEKTEXT, proc->pid, addr+offset, 0); 97 for(i=0; i<sizeof(long); i++) { 98 if (((char*)&a)[i] && offset+i < len) { 99 *(char *)(laddr+offset+i) = ((char*)&a)[i]; 100 } else { 101 *(char *)(laddr+offset+i) = '\0'; 102 return 0; 103 } 104 } 105 offset += sizeof(long); 106 } 107 *(char *)(laddr+offset) = '\0'; 108 return 0; 109} 110