handle_event.c revision 218c5ff26841f5bbd188c42ccbd67422a7a20556
1#define _GNU_SOURCE
2#include "config.h"
3
4#include <assert.h>
5#include <errno.h>
6#include <error.h>
7#include <signal.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11#include <sys/time.h>
12
13#include "breakpoint.h"
14#include "common.h"
15#include "library.h"
16#include "proc.h"
17
18static void handle_signal(Event *event);
19static void handle_exit(Event *event);
20static void handle_exit_signal(Event *event);
21static void handle_syscall(Event *event);
22static void handle_arch_syscall(Event *event);
23static void handle_sysret(Event *event);
24static void handle_arch_sysret(Event *event);
25static void handle_clone(Event *event);
26static void handle_exec(Event *event);
27static void handle_breakpoint(Event *event);
28static void handle_new(Event *event);
29
30static void callstack_push_syscall(Process *proc, int sysnum);
31static void callstack_push_symfunc(Process *proc,
32				   struct library_symbol *sym);
33static void callstack_pop(Process *proc);
34
35static char * shortsignal(Process *proc, int signum);
36static char * sysname(Process *proc, int sysnum);
37static char * arch_sysname(Process *proc, int sysnum);
38
39static Event *
40call_handler(Process * proc, Event * event)
41{
42	assert(proc != NULL);
43
44	struct event_handler *handler = proc->event_handler;
45	if (handler == NULL)
46		return event;
47
48	return (*handler->on_event) (handler, event);
49}
50
51void
52handle_event(Event *event)
53{
54	if (exiting == 1) {
55		debug(1, "ltrace about to exit");
56		os_ltrace_exiting();
57		exiting = 2;
58	}
59	debug(DEBUG_FUNCTION, "handle_event(pid=%d, type=%d)",
60	      event->proc ? event->proc->pid : -1, event->type);
61
62	/* If the thread group or an individual task define an
63	   overriding event handler, give them a chance to kick in.
64	   We will end up calling both handlers, if the first one
65	   doesn't sink the event.  */
66	if (event->proc != NULL) {
67		event = call_handler(event->proc, event);
68		if (event == NULL)
69			/* It was handled.  */
70			return;
71
72		/* Note: the previous handler has a chance to alter
73		 * the event.  */
74		if (event->proc != NULL
75		    && event->proc->leader != NULL
76		    && event->proc != event->proc->leader) {
77			event = call_handler(event->proc->leader, event);
78			if (event == NULL)
79				return;
80		}
81	}
82
83	switch (event->type) {
84	case EVENT_NONE:
85		debug(1, "event: none");
86		return;
87	case EVENT_SIGNAL:
88		debug(1, "[%d] event: signal (%s [%d])",
89		      event->proc->pid,
90		      shortsignal(event->proc, event->e_un.signum),
91		      event->e_un.signum);
92		handle_signal(event);
93		return;
94	case EVENT_EXIT:
95		debug(1, "[%d] event: exit (%d)",
96		      event->proc->pid,
97		      event->e_un.ret_val);
98		handle_exit(event);
99		return;
100	case EVENT_EXIT_SIGNAL:
101		debug(1, "[%d] event: exit signal (%s [%d])",
102		      event->proc->pid,
103		      shortsignal(event->proc, event->e_un.signum),
104		      event->e_un.signum);
105		handle_exit_signal(event);
106		return;
107	case EVENT_SYSCALL:
108		debug(1, "[%d] event: syscall (%s [%d])",
109		      event->proc->pid,
110		      sysname(event->proc, event->e_un.sysnum),
111		      event->e_un.sysnum);
112		handle_syscall(event);
113		return;
114	case EVENT_SYSRET:
115		debug(1, "[%d] event: sysret (%s [%d])",
116		      event->proc->pid,
117		      sysname(event->proc, event->e_un.sysnum),
118		      event->e_un.sysnum);
119		handle_sysret(event);
120		return;
121	case EVENT_ARCH_SYSCALL:
122		debug(1, "[%d] event: arch_syscall (%s [%d])",
123		      event->proc->pid,
124		      arch_sysname(event->proc, event->e_un.sysnum),
125		      event->e_un.sysnum);
126		handle_arch_syscall(event);
127		return;
128	case EVENT_ARCH_SYSRET:
129		debug(1, "[%d] event: arch_sysret (%s [%d])",
130		      event->proc->pid,
131		      arch_sysname(event->proc, event->e_un.sysnum),
132		      event->e_un.sysnum);
133		handle_arch_sysret(event);
134		return;
135	case EVENT_CLONE:
136	case EVENT_VFORK:
137		debug(1, "[%d] event: clone (%u)",
138		      event->proc->pid, event->e_un.newpid);
139		handle_clone(event);
140		return;
141	case EVENT_EXEC:
142		debug(1, "[%d] event: exec()",
143		      event->proc->pid);
144		handle_exec(event);
145		return;
146	case EVENT_BREAKPOINT:
147		debug(1, "[%d] event: breakpoint %p",
148		      event->proc->pid, event->e_un.brk_addr);
149		handle_breakpoint(event);
150		return;
151	case EVENT_NEW:
152		debug(1, "[%d] event: new process",
153		      event->e_un.newpid);
154		handle_new(event);
155		return;
156	default:
157		fprintf(stderr, "Error! unknown event?\n");
158		exit(1);
159	}
160}
161
162typedef struct Pending_New Pending_New;
163struct Pending_New {
164	pid_t pid;
165	Pending_New * next;
166};
167static Pending_New * pending_news = NULL;
168
169static int
170pending_new(pid_t pid) {
171	Pending_New * p;
172
173	debug(DEBUG_FUNCTION, "pending_new(%d)", pid);
174
175	p = pending_news;
176	while (p) {
177		if (p->pid == pid) {
178			return 1;
179		}
180		p = p->next;
181	}
182	return 0;
183}
184
185static void
186pending_new_insert(pid_t pid) {
187	Pending_New * p;
188
189	debug(DEBUG_FUNCTION, "pending_new_insert(%d)", pid);
190
191	p = malloc(sizeof(Pending_New));
192	if (!p) {
193		perror("malloc()");
194		exit(1);
195	}
196	p->pid = pid;
197	p->next = pending_news;
198	pending_news = p;
199}
200
201static void
202pending_new_remove(pid_t pid) {
203	Pending_New *p, *pred;
204
205	debug(DEBUG_FUNCTION, "pending_new_remove(%d)", pid);
206
207	p = pending_news;
208	if (p->pid == pid) {
209		pending_news = p->next;
210		free(p);
211	} else {
212		while (p) {
213			if (p->pid == pid) {
214				pred->next = p->next;
215				free(p);
216			}
217			pred = p;
218			p = p->next;
219		}
220	}
221}
222
223static void
224handle_clone(Event *event)
225{
226	debug(DEBUG_FUNCTION, "handle_clone(pid=%d)", event->proc->pid);
227
228	struct Process *proc = malloc(sizeof(*proc));
229	if (proc == NULL) {
230	fail:
231		free(proc);
232		/* XXX proper error handling here, please.  */
233		perror("malloc()");
234		exit(1);
235	}
236
237	if (process_clone(proc, event->proc, event->e_un.newpid) < 0)
238		goto fail;
239	proc->parent = event->proc;
240
241	/* We save register values to the arch pointer, and these need
242	   to be per-thread.  */
243	proc->arch_ptr = NULL;
244
245	if (pending_new(proc->pid)) {
246		pending_new_remove(proc->pid);
247		/* XXX this used to be destroy_event_handler call, but
248		 * I don't think we want to call that on a shared
249		 * state.  */
250		proc->event_handler = NULL;
251		if (event->proc->state == STATE_ATTACHED && options.follow)
252			proc->state = STATE_ATTACHED;
253		else
254			proc->state = STATE_IGNORED;
255		continue_process(proc->pid);
256	} else {
257		proc->state = STATE_BEING_CREATED;
258	}
259
260	if (event->type == EVENT_VFORK)
261		continue_after_vfork(proc);
262	else
263		continue_process(event->proc->pid);
264}
265
266static void
267handle_new(Event * event) {
268	Process * proc;
269
270	debug(DEBUG_FUNCTION, "handle_new(pid=%d)", event->e_un.newpid);
271
272	proc = pid2proc(event->e_un.newpid);
273	if (!proc) {
274		pending_new_insert(event->e_un.newpid);
275	} else {
276		assert(proc->state == STATE_BEING_CREATED);
277		if (options.follow) {
278			proc->state = STATE_ATTACHED;
279		} else {
280			proc->state = STATE_IGNORED;
281		}
282		continue_process(proc->pid);
283	}
284}
285
286static char *
287shortsignal(Process *proc, int signum) {
288	static char *signalent0[] = {
289#include "signalent.h"
290	};
291	static char *signalent1[] = {
292#include "signalent1.h"
293	};
294	static char **signalents[] = { signalent0, signalent1 };
295	int nsignals[] = { sizeof signalent0 / sizeof signalent0[0],
296		sizeof signalent1 / sizeof signalent1[0]
297	};
298
299	debug(DEBUG_FUNCTION, "shortsignal(pid=%d, signum=%d)", proc->pid, signum);
300
301	if (proc->personality > sizeof signalents / sizeof signalents[0])
302		abort();
303	if (signum < 0 || signum >= nsignals[proc->personality]) {
304		return "UNKNOWN_SIGNAL";
305	} else {
306		return signalents[proc->personality][signum];
307	}
308}
309
310static char *
311sysname(Process *proc, int sysnum) {
312	static char result[128];
313	static char *syscalent0[] = {
314#include "syscallent.h"
315	};
316	static char *syscalent1[] = {
317#include "syscallent1.h"
318	};
319	static char **syscalents[] = { syscalent0, syscalent1 };
320	int nsyscals[] = { sizeof syscalent0 / sizeof syscalent0[0],
321		sizeof syscalent1 / sizeof syscalent1[0]
322	};
323
324	debug(DEBUG_FUNCTION, "sysname(pid=%d, sysnum=%d)", proc->pid, sysnum);
325
326	if (proc->personality > sizeof syscalents / sizeof syscalents[0])
327		abort();
328	if (sysnum < 0 || sysnum >= nsyscals[proc->personality]) {
329		sprintf(result, "SYS_%d", sysnum);
330		return result;
331	} else {
332		sprintf(result, "SYS_%s",
333			syscalents[proc->personality][sysnum]);
334		return result;
335	}
336}
337
338static char *
339arch_sysname(Process *proc, int sysnum) {
340	static char result[128];
341	static char *arch_syscalent[] = {
342#include "arch_syscallent.h"
343	};
344	int nsyscals = sizeof arch_syscalent / sizeof arch_syscalent[0];
345
346	debug(DEBUG_FUNCTION, "arch_sysname(pid=%d, sysnum=%d)", proc->pid, sysnum);
347
348	if (sysnum < 0 || sysnum >= nsyscals) {
349		sprintf(result, "ARCH_%d", sysnum);
350		return result;
351	} else {
352		sprintf(result, "ARCH_%s",
353				arch_syscalent[sysnum]);
354		return result;
355	}
356}
357
358static void
359handle_signal(Event *event) {
360	debug(DEBUG_FUNCTION, "handle_signal(pid=%d, signum=%d)", event->proc->pid, event->e_un.signum);
361	if (event->proc->state != STATE_IGNORED && !options.no_signals) {
362		output_line(event->proc, "--- %s (%s) ---",
363				shortsignal(event->proc, event->e_un.signum),
364				strsignal(event->e_un.signum));
365	}
366	continue_after_signal(event->proc->pid, event->e_un.signum);
367}
368
369static void
370handle_exit(Event *event) {
371	debug(DEBUG_FUNCTION, "handle_exit(pid=%d, status=%d)", event->proc->pid, event->e_un.ret_val);
372	if (event->proc->state != STATE_IGNORED) {
373		output_line(event->proc, "+++ exited (status %d) +++",
374				event->e_un.ret_val);
375	}
376	remove_process(event->proc);
377	free(event->proc);
378}
379
380static void
381handle_exit_signal(Event *event) {
382	debug(DEBUG_FUNCTION, "handle_exit_signal(pid=%d, signum=%d)", event->proc->pid, event->e_un.signum);
383	if (event->proc->state != STATE_IGNORED) {
384		output_line(event->proc, "+++ killed by %s +++",
385				shortsignal(event->proc, event->e_un.signum));
386	}
387	remove_process(event->proc);
388	free(event->proc);
389}
390
391static struct library_symbol *
392temporary_syscall_symbol(const char *name)
393{
394	struct library *syscalls = malloc(sizeof(*syscalls));
395	struct library_symbol *syscall = malloc(sizeof(*syscall));
396	if (syscalls == NULL || syscall == NULL) {
397		free(syscalls);
398		free(syscall);
399		return NULL;
400	}
401	/* XXX TODO: this needs to be fleshed out.  */
402	library_init(syscalls, (enum library_type)-1);
403	library_set_soname(syscalls, "SYS", 0);
404	if (library_symbol_init(syscall, 0, name, 0, LS_TOPLT_NONE) < 0)
405		abort();
406	library_add_symbol(syscalls, syscall);
407	return syscall;
408}
409
410static void
411output_syscall_left(struct Process *proc, const char *name)
412{
413	struct library_symbol *syscall = temporary_syscall_symbol(name);
414	output_left(LT_TOF_SYSCALL, proc, syscall);
415	struct library *lib = syscall->lib;
416	library_destroy(lib);
417	free(lib);
418}
419
420static void
421output_syscall_right(struct Process *proc, const char *name)
422{
423	struct library_symbol *syscall = temporary_syscall_symbol(name);
424	output_right(LT_TOF_SYSCALLR, proc, syscall);
425	struct library *lib = syscall->lib;
426	library_destroy(lib);
427	free(lib);
428}
429
430static void
431handle_syscall(Event *event) {
432	debug(DEBUG_FUNCTION, "handle_syscall(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum);
433	if (event->proc->state != STATE_IGNORED) {
434		callstack_push_syscall(event->proc, event->e_un.sysnum);
435		if (options.syscalls)
436			output_syscall_left(event->proc,
437					    sysname(event->proc,
438						    event->e_un.sysnum));
439	}
440	continue_after_syscall(event->proc, event->e_un.sysnum, 0);
441}
442
443static void
444handle_exec(Event * event) {
445	Process * proc = event->proc;
446
447	/* Save the PID so that we can use it after unsuccessful
448	 * process_exec.  */
449	pid_t pid = proc->pid;
450
451	debug(DEBUG_FUNCTION, "handle_exec(pid=%d)", proc->pid);
452	if (proc->state == STATE_IGNORED) {
453	untrace:
454		untrace_pid(pid);
455		remove_process(proc);
456		free(proc);
457		return;
458	}
459	output_line(proc, "--- Called exec() ---");
460
461	if (process_exec(proc) < 0) {
462		error(0, errno,
463		      "couldn't reinitialize process %d after exec", pid);
464		goto untrace;
465	}
466
467	continue_process(proc->pid);
468
469	/* After the exec, we expect to hit the first executable
470	 * instruction.
471	 *
472	 * XXX TODO It would be nice to have this removed, but then we
473	 * need to do that also for initial call to wait_for_proc in
474	 * execute_program.  In that case we could generate a
475	 * EVENT_FIRST event or something, or maybe this could somehow
476	 * be rolled into EVENT_NEW.  */
477	wait_for_proc(proc->pid);
478	continue_process(proc->pid);
479}
480
481static void
482handle_arch_syscall(Event *event) {
483	debug(DEBUG_FUNCTION, "handle_arch_syscall(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum);
484	if (event->proc->state != STATE_IGNORED) {
485		callstack_push_syscall(event->proc, 0xf0000 + event->e_un.sysnum);
486		if (options.syscalls) {
487			output_syscall_left(event->proc,
488					    arch_sysname(event->proc,
489							 event->e_un.sysnum));
490		}
491	}
492	continue_process(event->proc->pid);
493}
494
495struct timeval current_time_spent;
496
497static void
498calc_time_spent(Process *proc) {
499	struct timeval tv;
500	struct timezone tz;
501	struct timeval diff;
502	struct callstack_element *elem;
503
504	debug(DEBUG_FUNCTION, "calc_time_spent(pid=%d)", proc->pid);
505	elem = &proc->callstack[proc->callstack_depth - 1];
506
507	gettimeofday(&tv, &tz);
508
509	diff.tv_sec = tv.tv_sec - elem->time_spent.tv_sec;
510	if (tv.tv_usec >= elem->time_spent.tv_usec) {
511		diff.tv_usec = tv.tv_usec - elem->time_spent.tv_usec;
512	} else {
513		diff.tv_sec++;
514		diff.tv_usec = 1000000 + tv.tv_usec - elem->time_spent.tv_usec;
515	}
516	current_time_spent = diff;
517}
518
519static void
520handle_sysret(Event *event) {
521	debug(DEBUG_FUNCTION, "handle_sysret(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum);
522	if (event->proc->state != STATE_IGNORED) {
523		if (opt_T || options.summary) {
524			calc_time_spent(event->proc);
525		}
526		if (options.syscalls)
527			output_syscall_right(event->proc,
528					     sysname(event->proc,
529						     event->e_un.sysnum));
530
531		assert(event->proc->callstack_depth > 0);
532		unsigned d = event->proc->callstack_depth - 1;
533		assert(event->proc->callstack[d].is_syscall);
534		callstack_pop(event->proc);
535	}
536	continue_after_syscall(event->proc, event->e_un.sysnum, 1);
537}
538
539static void
540handle_arch_sysret(Event *event) {
541	debug(DEBUG_FUNCTION, "handle_arch_sysret(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum);
542	if (event->proc->state != STATE_IGNORED) {
543		if (opt_T || options.summary) {
544			calc_time_spent(event->proc);
545		}
546		if (options.syscalls)
547			output_syscall_right(event->proc,
548					     arch_sysname(event->proc,
549							  event->e_un.sysnum));
550		callstack_pop(event->proc);
551	}
552	continue_process(event->proc->pid);
553}
554
555static void
556output_right_tos(struct Process *proc)
557{
558	size_t d = proc->callstack_depth;
559	struct callstack_element *elem = &proc->callstack[d - 1];
560	if (proc->state != STATE_IGNORED)
561		output_right(LT_TOF_FUNCTIONR, proc, elem->c_un.libfunc->name);
562}
563
564static void
565handle_breakpoint(Event *event)
566{
567	int i, j;
568	struct breakpoint *sbp;
569	Process *leader = event->proc->leader;
570	void *brk_addr = event->e_un.brk_addr;
571
572	/* The leader has terminated.  */
573	if (leader == NULL) {
574		continue_process(event->proc->pid);
575		return;
576	}
577
578	debug(DEBUG_FUNCTION, "handle_breakpoint(pid=%d, addr=%p)",
579	      event->proc->pid, brk_addr);
580	debug(2, "event: breakpoint (%p)", brk_addr);
581
582	for (i = event->proc->callstack_depth - 1; i >= 0; i--) {
583		if (brk_addr == event->proc->callstack[i].return_addr) {
584#if defined(__mips__)
585			void *addr = NULL;
586			struct library_symbol *sym= event->proc->callstack[i].c_un.libfunc;
587			struct library_symbol *new_sym;
588			assert(sym);
589			addr = sym2addr(event->proc, sym);
590			sbp = dict_find_entry(leader->breakpoints, addr);
591			if (sbp) {
592				if (addr != sbp->addr) {
593					insert_breakpoint(event->proc, addr, sym);
594				}
595			} else {
596				new_sym=malloc(sizeof(*new_sym) + strlen(sym->name) + 1);
597				memcpy(new_sym,sym,sizeof(*new_sym) + strlen(sym->name) + 1);
598				new_sym->next = leader->list_of_symbols;
599				leader->list_of_symbols = new_sym;
600				insert_breakpoint(event->proc, addr, new_sym);
601			}
602#endif
603			for (j = event->proc->callstack_depth - 1; j > i; j--) {
604				callstack_pop(event->proc);
605			}
606			if (event->proc->state != STATE_IGNORED) {
607				if (opt_T || options.summary) {
608					calc_time_spent(event->proc);
609				}
610			}
611			event->proc->return_addr = brk_addr;
612
613			output_right_tos(event->proc);
614			callstack_pop(event->proc);
615
616			/* Pop also any other entries that seem like
617			 * they are linked to the current one: they
618			 * have the same return address, but were made
619			 * for different symbols.  This should only
620			 * happen for entry point tracing, i.e. for -x
621			 * everywhere, or -x and -e on PPC64.  */
622			while (event->proc->callstack_depth > 0) {
623				struct callstack_element *prev;
624				size_t d = event->proc->callstack_depth;
625				prev = &event->proc->callstack[d - 1];
626
627				if (prev->c_un.libfunc == libsym
628				    || prev->return_addr != brk_addr)
629					break;
630
631				output_right_tos(event->proc);
632				callstack_pop(event->proc);
633			}
634
635			sbp = address2bpstruct(leader, brk_addr);
636			continue_after_breakpoint(event->proc, sbp);
637			return;
638		}
639	}
640
641	if ((sbp = address2bpstruct(leader, brk_addr))) {
642		breakpoint_on_hit(sbp, event->proc);
643
644		if (event->proc->state != STATE_IGNORED
645		    && sbp->libsym != NULL) {
646			event->proc->stack_pointer = get_stack_pointer(event->proc);
647			event->proc->return_addr =
648				get_return_addr(event->proc, event->proc->stack_pointer);
649			callstack_push_symfunc(event->proc, sbp->libsym);
650			output_left(LT_TOF_FUNCTION, event->proc, sbp->libsym);
651		}
652
653		breakpoint_on_continue(sbp, event->proc);
654		return;
655	}
656
657	if (event->proc->state != STATE_IGNORED)
658		output_line(event->proc, "unexpected breakpoint at %p",
659			    brk_addr);
660
661	continue_process(event->proc->pid);
662}
663
664static void
665callstack_push_syscall(Process *proc, int sysnum) {
666	struct callstack_element *elem;
667
668	debug(DEBUG_FUNCTION, "callstack_push_syscall(pid=%d, sysnum=%d)", proc->pid, sysnum);
669	/* FIXME: not good -- should use dynamic allocation. 19990703 mortene. */
670	if (proc->callstack_depth == MAX_CALLDEPTH - 1) {
671		fprintf(stderr, "%s: Error: call nesting too deep!\n", __func__);
672		abort();
673		return;
674	}
675
676	elem = &proc->callstack[proc->callstack_depth];
677	elem->is_syscall = 1;
678	elem->c_un.syscall = sysnum;
679	elem->return_addr = NULL;
680
681	proc->callstack_depth++;
682	if (opt_T || options.summary) {
683		struct timezone tz;
684		gettimeofday(&elem->time_spent, &tz);
685	}
686}
687
688static void
689callstack_push_symfunc(Process *proc, struct library_symbol *sym) {
690	struct callstack_element *elem;
691
692	debug(DEBUG_FUNCTION, "callstack_push_symfunc(pid=%d, symbol=%s)", proc->pid, sym->name);
693	/* FIXME: not good -- should use dynamic allocation. 19990703 mortene. */
694	if (proc->callstack_depth == MAX_CALLDEPTH - 1) {
695		fprintf(stderr, "%s: Error: call nesting too deep!\n", __func__);
696		abort();
697		return;
698	}
699
700	elem = &proc->callstack[proc->callstack_depth++];
701	elem->is_syscall = 0;
702	elem->c_un.libfunc = sym;
703
704	elem->return_addr = proc->return_addr;
705	if (elem->return_addr)
706		insert_breakpoint(proc, elem->return_addr, NULL);
707
708	/* handle functions like atexit() on mips which have no return */
709	if (opt_T || options.summary) {
710		struct timezone tz;
711		gettimeofday(&elem->time_spent, &tz);
712	}
713}
714
715static void
716callstack_pop(Process *proc) {
717	struct callstack_element *elem;
718	assert(proc->callstack_depth > 0);
719
720	debug(DEBUG_FUNCTION, "callstack_pop(pid=%d)", proc->pid);
721	elem = &proc->callstack[proc->callstack_depth - 1];
722	if (!elem->is_syscall && elem->return_addr) {
723		assert(proc->leader != NULL);
724		delete_breakpoint(proc, elem->return_addr);
725	}
726	if (elem->arch_ptr != NULL) {
727		free(elem->arch_ptr);
728		elem->arch_ptr = NULL;
729	}
730	proc->callstack_depth--;
731}
732