events.c revision 63184be8c577f5799e44db2a4e312a8240ad7751
1d44c6b8b090b8b7aa9d971d9e0bfd848732a3071Juan Cespedes#if HAVE_CONFIG_H
2d44c6b8b090b8b7aa9d971d9e0bfd848732a3071Juan Cespedes#include "config.h"
3d44c6b8b090b8b7aa9d971d9e0bfd848732a3071Juan Cespedes#endif
4d44c6b8b090b8b7aa9d971d9e0bfd848732a3071Juan Cespedes
55e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes#define	_GNU_SOURCE	1
61cd999a32728f41208dc30f38a125d7bb7063625Juan Cespedes#include <stdlib.h>
75e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes#include <sys/types.h>
85e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes#include <sys/wait.h>
95e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes#include <errno.h>
105e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes#include <signal.h>
115e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes#include <string.h>
125e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes
135e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes#include "ltrace.h"
145e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes#include "options.h"
15cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes#include "debug.h"
165e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes
175e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedesstatic struct event event;
185e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes
195e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes/* This should also update `current_process' */
205e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes
212d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienandstatic struct process *pid2proc(int pid);
225e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes
232d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienandstruct event *wait_for_something(void)
242d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand{
255e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes	pid_t pid;
265e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes	int status;
275e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes	int tmp;
28ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata	int stop_signal;
295e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes
3028f60197b93b45422a73e5d1a6aa581584d6c4a5Juan Cespedes	if (!list_of_processes) {
31cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes		debug(1, "No more children");
3228f60197b93b45422a73e5d1a6aa581584d6c4a5Juan Cespedes		exit(0);
3328f60197b93b45422a73e5d1a6aa581584d6c4a5Juan Cespedes	}
345e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes	pid = wait(&status);
352d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	if (pid == -1) {
362d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand		if (errno == ECHILD) {
37cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes			debug(1, "No more children");
385e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes			exit(0);
392d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand		} else if (errno == EINTR) {
40cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes			debug(1, "wait received EINTR ?");
4128f60197b93b45422a73e5d1a6aa581584d6c4a5Juan Cespedes			event.thing = LT_EV_NONE;
4228f60197b93b45422a73e5d1a6aa581584d6c4a5Juan Cespedes			return &event;
435e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes		}
445e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes		perror("wait");
455e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes		exit(1);
465e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes	}
475e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes	event.proc = pid2proc(pid);
485e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes	if (!event.proc) {
495e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes		fprintf(stderr, "signal from wrong pid %u ?!?\n", pid);
505e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes		exit(1);
515e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes	}
525c3fe0697b202cc7d95e90459de0fb312b297b27Juan Cespedes	get_arch_dep(event.proc);
5335d70634aacdf85a3cdf85792ce68989e27bc9c2Juan Cespedes	event.proc->instruction_pointer = NULL;
54cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes	debug(3, "signal from pid %u", pid);
555e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes	if (event.proc->breakpoints_enabled == -1) {
565e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes		enable_all_breakpoints(event.proc);
575e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes		event.thing = LT_EV_NONE;
589a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand		trace_set_options(event.proc, event.proc->pid);
595e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes		continue_process(event.proc->pid);
605e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes		return &event;
615e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes	}
6235d70634aacdf85a3cdf85792ce68989e27bc9c2Juan Cespedes	if (opt_i) {
632d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand		event.proc->instruction_pointer =
642d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand		    get_instruction_pointer(event.proc);
65f0fdae9e2444c2fb7764774088c574ab53c787f4Juan Cespedes	}
662d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	switch (syscall_p(event.proc, status, &tmp)) {
6763184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes		case 1:
6863184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			event.thing = LT_EV_SYSCALL;
6963184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			event.e_un.sysnum = tmp;
7063184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			return &event;
7163184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes		case 2:
7263184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			event.thing = LT_EV_SYSRET;
7363184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			event.e_un.sysnum = tmp;
7463184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			return &event;
7563184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes		case 3:
7663184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			event.thing = LT_EV_ARCH_SYSCALL;
7763184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			event.e_un.sysnum = tmp;
7863184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			return &event;
7963184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes		case 4:
8063184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			event.thing = LT_EV_ARCH_SYSRET;
8163184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			event.e_un.sysnum = tmp;
8263184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			return &event;
8363184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes		case -1:
8463184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			event.thing = LT_EV_NONE;
8563184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			continue_process(event.proc->pid);
8663184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			return &event;
875e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes	}
885e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes	if (WIFEXITED(status)) {
895e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes		event.thing = LT_EV_EXIT;
905e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes		event.e_un.ret_val = WEXITSTATUS(status);
915e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes		return &event;
925e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes	}
935e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes	if (WIFSIGNALED(status)) {
945e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes		event.thing = LT_EV_EXIT_SIGNAL;
955e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes		event.e_un.signum = WTERMSIG(status);
965e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes		return &event;
975e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes	}
985e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes	if (!WIFSTOPPED(status)) {
995e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes		event.thing = LT_EV_UNKNOWN;
1005e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes		return &event;
1015e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes	}
102ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata
103ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata	stop_signal = WSTOPSIG(status);
104ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata
105ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata	/* On some targets, breakpoints are signalled not using
106ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata	   SIGTRAP, but also with SIGILL, SIGSEGV or SIGEMT.  Check
107ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata	   for these. */
108ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata	if (stop_signal == SIGSEGV
109ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata	    || stop_signal == SIGILL
110ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata#ifdef SIGEMT
111ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata	    || stop_signal == SIGEMT
112ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata#endif
113ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata	    ) {
114ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata		// If we didn't need to know IP so far, get it now.
115ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata		void * addr = opt_i
116ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata		  ? event.proc->instruction_pointer
117ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata		  : (event.proc->instruction_pointer = get_instruction_pointer (event.proc));
118ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata
119ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata		if (address2bpstruct(event.proc, addr))
120ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata			stop_signal = SIGTRAP;
121ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata	}
122ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata
123ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata	if (stop_signal != (SIGTRAP | event.proc->tracesysgood)
124ef46b3e70e54059a7a8bf32af7361bb262ccc8d1Petr Machata	    && stop_signal != SIGTRAP) {
1255e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes		event.thing = LT_EV_SIGNAL;
126a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes		event.e_un.signum = stop_signal;
1275e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes		return &event;
1285e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes	}
12955ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata
13055ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata	if (was_exec(event.proc, status)) {
13155ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata		pid_t saved_pid;
13255ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata
13355ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata		event.thing = LT_EV_NONE;
13455ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata		event.e_un.signum = WSTOPSIG(status);
13555ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata		debug(1, "Placing breakpoints for the new program");
13655ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata		event.proc->mask_32bit = 0;
13755ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata		event.proc->personality = 0;
13855ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata		event.proc->arch_ptr = NULL;
13955ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata		event.proc->filename = pid2name(event.proc->pid);
14055ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata		saved_pid = event.proc->pid;
14155ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata		event.proc->pid = 0;
14255ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata		breakpoints_init(event.proc);
14355ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata		event.proc->pid = saved_pid;
14455ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata		continue_process(event.proc->pid);
14555ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata		return &event;
14655ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata	}
14755ed83b24df9c6d671091a8c75caab33ffecd40ePetr Machata
1485e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes	event.thing = LT_EV_BREAKPOINT;
14935d70634aacdf85a3cdf85792ce68989e27bc9c2Juan Cespedes	if (!event.proc->instruction_pointer) {
1502d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand		event.proc->instruction_pointer =
1512d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand		    get_instruction_pointer(event.proc);
15235d70634aacdf85a3cdf85792ce68989e27bc9c2Juan Cespedes	}
1532d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	event.e_un.brk_addr =
1542d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	    event.proc->instruction_pointer - DECR_PC_AFTER_BREAK;
1555e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes	return &event;
1565e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes}
1575e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes
1582d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienandstatic struct process *pid2proc(pid_t pid)
1592d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand{
1602d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	struct process *tmp;
1615e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes
1625e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes	tmp = list_of_processes;
1632d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	while (tmp) {
1645e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes		if (pid == tmp->pid) {
1655e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes			return tmp;
1665e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes		}
1675e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes		tmp = tmp->next;
1685e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes	}
1695e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes	return NULL;
1705e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes}
171