handle_event.c revision 3d0c91c0c7b425e2866f9c65f655d399693328a5
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	library_init(syscalls, (enum library_type)-1);
402	library_set_soname(syscalls, "SYS", 0);
403	library_symbol_init(syscall, 0, name, 0, LS_TOPLT_NONE);
404	library_add_symbol(syscalls, syscall);
405	return syscall;
406}
407
408static void
409output_syscall_left(struct Process *proc, const char *name)
410{
411	struct library_symbol *syscall = temporary_syscall_symbol(name);
412	output_left(LT_TOF_SYSCALL, proc, syscall);
413	struct library *lib = syscall->lib;
414	library_destroy(lib);
415	free(lib);
416}
417
418static void
419output_syscall_right(struct Process *proc, const char *name)
420{
421	struct library_symbol *syscall = temporary_syscall_symbol(name);
422	output_right(LT_TOF_SYSCALLR, proc, syscall);
423	struct library *lib = syscall->lib;
424	library_destroy(lib);
425	free(lib);
426}
427
428static void
429handle_syscall(Event *event) {
430	debug(DEBUG_FUNCTION, "handle_syscall(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum);
431	if (event->proc->state != STATE_IGNORED) {
432		callstack_push_syscall(event->proc, event->e_un.sysnum);
433		if (options.syscalls)
434			output_syscall_left(event->proc,
435					    sysname(event->proc,
436						    event->e_un.sysnum));
437	}
438	continue_after_syscall(event->proc, event->e_un.sysnum, 0);
439}
440
441static void
442handle_exec(Event * event) {
443	Process * proc = event->proc;
444
445	/* Save the PID so that we can use it after unsuccessful
446	 * process_exec.  */
447	pid_t pid = proc->pid;
448
449	debug(DEBUG_FUNCTION, "handle_exec(pid=%d)", proc->pid);
450	if (proc->state == STATE_IGNORED) {
451	untrace:
452		untrace_pid(pid);
453		remove_process(proc);
454		free(proc);
455		return;
456	}
457	output_line(proc, "--- Called exec() ---");
458
459	if (process_exec(proc) < 0) {
460		error(0, errno,
461		      "couldn't reinitialize process %d after exec", pid);
462		goto untrace;
463	}
464
465	continue_process(proc->pid);
466
467	/* After the exec, we expect to hit the first executable
468	 * instruction.
469	 *
470	 * XXX TODO It would be nice to have this removed, but then we
471	 * need to do that also for initial call to wait_for_proc in
472	 * execute_program.  In that case we could generate a
473	 * EVENT_FIRST event or something, or maybe this could somehow
474	 * be rolled into EVENT_NEW.  */
475	wait_for_proc(proc->pid);
476	continue_process(proc->pid);
477}
478
479static void
480handle_arch_syscall(Event *event) {
481	debug(DEBUG_FUNCTION, "handle_arch_syscall(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum);
482	if (event->proc->state != STATE_IGNORED) {
483		callstack_push_syscall(event->proc, 0xf0000 + event->e_un.sysnum);
484		if (options.syscalls) {
485			output_syscall_left(event->proc,
486					    arch_sysname(event->proc,
487							 event->e_un.sysnum));
488		}
489	}
490	continue_process(event->proc->pid);
491}
492
493struct timeval current_time_spent;
494
495static void
496calc_time_spent(Process *proc) {
497	struct timeval tv;
498	struct timezone tz;
499	struct timeval diff;
500	struct callstack_element *elem;
501
502	debug(DEBUG_FUNCTION, "calc_time_spent(pid=%d)", proc->pid);
503	elem = &proc->callstack[proc->callstack_depth - 1];
504
505	gettimeofday(&tv, &tz);
506
507	diff.tv_sec = tv.tv_sec - elem->time_spent.tv_sec;
508	if (tv.tv_usec >= elem->time_spent.tv_usec) {
509		diff.tv_usec = tv.tv_usec - elem->time_spent.tv_usec;
510	} else {
511		diff.tv_sec++;
512		diff.tv_usec = 1000000 + tv.tv_usec - elem->time_spent.tv_usec;
513	}
514	current_time_spent = diff;
515}
516
517static void
518handle_sysret(Event *event) {
519	debug(DEBUG_FUNCTION, "handle_sysret(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum);
520	if (event->proc->state != STATE_IGNORED) {
521		if (opt_T || options.summary) {
522			calc_time_spent(event->proc);
523		}
524		if (options.syscalls)
525			output_syscall_right(event->proc,
526					     sysname(event->proc,
527						     event->e_un.sysnum));
528
529		assert(event->proc->callstack_depth > 0);
530		unsigned d = event->proc->callstack_depth - 1;
531		assert(event->proc->callstack[d].is_syscall);
532		callstack_pop(event->proc);
533	}
534	continue_after_syscall(event->proc, event->e_un.sysnum, 1);
535}
536
537static void
538handle_arch_sysret(Event *event) {
539	debug(DEBUG_FUNCTION, "handle_arch_sysret(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum);
540	if (event->proc->state != STATE_IGNORED) {
541		if (opt_T || options.summary) {
542			calc_time_spent(event->proc);
543		}
544		if (options.syscalls)
545			output_syscall_right(event->proc,
546					     arch_sysname(event->proc,
547							  event->e_un.sysnum));
548		callstack_pop(event->proc);
549	}
550	continue_process(event->proc->pid);
551}
552
553static void
554output_right_tos(struct Process *proc)
555{
556	size_t d = proc->callstack_depth;
557	struct callstack_element *elem = &proc->callstack[d - 1];
558	if (proc->state != STATE_IGNORED)
559		output_right(LT_TOF_FUNCTIONR, proc, elem->c_un.libfunc->name);
560}
561
562static void
563handle_breakpoint(Event *event)
564{
565	int i, j;
566	struct breakpoint *sbp;
567	Process *leader = event->proc->leader;
568	void *brk_addr = event->e_un.brk_addr;
569
570	/* The leader has terminated.  */
571	if (leader == NULL) {
572		continue_process(event->proc->pid);
573		return;
574	}
575
576	debug(DEBUG_FUNCTION, "handle_breakpoint(pid=%d, addr=%p)",
577	      event->proc->pid, brk_addr);
578	debug(2, "event: breakpoint (%p)", brk_addr);
579
580	for (i = event->proc->callstack_depth - 1; i >= 0; i--) {
581		if (brk_addr == event->proc->callstack[i].return_addr) {
582#if defined(__mips__)
583			void *addr = NULL;
584			struct library_symbol *sym= event->proc->callstack[i].c_un.libfunc;
585			struct library_symbol *new_sym;
586			assert(sym);
587			addr = sym2addr(event->proc, sym);
588			sbp = dict_find_entry(leader->breakpoints, addr);
589			if (sbp) {
590				if (addr != sbp->addr) {
591					insert_breakpoint(event->proc, addr, sym);
592				}
593			} else {
594				new_sym=malloc(sizeof(*new_sym) + strlen(sym->name) + 1);
595				memcpy(new_sym,sym,sizeof(*new_sym) + strlen(sym->name) + 1);
596				new_sym->next = leader->list_of_symbols;
597				leader->list_of_symbols = new_sym;
598				insert_breakpoint(event->proc, addr, new_sym);
599			}
600#endif
601			for (j = event->proc->callstack_depth - 1; j > i; j--) {
602				callstack_pop(event->proc);
603			}
604			if (event->proc->state != STATE_IGNORED) {
605				if (opt_T || options.summary) {
606					calc_time_spent(event->proc);
607				}
608			}
609			event->proc->return_addr = brk_addr;
610
611			output_right_tos(event->proc);
612			callstack_pop(event->proc);
613
614			/* Pop also any other entries that seem like
615			 * they are linked to the current one: they
616			 * have the same return address, but were made
617			 * for different symbols.  This should only
618			 * happen for entry point tracing, i.e. for -x
619			 * everywhere, or -x and -e on PPC64.  */
620			while (event->proc->callstack_depth > 0) {
621				struct callstack_element *prev;
622				size_t d = event->proc->callstack_depth;
623				prev = &event->proc->callstack[d - 1];
624
625				if (prev->c_un.libfunc == libsym
626				    || prev->return_addr != brk_addr)
627					break;
628
629				output_right_tos(event->proc);
630				callstack_pop(event->proc);
631			}
632
633			sbp = address2bpstruct(leader, brk_addr);
634			continue_after_breakpoint(event->proc, sbp);
635			return;
636		}
637	}
638
639	if ((sbp = address2bpstruct(leader, brk_addr))) {
640		breakpoint_on_hit(sbp, event->proc);
641
642		if (event->proc->state != STATE_IGNORED
643		    && sbp->libsym != NULL) {
644			event->proc->stack_pointer = get_stack_pointer(event->proc);
645			event->proc->return_addr =
646				get_return_addr(event->proc, event->proc->stack_pointer);
647			callstack_push_symfunc(event->proc, sbp->libsym);
648			output_left(LT_TOF_FUNCTION, event->proc, sbp->libsym);
649		}
650
651		breakpoint_on_continue(sbp, event->proc);
652		return;
653	}
654
655	if (event->proc->state != STATE_IGNORED)
656		output_line(event->proc, "unexpected breakpoint at %p",
657			    brk_addr);
658
659	continue_process(event->proc->pid);
660}
661
662static void
663callstack_push_syscall(Process *proc, int sysnum) {
664	struct callstack_element *elem;
665
666	debug(DEBUG_FUNCTION, "callstack_push_syscall(pid=%d, sysnum=%d)", proc->pid, sysnum);
667	/* FIXME: not good -- should use dynamic allocation. 19990703 mortene. */
668	if (proc->callstack_depth == MAX_CALLDEPTH - 1) {
669		fprintf(stderr, "%s: Error: call nesting too deep!\n", __func__);
670		abort();
671		return;
672	}
673
674	elem = &proc->callstack[proc->callstack_depth];
675	elem->is_syscall = 1;
676	elem->c_un.syscall = sysnum;
677	elem->return_addr = NULL;
678
679	proc->callstack_depth++;
680	if (opt_T || options.summary) {
681		struct timezone tz;
682		gettimeofday(&elem->time_spent, &tz);
683	}
684}
685
686static void
687callstack_push_symfunc(Process *proc, struct library_symbol *sym) {
688	struct callstack_element *elem;
689
690	debug(DEBUG_FUNCTION, "callstack_push_symfunc(pid=%d, symbol=%s)", proc->pid, sym->name);
691	/* FIXME: not good -- should use dynamic allocation. 19990703 mortene. */
692	if (proc->callstack_depth == MAX_CALLDEPTH - 1) {
693		fprintf(stderr, "%s: Error: call nesting too deep!\n", __func__);
694		abort();
695		return;
696	}
697
698	elem = &proc->callstack[proc->callstack_depth++];
699	elem->is_syscall = 0;
700	elem->c_un.libfunc = sym;
701
702	elem->return_addr = proc->return_addr;
703	if (elem->return_addr)
704		insert_breakpoint(proc, elem->return_addr, NULL);
705
706	/* handle functions like atexit() on mips which have no return */
707	if (opt_T || options.summary) {
708		struct timezone tz;
709		gettimeofday(&elem->time_spent, &tz);
710	}
711}
712
713static void
714callstack_pop(Process *proc) {
715	struct callstack_element *elem;
716	assert(proc->callstack_depth > 0);
717
718	debug(DEBUG_FUNCTION, "callstack_pop(pid=%d)", proc->pid);
719	elem = &proc->callstack[proc->callstack_depth - 1];
720	if (!elem->is_syscall && elem->return_addr) {
721		assert(proc->leader != NULL);
722		delete_breakpoint(proc, elem->return_addr);
723	}
724	if (elem->arch_ptr != NULL) {
725		free(elem->arch_ptr);
726		elem->arch_ptr = NULL;
727	}
728	proc->callstack_depth--;
729}
730