[PATCH] utrace: utrace_reset() should clear TIF_SINGLESTEP if no more engines

Oleg Nesterov oleg at redhat.com
Sun Sep 26 15:48:39 UTC 2010


On 09/23, Roland McGrath wrote:
>
> > I think we should start with changing utrace_control(DETACH) anyway,
> > then try to improve. I'll ressend the one-liner I already showed.
>
> Ok.

Yes. I think we need a simple fix first, please see another email
I am going to send.

However, I am a bit confused. I was going to send the patch which
changes utrace_control(DETACH) as you suggested, but now I am not
sure. See below.

> The original theory on this was that we'd one day stop overloading
> user signals for debugger-induced traps.
> things like hardware stepping would generate a special new flavor
> of utrace event
>
> But we don't have any of that now, and don't yet know if we will
> really pursue any big improvements at this API level.

Yes! I thought about this too many times.


So. Let's discuss the alternatives for now.

The 1st patch I sent initially:

	--- kstub/kernel/utrace.c~10_utrace_reset_should_clear_ss	2010-09-20 03:55:12.000000000 +0200
	+++ kstub/kernel/utrace.c	2010-09-20 21:33:47.000000000 +0200
	@@ -709,6 +709,7 @@ static bool utrace_reset(struct task_str
			 */
			utrace->resume = UTRACE_RESUME;
			utrace->signal_handler = 0;
	+		user_disable_single_step(task);
		}
	 
		/*

It clears TIF_SINGLESTEP when the last engine detaches.

The 2nd one which changes utrace_control(DETACH),

	@@ -1139,7 +1139,9 @@ int utrace_control(struct task_struct *t
				target->utrace_flags &= ~ENGINE_STOP;
			mark_engine_detached(engine);
			reset = reset || utrace_do_stop(target, utrace);
	-		if (!reset) {
	+		if (reset) {
	+			user_disable_single_step(target);
	+		} else {
				/*
				 * As in utrace_set_events(), this barrier ensures
				 * that our engine->flags changes have hit before we

It doesn't cover the case when the TIF_SINGLESTEP tracee detaches
itself, but a) currently the are no such engines, and b) it looks
more clean.

However, I am starting to think that if you prefer this change we
have a better option. Instead of duplicating UTRACE_RESUME logic,
perhaps the patch below makes more sense?

Please tell me which fix you prefer? Or just commit the fix you
like more.

Oleg.

--- x/kernel/utrace.c
+++ x/kernel/utrace.c
@@ -716,8 +716,15 @@ static bool utrace_reset(struct task_str
 	/*
 	 * If no more engines want it stopped, wake it up.
 	 */
-	if (task_is_traced(task) && !(flags & ENGINE_STOP))
+	if (task_is_traced(task) && !(flags & ENGINE_STOP)) {
+		/*
+		 * It just resumes, so make sure single-step
+		 * is not left set.
+		 */
+		if (utrace->resume == UTRACE_RESUME)
+			user_disable_single_step(task);
 		utrace_wakeup(task, utrace);
+	}
 
 	/*
 	 * In theory spin_lock() doesn't imply rcu_read_lock().
@@ -1157,14 +1164,7 @@ int utrace_control(struct task_struct *t
 		break;
 
 	case UTRACE_RESUME:
-		/*
-		 * This and all other cases imply resuming if stopped.
-		 * There might not be another report before it just
-		 * resumes, so make sure single-step is not left set.
-		 */
 		clear_engine_wants_stop(engine);
-		if (likely(reset))
-			user_disable_single_step(target);
 		break;
 
 	case UTRACE_BLOCKSTEP:




More information about the utrace-devel mailing list