events.c revision f0bd98b3e6753d8609a3054a61f2df6f9cdac10a
1#include "config.h" 2 3#define _GNU_SOURCE 1 4#include <stdlib.h> 5#include <sys/types.h> 6#include <sys/wait.h> 7#include <errno.h> 8#include <signal.h> 9#include <string.h> 10#include <sys/ptrace.h> 11 12#include "common.h" 13 14static Event event; 15 16Event * 17next_event(void) { 18 pid_t pid; 19 int status; 20 int tmp; 21 int stop_signal; 22 23 debug(DEBUG_FUNCTION, "next_event()"); 24 if (!list_of_processes) { 25 debug(DEBUG_EVENT, "event: No more traced programs: exiting"); 26 exit(0); 27 } 28 pid = waitpid(-1, &status, __WALL); 29 if (pid == -1) { 30 if (errno == ECHILD) { 31 debug(DEBUG_EVENT, "event: No more traced programs: exiting"); 32 exit(0); 33 } else if (errno == EINTR) { 34 debug(DEBUG_EVENT, "event: none (wait received EINTR?)"); 35 event.type = EVENT_NONE; 36 return &event; 37 } 38 perror("wait"); 39 exit(1); 40 } 41 event.proc = pid2proc(pid); 42 if (!event.proc || event.proc->state == STATE_BEING_CREATED) { 43 event.type = EVENT_NEW; 44 event.e_un.newpid = pid; 45 debug(DEBUG_EVENT, "event: NEW: pid=%d", pid); 46 return &event; 47 } 48 get_arch_dep(event.proc); 49 event.proc->instruction_pointer = NULL; 50 debug(3, "event from pid %u", pid); 51 if (event.proc->breakpoints_enabled == -1) { 52 event.type = EVENT_NONE; 53 trace_set_options(event.proc, event.proc->pid); 54 enable_all_breakpoints(event.proc); 55 continue_process(event.proc->pid); 56 debug(DEBUG_EVENT, "event: NONE: pid=%d (enabling breakpoints)", pid); 57 return &event; 58 } else if (!event.proc->libdl_hooked) { 59 /* debug struct may not have been written yet.. */ 60 if (linkmap_init(event.proc, &main_lte) == 0) { 61 event.proc->libdl_hooked = 1; 62 } 63 } 64 65 if (opt_i) { 66 event.proc->instruction_pointer = 67 get_instruction_pointer(event.proc); 68 } 69 switch (syscall_p(event.proc, status, &tmp)) { 70 case 1: 71 event.type = EVENT_SYSCALL; 72 event.e_un.sysnum = tmp; 73 debug(DEBUG_EVENT, "event: SYSCALL: pid=%d, sysnum=%d", pid, tmp); 74 return &event; 75 case 2: 76 event.type = EVENT_SYSRET; 77 event.e_un.sysnum = tmp; 78 debug(DEBUG_EVENT, "event: SYSRET: pid=%d, sysnum=%d", pid, tmp); 79 return &event; 80 case 3: 81 event.type = EVENT_ARCH_SYSCALL; 82 event.e_un.sysnum = tmp; 83 debug(DEBUG_EVENT, "event: ARCH_SYSCALL: pid=%d, sysnum=%d", pid, tmp); 84 return &event; 85 case 4: 86 event.type = EVENT_ARCH_SYSRET; 87 event.e_un.sysnum = tmp; 88 debug(DEBUG_EVENT, "event: ARCH_SYSRET: pid=%d, sysnum=%d", pid, tmp); 89 return &event; 90 case -1: 91 event.type = EVENT_NONE; 92 continue_process(event.proc->pid); 93 debug(DEBUG_EVENT, "event: NONE: pid=%d (syscall_p returned -1)", pid); 94 return &event; 95 } 96 if (WIFSTOPPED(status) && ((status>>16 == PTRACE_EVENT_FORK) || (status>>16 == PTRACE_EVENT_VFORK) || (status>>16 == PTRACE_EVENT_CLONE))) { 97 unsigned long data; 98 ptrace(PTRACE_GETEVENTMSG, pid, NULL, &data); 99 event.type = EVENT_CLONE; 100 event.e_un.newpid = data; 101 debug(DEBUG_EVENT, "event: CLONE: pid=%d, newpid=%d", pid, (int)data); 102 return &event; 103 } 104 if (WIFSTOPPED(status) && (status>>16 == PTRACE_EVENT_EXEC)) { 105 event.type = EVENT_EXEC; 106 debug(DEBUG_EVENT, "event: EXEC: pid=%d", pid); 107 return &event; 108 } 109 if (WIFEXITED(status)) { 110 event.type = EVENT_EXIT; 111 event.e_un.ret_val = WEXITSTATUS(status); 112 debug(DEBUG_EVENT, "event: EXIT: pid=%d, status=%d", pid, event.e_un.ret_val); 113 return &event; 114 } 115 if (WIFSIGNALED(status)) { 116 event.type = EVENT_EXIT_SIGNAL; 117 event.e_un.signum = WTERMSIG(status); 118 debug(DEBUG_EVENT, "event: EXIT_SIGNAL: pid=%d, signum=%d", pid, event.e_un.signum); 119 return &event; 120 } 121 if (!WIFSTOPPED(status)) { 122 /* should never happen */ 123 event.type = EVENT_NONE; 124 debug(DEBUG_EVENT, "event: NONE: pid=%d (wait error?)", pid); 125 return &event; 126 } 127 128 stop_signal = WSTOPSIG(status); 129 130 /* On some targets, breakpoints are signalled not using 131 SIGTRAP, but also with SIGILL, SIGSEGV or SIGEMT. Check 132 for these. (TODO: is this true?) */ 133 if (stop_signal == SIGSEGV 134 || stop_signal == SIGILL 135#ifdef SIGEMT 136 || stop_signal == SIGEMT 137#endif 138 ) { 139 if (!event.proc->instruction_pointer) { 140 event.proc->instruction_pointer = 141 get_instruction_pointer(event.proc); 142 } 143 144 if (address2bpstruct(event.proc, event.proc->instruction_pointer)) 145 stop_signal = SIGTRAP; 146 } 147 148 if (stop_signal != (SIGTRAP | event.proc->tracesysgood) 149 && stop_signal != SIGTRAP) { 150 event.type = EVENT_SIGNAL; 151 event.e_un.signum = stop_signal; 152 debug(DEBUG_EVENT, "event: SIGNAL: pid=%d, signum=%d", pid, stop_signal); 153 return &event; 154 } 155 156 /* last case [by exhaustion] */ 157 event.type = EVENT_BREAKPOINT; 158 159 if (!event.proc->instruction_pointer) { 160 event.proc->instruction_pointer = 161 get_instruction_pointer(event.proc); 162 } 163 event.e_un.brk_addr = 164 event.proc->instruction_pointer - DECR_PC_AFTER_BREAK; 165 debug(DEBUG_EVENT, "event: BREAKPOINT: pid=%d, addr=%p", pid, event.e_un.brk_addr); 166 return &event; 167} 168