aboutsummaryrefslogtreecommitdiff
path: root/handle_event.c
diff options
context:
space:
mode:
authorPetr Machata <pmachata@redhat.com>2013-10-11 21:17:24 +0200
committerPetr Machata <pmachata@redhat.com>2013-10-23 01:00:02 +0200
commitcf98923cf77f12bef15b3f1af0c0bbd673a8e4f9 (patch)
treedf9699f5c42d560f9fd32d854ea42456eb4bcdaa /handle_event.c
parent23124cc5c33c6b7a547eb1008505f60590f67593 (diff)
downloadltrace-cf98923cf77f12bef15b3f1af0c0bbd673a8e4f9.tar.gz
Introduce breakpoint_get_return_bp
- This should be used for per-breakpoint customization of how return breakpoints are constructed. Hopefully it will be possible to use this to implement the address mangling that the ARM backed currently has to do.
Diffstat (limited to 'handle_event.c')
-rw-r--r--handle_event.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/handle_event.c b/handle_event.c
index ae61ade..e7e9f1e 100644
--- a/handle_event.c
+++ b/handle_event.c
@@ -57,8 +57,7 @@ static void handle_breakpoint(Event *event);
static void handle_new(Event *event);
static void callstack_push_syscall(struct process *proc, int sysnum);
-static void callstack_push_symfunc(struct process *proc,
- struct library_symbol *sym);
+static void callstack_push_symfunc(struct process *proc, struct breakpoint *bp);
/* XXX Stack maintenance should be moved to a dedicated module, or to
* proc.c, and push/pop should be visible outside this module. For
* now, because we need this in proc.c, this is non-static. */
@@ -709,7 +708,7 @@ handle_breakpoint(Event *event)
if (event->proc->state != STATE_IGNORED
&& sbp->libsym != NULL) {
event->proc->stack_pointer = get_stack_pointer(event->proc);
- callstack_push_symfunc(event->proc, sbp->libsym);
+ callstack_push_symfunc(event->proc, sbp);
output_left(LT_TOF_FUNCTION, event->proc, sbp->libsym);
}
@@ -749,11 +748,12 @@ callstack_push_syscall(struct process *proc, int sysnum)
}
static void
-callstack_push_symfunc(struct process *proc, struct library_symbol *sym)
+callstack_push_symfunc(struct process *proc, struct breakpoint *bp)
{
struct callstack_element *elem;
- debug(DEBUG_FUNCTION, "callstack_push_symfunc(pid=%d, symbol=%s)", proc->pid, sym->name);
+ debug(DEBUG_FUNCTION, "callstack_push_symfunc(pid=%d, symbol=%s)",
+ proc->pid, bp->libsym->name);
/* FIXME: not good -- should use dynamic allocation. 19990703 mortene. */
if (proc->callstack_depth == MAX_CALLDEPTH - 1) {
fprintf(stderr, "%s: Error: call nesting too deep!\n", __func__);
@@ -764,12 +764,18 @@ callstack_push_symfunc(struct process *proc, struct library_symbol *sym)
elem = &proc->callstack[proc->callstack_depth++];
*elem = (struct callstack_element){};
elem->is_syscall = 0;
- elem->c_un.libfunc = sym;
+ elem->c_un.libfunc = bp->libsym;
- arch_addr_t return_addr = get_return_addr(proc, proc->stack_pointer);
struct breakpoint *rbp = NULL;
- if (return_addr != 0)
- rbp = insert_breakpoint_at(proc, return_addr, NULL);
+ if (breakpoint_get_return_bp(&rbp, bp, proc) == 0) {
+ struct breakpoint *ext_rbp = insert_breakpoint(proc, rbp);
+ if (ext_rbp != rbp) {
+ breakpoint_destroy(rbp);
+ free(rbp);
+ rbp = ext_rbp;
+ }
+ }
+
elem->return_addr = rbp != NULL ? rbp->addr : 0;
if (opt_T || options.summary) {