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