10 #include <sys/ptrace.h>
23 debug(DEBUG_FUNCTION, "next_event()");
24 if (!list_of_processes) {
25 debug(DEBUG_EVENT, "event: No more traced programs: exiting");
28 pid = waitpid(-1, &status, __WALL);
30 if (errno == ECHILD) {
31 debug(DEBUG_EVENT, "event: No more traced programs: exiting");
33 } else if (errno == EINTR) {
34 debug(DEBUG_EVENT, "event: none (wait received EINTR?)");
35 event.type = EVENT_NONE;
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);
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 enable_all_breakpoints(event.proc);
53 event.type = EVENT_NONE;
54 trace_set_options(event.proc, event.proc->pid);
55 continue_process(event.proc->pid);
56 debug(DEBUG_EVENT, "event: NONE: pid=%d (enabling breakpoints)", pid);
60 event.proc->instruction_pointer =
61 get_instruction_pointer(event.proc);
63 switch (syscall_p(event.proc, status, &tmp)) {
65 event.type = EVENT_SYSCALL;
66 event.e_un.sysnum = tmp;
67 debug(DEBUG_EVENT, "event: SYSCALL: pid=%d, sysnum=%d", pid, tmp);
70 event.type = EVENT_SYSRET;
71 event.e_un.sysnum = tmp;
72 debug(DEBUG_EVENT, "event: SYSRET: pid=%d, sysnum=%d", pid, tmp);
75 event.type = EVENT_ARCH_SYSCALL;
76 event.e_un.sysnum = tmp;
77 debug(DEBUG_EVENT, "event: ARCH_SYSCALL: pid=%d, sysnum=%d", pid, tmp);
80 event.type = EVENT_ARCH_SYSRET;
81 event.e_un.sysnum = tmp;
82 debug(DEBUG_EVENT, "event: ARCH_SYSRET: pid=%d, sysnum=%d", pid, tmp);
85 event.type = EVENT_NONE;
86 continue_process(event.proc->pid);
87 debug(DEBUG_EVENT, "event: NONE: pid=%d (syscall_p returned -1)", pid);
90 if (WIFSTOPPED(status) && ((status>>16 == PTRACE_EVENT_FORK) || (status>>16 == PTRACE_EVENT_VFORK) || (status>>16 == PTRACE_EVENT_CLONE))) {
92 ptrace(PTRACE_GETEVENTMSG, pid, NULL, &data);
93 event.type = EVENT_CLONE;
94 event.e_un.newpid = data;
95 debug(DEBUG_EVENT, "event: CLONE: pid=%d, newpid=%d", pid, (int)data);
98 if (WIFSTOPPED(status) && (status>>16 == PTRACE_EVENT_EXEC)) {
99 event.type = EVENT_EXEC;
100 debug(DEBUG_EVENT, "event: EXEC: pid=%d", pid);
103 if (WIFEXITED(status)) {
104 event.type = EVENT_EXIT;
105 event.e_un.ret_val = WEXITSTATUS(status);
106 debug(DEBUG_EVENT, "event: EXIT: pid=%d, status=%d", pid, event.e_un.ret_val);
109 if (WIFSIGNALED(status)) {
110 event.type = EVENT_EXIT_SIGNAL;
111 event.e_un.signum = WTERMSIG(status);
112 debug(DEBUG_EVENT, "event: EXIT_SIGNAL: pid=%d, signum=%d", pid, event.e_un.signum);
115 if (!WIFSTOPPED(status)) {
116 /* should never happen */
117 event.type = EVENT_NONE;
118 debug(DEBUG_EVENT, "event: NONE: pid=%d (wait error?)", pid);
122 stop_signal = WSTOPSIG(status);
124 /* On some targets, breakpoints are signalled not using
125 SIGTRAP, but also with SIGILL, SIGSEGV or SIGEMT. Check
126 for these. (TODO: is this true?) */
127 if (stop_signal == SIGSEGV
128 || stop_signal == SIGILL
130 || stop_signal == SIGEMT
133 if (!event.proc->instruction_pointer) {
134 event.proc->instruction_pointer =
135 get_instruction_pointer(event.proc);
138 if (address2bpstruct(event.proc, event.proc->instruction_pointer))
139 stop_signal = SIGTRAP;
142 if (stop_signal != (SIGTRAP | event.proc->tracesysgood)
143 && stop_signal != SIGTRAP) {
144 event.type = EVENT_SIGNAL;
145 event.e_un.signum = stop_signal;
146 debug(DEBUG_EVENT, "event: SIGNAL: pid=%d, signum=%d", pid, stop_signal);
150 /* last case [by exhaustion] */
151 event.type = EVENT_BREAKPOINT;
153 if (!event.proc->instruction_pointer) {
154 event.proc->instruction_pointer =
155 get_instruction_pointer(event.proc);
157 event.e_un.brk_addr =
158 event.proc->instruction_pointer - DECR_PC_AFTER_BREAK;
159 debug(DEBUG_EVENT, "event: BREAKPOINT: pid=%d, addr=%p", pid, event.e_un.brk_addr);