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