diff options
author | Petr Machata <pmachata@redhat.com> | 2011-11-02 13:22:46 +0100 |
---|---|---|
committer | Petr Machata <pmachata@redhat.com> | 2011-11-02 13:22:46 +0100 |
commit | 06986d5432c92337dc2fc0bd81fa43640b48d1e2 (patch) | |
tree | c882d49321a44d38f190d766166cda92f69385a3 | |
parent | d5d93c492fd7cec016f09883f1e9c09cf97c6fb5 (diff) | |
download | ltrace-06986d5432c92337dc2fc0bd81fa43640b48d1e2.tar.gz |
More robust fix of signal-before-singlestep problem
- On s390x, when we PTRACE_CONT the process, it will actually continue,
even though we ordered PTRACE_SINGLESTEP before. So always issue
PTRACE_SINGLESTEP when we get signal before singlestep.
- Also, simply queue the signal as usual.
-rw-r--r-- | sysdeps/linux-gnu/trace.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/sysdeps/linux-gnu/trace.c b/sysdeps/linux-gnu/trace.c index 1a82b41..5337cb0 100644 --- a/sysdeps/linux-gnu/trace.c +++ b/sysdeps/linux-gnu/trace.c @@ -556,6 +556,14 @@ all_stops_accountable(struct pid_set * pids) return 1; } +static void +singlestep(Process * proc) +{ + debug(1, "PTRACE_SINGLESTEP"); + if (ptrace(PTRACE_SINGLESTEP, proc->pid, 0, 0)) + perror("PTRACE_SINGLESTEP"); +} + /* This event handler is installed when we are in the process of * stopping the whole thread group to do the pointer re-enablement for * one of the threads. We pump all events to the queue for later @@ -595,24 +603,19 @@ process_stopping_on_event(Event_Handler * super, Event * event) teb->pid); if (sbp->enabled) disable_breakpoint(teb, sbp); - if (ptrace(PTRACE_SINGLESTEP, teb->pid, 0, 0)) - perror("PTRACE_SINGLESTEP"); + singlestep(teb); self->state = state = psh_singlestep; } break; - case psh_singlestep: { + case psh_singlestep: /* In singlestep state, breakpoint signifies that we * have now stepped, and can re-enable the breakpoint. */ if (event != NULL && task == teb) { - /* Let the outer shell handle this event and - * continue the process. The breakpoint - * should arrive afterwards. */ + /* This is not the singlestep that we are waiting for. */ if (event->type == EVENT_SIGNAL) { - debug(DEBUG_PROCESS, - "SIGNAL after SINGLESTEP %d", teb->pid); - event_to_queue = 0; + singlestep(task); break; } @@ -631,7 +634,6 @@ process_stopping_on_event(Event_Handler * super, Event * event) event = NULL; // handled } else break; - } /* fall-through */ |