aboutsummaryrefslogtreecommitdiff
path: root/handle_event.c
diff options
context:
space:
mode:
authorPetr Machata <pmachata@redhat.com>2012-04-19 17:01:51 +0200
committerPetr Machata <pmachata@redhat.com>2012-04-19 17:01:51 +0200
commit5ee368270823922ee2a11f0637a355641f6af457 (patch)
treefda14a139cea10189ef8f909aed7d5709ea9e8f8 /handle_event.c
parentf7fee43f72667f453bba5aaeea6b5490ece6792a (diff)
downloadltrace-5ee368270823922ee2a11f0637a355641f6af457.tar.gz
Fix code that assumes that breakpoint is valid after removed
(Which may actually hold sometimes, but generally won't.)
Diffstat (limited to 'handle_event.c')
-rw-r--r--handle_event.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/handle_event.c b/handle_event.c
index 3ca49fc..63c79b8 100644
--- a/handle_event.c
+++ b/handle_event.c
@@ -635,15 +635,27 @@ handle_breakpoint(Event *event)
callstack_pop(event->proc);
}
- sbp = address2bpstruct(leader, brk_addr);
- continue_after_breakpoint(event->proc, sbp);
+ /* Maybe the previous callstack_pop's got rid
+ * of the breakpoint, but if we are in a
+ * recursive call, it's still enabled. In
+ * that case we need to skip it properly. */
+ if ((sbp = address2bpstruct(leader, brk_addr)) != NULL)
+ continue_after_breakpoint(event->proc, sbp);
+ else
+ continue_process(event->proc->pid);
return;
}
}
- if ((sbp = address2bpstruct(leader, brk_addr))) {
+ if ((sbp = address2bpstruct(leader, brk_addr)) != NULL)
breakpoint_on_hit(sbp, event->proc);
+ else if (event->proc->state != STATE_IGNORED)
+ output_line(event->proc,
+ "unexpected breakpoint at %p", brk_addr);
+ /* breakpoint_on_hit may delete its own breakpoint, so we have
+ * to look it up again. */
+ if ((sbp = address2bpstruct(leader, brk_addr)) != NULL) {
if (event->proc->state != STATE_IGNORED
&& sbp->libsym != NULL) {
event->proc->stack_pointer = get_stack_pointer(event->proc);
@@ -657,10 +669,6 @@ handle_breakpoint(Event *event)
return;
}
- if (event->proc->state != STATE_IGNORED)
- output_line(event->proc, "unexpected breakpoint at %p",
- brk_addr);
-
continue_process(event->proc->pid);
}