events.c revision cebb88491e68bdf4d466b03970c9ca77f65615f8
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 16static enum pcb_status 17first (Process * proc, void * data) 18{ 19 return pcb_stop; 20} 21 22Event * 23next_event(void) 24{ 25 pid_t pid; 26 int status; 27 int tmp; 28 int stop_signal; 29 30 debug(DEBUG_FUNCTION, "next_event()"); 31 if (!each_process(NULL, &first, NULL)) { 32 debug(DEBUG_EVENT, "event: No more traced programs: exiting"); 33 exit(0); 34 } 35 pid = waitpid(-1, &status, __WALL); 36 if (pid == -1) { 37 if (errno == ECHILD) { 38 debug(DEBUG_EVENT, "event: No more traced programs: exiting"); 39 exit(0); 40 } else if (errno == EINTR) { 41 debug(DEBUG_EVENT, "event: none (wait received EINTR?)"); 42 event.type = EVENT_NONE; 43 return &event; 44 } 45 perror("wait"); 46 exit(1); 47 } 48 event.proc = pid2proc(pid); 49 if (!event.proc || event.proc->state == STATE_BEING_CREATED) { 50 event.type = EVENT_NEW; 51 event.e_un.newpid = pid; 52 debug(DEBUG_EVENT, "event: NEW: pid=%d", pid); 53 return &event; 54 } 55 get_arch_dep(event.proc); 56 event.proc->instruction_pointer = NULL; 57 debug(3, "event from pid %u", pid); 58 if (event.proc->breakpoints_enabled == -1) { 59 event.type = EVENT_NONE; 60 trace_set_options(event.proc, event.proc->pid); 61 enable_all_breakpoints(event.proc); 62 continue_process(event.proc->pid); 63 debug(DEBUG_EVENT, "event: NONE: pid=%d (enabling breakpoints)", pid); 64 return &event; 65 } else if (!event.proc->libdl_hooked) { 66 /* debug struct may not have been written yet.. */ 67 if (linkmap_init(event.proc, &main_lte) == 0) { 68 event.proc->libdl_hooked = 1; 69 } 70 } 71 72 73 event.proc->instruction_pointer = get_instruction_pointer(event.proc); 74 if (event.proc->instruction_pointer == (void *)(uintptr_t)-1) { 75 if (errno != 0) 76 perror("get_instruction_pointer"); 77 } 78 79 switch (syscall_p(event.proc, status, &tmp)) { 80 case 1: 81 event.type = EVENT_SYSCALL; 82 event.e_un.sysnum = tmp; 83 debug(DEBUG_EVENT, "event: SYSCALL: pid=%d, sysnum=%d", pid, tmp); 84 return &event; 85 case 2: 86 event.type = EVENT_SYSRET; 87 event.e_un.sysnum = tmp; 88 debug(DEBUG_EVENT, "event: SYSRET: pid=%d, sysnum=%d", pid, tmp); 89 return &event; 90 case 3: 91 event.type = EVENT_ARCH_SYSCALL; 92 event.e_un.sysnum = tmp; 93 debug(DEBUG_EVENT, "event: ARCH_SYSCALL: pid=%d, sysnum=%d", pid, tmp); 94 return &event; 95 case 4: 96 event.type = EVENT_ARCH_SYSRET; 97 event.e_un.sysnum = tmp; 98 debug(DEBUG_EVENT, "event: ARCH_SYSRET: pid=%d, sysnum=%d", pid, tmp); 99 return &event; 100 case -1: 101 event.type = EVENT_NONE; 102 continue_process(event.proc->pid); 103 debug(DEBUG_EVENT, "event: NONE: pid=%d (syscall_p returned -1)", pid); 104 return &event; 105 } 106 if (WIFSTOPPED(status) && ((status>>16 == PTRACE_EVENT_FORK) || (status>>16 == PTRACE_EVENT_VFORK) || (status>>16 == PTRACE_EVENT_CLONE))) { 107 unsigned long data; 108 ptrace(PTRACE_GETEVENTMSG, pid, NULL, &data); 109 event.type = EVENT_CLONE; 110 event.e_un.newpid = data; 111 debug(DEBUG_EVENT, "event: CLONE: pid=%d, newpid=%d", pid, (int)data); 112 return &event; 113 } 114 if (WIFSTOPPED(status) && (status>>16 == PTRACE_EVENT_EXEC)) { 115 event.type = EVENT_EXEC; 116 debug(DEBUG_EVENT, "event: EXEC: pid=%d", pid); 117 return &event; 118 } 119 if (WIFEXITED(status)) { 120 event.type = EVENT_EXIT; 121 event.e_un.ret_val = WEXITSTATUS(status); 122 debug(DEBUG_EVENT, "event: EXIT: pid=%d, status=%d", pid, event.e_un.ret_val); 123 return &event; 124 } 125 if (WIFSIGNALED(status)) { 126 event.type = EVENT_EXIT_SIGNAL; 127 event.e_un.signum = WTERMSIG(status); 128 debug(DEBUG_EVENT, "event: EXIT_SIGNAL: pid=%d, signum=%d", pid, event.e_un.signum); 129 return &event; 130 } 131 if (!WIFSTOPPED(status)) { 132 /* should never happen */ 133 event.type = EVENT_NONE; 134 debug(DEBUG_EVENT, "event: NONE: pid=%d (wait error?)", pid); 135 return &event; 136 } 137 138 stop_signal = WSTOPSIG(status); 139 140 /* On some targets, breakpoints are signalled not using 141 SIGTRAP, but also with SIGILL, SIGSEGV or SIGEMT. SIGEMT 142 is not defined on Linux, but check for the others. 143 144 N.B. see comments in GDB's infrun.c for details. I've 145 actually seen this on an Itanium machine on RHEL 5, I don't 146 remember the exact kernel version anymore. ia64-sigill.s 147 in the test suite tests this. Petr Machata 2011-06-08. */ 148 void * break_address 149 = event.proc->instruction_pointer - DECR_PC_AFTER_BREAK; 150 if ((stop_signal == SIGSEGV || stop_signal == SIGILL) 151 && address2bpstruct(event.proc, break_address)) 152 stop_signal = SIGTRAP; 153 154 if (stop_signal != (SIGTRAP | event.proc->tracesysgood) 155 && stop_signal != SIGTRAP) { 156 event.type = EVENT_SIGNAL; 157 event.e_un.signum = stop_signal; 158 debug(DEBUG_EVENT, "event: SIGNAL: pid=%d, signum=%d", pid, stop_signal); 159 return &event; 160 } 161 162 /* last case [by exhaustion] */ 163 event.type = EVENT_BREAKPOINT; 164 165 event.e_un.brk_addr = break_address; 166 debug(DEBUG_EVENT, "event: BREAKPOINT: pid=%d, addr=%p", pid, event.e_un.brk_addr); 167 168 return &event; 169} 170