[HACK] utrace: "fix" utrace_resume()->finish_resume_report() logic
Oleg Nesterov
oleg at redhat.com
Mon Nov 16 16:52:15 UTC 2009
In short, it is just wrong to call finish_resume_report() in utrace_resume()
without reporting loop, because utrace never clears TIF_NOTIFY_RESUME. It is
very possible we enter utrace_resume() with utrace->resume == UTRACE_RESUME,
in this case finish_resume_report() does user_disable_single_step(). And if
TIF_SINGLESTEP was previously set by utrace_get_signal() which noticed
->resume < UTRACE_RESUME we lost: engine can't re-assert the stepping.
IOW. Just one example. The tracee reports the signal and sleeps in
utrace_get_signal()->finish_resume_report().
Suppose that the tracee has TIF_NOTIFY_RESUME bit set. A lot of reasons
why this can happen.
The tracer wakes up the tracee via utrace_control(UTRACE_SINGLESTEP).
The tracee resumes, calls utrace_get_signal_again(), notices
utrace->resume < UTRACE_RESUME, resets utrace->resume, and does
finish_resume_report()->enable_step() correctly.
But, since TIF_NOTIFY_RESUME is set, the tracee will call utrace_resume()
before return to user-mode, and the next finish_resume_report() from
utrace_resume() clears TIF_SINGLESTEP.
Of course, this is just the temporary hack, to do the testing right now.
I still do not understand the new code in details, need to read it
carefully but didn't have the time yet :/
---
kernel/utrace.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- UTRACE-PTRACE/kernel/utrace.c~UTRACE_HACK_RESUME 2009-11-16 17:02:11.000000000 +0100
+++ UTRACE-PTRACE/kernel/utrace.c 2009-11-16 17:28:10.000000000 +0100
@@ -1871,7 +1871,7 @@ void utrace_resume(struct task_struct *t
*/
report.action = start_report(utrace);
- if (report.action == UTRACE_REPORT &&
+ if (1 && //report.action == UTRACE_REPORT &&
likely(task->utrace_flags & UTRACE_EVENT(QUIESCE))) {
/*
* Do a simple reporting pass, with no specific
More information about the utrace-devel
mailing list