diff options
author | Petr Machata <pmachata@redhat.com> | 2012-03-28 02:07:19 +0200 |
---|---|---|
committer | Petr Machata <pmachata@redhat.com> | 2012-04-19 01:34:03 +0200 |
commit | 36f40e7d46838ec41ea03a2b9b748536d8fd57e2 (patch) | |
tree | 028b832fac447b4350e13c8f944f4eed6333ad2d /sysdeps/linux-gnu/trace.c | |
parent | ef7fa37f2d0b949b5afb1f326187e4f023d86c25 (diff) | |
download | ltrace-36f40e7d46838ec41ea03a2b9b748536d8fd57e2.tar.gz |
Further generalize the process stopping handler
Diffstat (limited to 'sysdeps/linux-gnu/trace.c')
-rw-r--r-- | sysdeps/linux-gnu/trace.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/sysdeps/linux-gnu/trace.c b/sysdeps/linux-gnu/trace.c index dfa5126..c4754ea 100644 --- a/sysdeps/linux-gnu/trace.c +++ b/sysdeps/linux-gnu/trace.c @@ -695,9 +695,10 @@ process_stopping_on_event(struct event_handler *super, Event *event) * have now stepped, and can re-enable the breakpoint. */ if (event != NULL && task == teb) { - /* This is not the singlestep that we are - * waiting for. */ - if (event->type == EVENT_SIGNAL) { + /* If we got SIGNAL instead of BREAKPOINT, + * then this is not singlestep at all. */ + if (event->type == EVENT_SIGNAL + || (self->keep_stepping_p)(self)) { if (singlestep(self) < 0) { singlestep_error(self, &event); goto psh_sinking; @@ -755,19 +756,33 @@ process_stopping_destroy(struct event_handler *super) free(self->pids.tasks); } +static enum callback_status +no(struct process_stopping_handler *self) +{ + return 0; +} + int process_install_stopping_handler(struct Process *proc, struct breakpoint *sbp, - void (*cb)(struct process_stopping_handler *)) + void (*as)(struct process_stopping_handler *), + enum callback_status (*ks) + (struct process_stopping_handler *)) { struct process_stopping_handler *handler = calloc(sizeof(*handler), 1); if (handler == NULL) return -1; + if (as == NULL) + as = &disable_and_singlestep; + if (ks == NULL) + ks = &no; + handler->super.on_event = process_stopping_on_event; handler->super.destroy = process_stopping_destroy; handler->task_enabling_breakpoint = proc; handler->breakpoint_being_enabled = sbp; - handler->on_all_stopped = cb; + handler->on_all_stopped = as; + handler->keep_stepping_p = ks; install_event_handler(proc->leader, &handler->super); @@ -803,8 +818,8 @@ continue_after_breakpoint(Process *proc, struct breakpoint *sbp) /* we don't want to singlestep here */ continue_process(proc->pid); #else - if (process_install_stopping_handler - (proc, sbp, &disable_and_singlestep) < 0) { + if (process_install_stopping_handler(proc, sbp, + NULL, NULL) < 0) { perror("process_stopping_handler_create"); /* Carry on not bothering to re-enable. */ continue_process(proc->pid); |