Tejun Heo fca26f260c ptrace: implement PTRACE_INTERRUPT
Currently, there's no way to trap a running ptracee short of sending a
signal which has various side effects.  This patch implements
PTRACE_INTERRUPT which traps ptracee without any signal or job control
related side effect.

The implementation is almost trivial.  It uses the group stop trap -
SIGTRAP | PTRACE_EVENT_STOP << 8.  A new trap flag
JOBCTL_TRAP_INTERRUPT is added, which is set on PTRACE_INTERRUPT and
cleared when any trap happens.  As INTERRUPT should be useable
regardless of the current state of tracee, task_is_traced() test in
ptrace_check_attach() is skipped for INTERRUPT.

PTRACE_INTERRUPT is available iff tracee is attached with
PTRACE_SEIZE.

Test program follows.

  #define PTRACE_SEIZE		0x4206
  #define PTRACE_INTERRUPT	0x4207

  #define PTRACE_SEIZE_DEVEL	0x80000000

  static const struct timespec ts100ms = { .tv_nsec = 100000000 };
  static const struct timespec ts1s = { .tv_sec = 1 };
  static const struct timespec ts3s = { .tv_sec = 3 };

  int main(int argc, char **argv)
  {
	  pid_t tracee;

	  tracee = fork();
	  if (tracee == 0) {
		  nanosleep(&ts100ms, NULL);
		  while (1) {
			  printf("tracee: alive pid=%d\n", getpid());
			  nanosleep(&ts1s, NULL);
		  }
	  }

	  if (argc > 1)
		  kill(tracee, SIGSTOP);

	  nanosleep(&ts100ms, NULL);

	  ptrace(PTRACE_SEIZE, tracee, NULL,
		 (void *)(unsigned long)PTRACE_SEIZE_DEVEL);
	  if (argc > 1) {
		  waitid(P_PID, tracee, NULL, WSTOPPED);
		  ptrace(PTRACE_CONT, tracee, NULL, NULL);
	  }
	  nanosleep(&ts3s, NULL);

	  printf("tracer: INTERRUPT and DETACH\n");
	  ptrace(PTRACE_INTERRUPT, tracee, NULL, NULL);
	  waitid(P_PID, tracee, NULL, WSTOPPED);
	  ptrace(PTRACE_DETACH, tracee, NULL, NULL);
	  nanosleep(&ts3s, NULL);

	  printf("tracer: exiting\n");
	  kill(tracee, SIGKILL);
	  return 0;
  }

When called without argument, tracee is seized from running state,
interrupted and then detached back to running state.

  # ./test-interrupt
  tracee: alive pid=4546
  tracee: alive pid=4546
  tracee: alive pid=4546
  tracer: INTERRUPT and DETACH
  tracee: alive pid=4546
  tracee: alive pid=4546
  tracee: alive pid=4546
  tracer: exiting

When called with argument, tracee is seized from stopped state,
continued, interrupted and then detached back to stopped state.

  # ./test-interrupt  1
  tracee: alive pid=4548
  tracee: alive pid=4548
  tracee: alive pid=4548
  tracer: INTERRUPT and DETACH
  tracer: exiting

Before PTRACE_INTERRUPT, once the tracee was running, there was no way
to trap tracee and do PTRACE_DETACH without causing side effect.

-v2: Updated to use task_set_jobctl_pending() so that it doesn't end
     up scheduling TRAP_STOP if child is dying which may make the
     child unkillable.  Spotted by Oleg.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Oleg Nesterov <oleg@redhat.com>
2011-06-16 21:41:53 +02:00
..
2011-03-31 11:26:23 -03:00
2011-05-04 14:08:36 -07:00
2011-03-31 11:26:23 -03:00
2011-05-26 19:45:40 +02:00
2011-03-31 11:26:23 -03:00
2011-06-01 11:36:49 +01:00
2011-03-31 11:26:23 -03:00
2011-03-31 11:26:23 -03:00
2011-03-31 11:26:23 -03:00
2011-03-31 11:26:23 -03:00
2011-02-24 19:58:42 +01:00
2011-04-01 02:24:31 -04:00
2010-11-23 20:14:46 +00:00
2011-01-31 14:03:00 -08:00
2011-05-28 17:41:46 +02:00
2011-01-15 20:07:45 -05:00
2011-03-10 08:52:07 +01:00
2011-03-22 17:43:59 -07:00
2011-03-11 14:25:50 +00:00
2011-05-31 13:45:53 +02:00
2011-03-31 11:26:23 -03:00
2010-12-16 17:53:38 +01:00
2011-03-31 11:26:23 -03:00
2011-05-26 17:12:34 -07:00
2011-05-26 17:12:34 -07:00
2011-03-31 11:26:23 -03:00
2011-03-31 11:26:23 -03:00
2011-03-31 11:26:23 -03:00
2011-03-22 17:44:15 -07:00
2011-05-19 15:59:38 -07:00
2011-01-10 08:51:44 -08:00
2010-05-19 22:41:57 -04:00
2011-05-23 10:47:06 -05:00
2011-05-29 13:03:09 +01:00
2011-03-31 11:26:23 -03:00
2011-03-31 11:26:23 -03:00
2011-03-10 11:35:17 +01:00
2011-05-24 10:21:29 +02:00
2011-05-24 10:21:29 +02:00
2009-11-04 09:50:58 -08:00
2011-05-13 14:37:28 -04:00
2011-03-31 11:26:23 -03:00
2011-03-31 11:26:23 -03:00
2011-01-12 20:16:43 -05:00
2011-03-14 19:12:20 -04:00
2011-03-31 11:26:23 -03:00
2011-01-10 08:51:44 -08:00
2011-01-07 17:50:27 +11:00
2011-03-31 11:26:23 -03:00
2011-01-07 17:50:23 +11:00
2010-12-07 20:16:56 +01:00
2011-03-05 10:56:00 +01:00
2011-03-31 11:26:23 -03:00
2011-03-31 11:26:23 -03:00
2011-05-23 13:59:54 +02:00
2011-05-26 12:03:50 -07:00
2011-02-23 00:53:26 +00:00
2011-05-25 20:43:32 +02:00
2011-03-31 11:26:23 -03:00
2011-05-08 16:41:45 -07:00
2010-11-16 10:58:30 -08:00
2011-02-27 16:11:51 -08:00
2011-05-26 17:12:37 -07:00
2011-03-31 11:26:23 -03:00
2010-11-24 11:16:42 -08:00
2011-03-31 11:26:23 -03:00
2010-12-09 20:17:07 -08:00
2011-03-31 11:26:23 -03:00
2011-02-17 11:12:40 -08:00
2011-01-13 17:32:31 -08:00
2011-05-25 08:39:52 -07:00
2011-01-13 17:32:47 -08:00
2011-02-13 16:54:24 -08:00
2011-01-24 14:45:11 +10:30
2011-05-24 22:55:24 +10:00
2011-03-31 11:26:23 -03:00
2011-05-22 08:47:53 -04:00
2005-04-16 15:20:36 -07:00
2011-03-31 11:26:23 -03:00
2011-05-19 20:50:53 -04:00
2011-05-24 14:33:35 +02:00
2011-04-25 18:14:10 -07:00
2010-12-06 11:03:46 -08:00
2011-05-29 11:32:28 -07:00
2011-05-26 17:12:36 -07:00
2011-05-19 16:55:27 +09:30
2011-01-16 13:47:07 -05:00
2006-11-30 04:40:22 +01:00
2011-03-31 11:26:23 -03:00
2008-06-06 11:29:12 -07:00
2011-05-20 11:46:11 -07:00
2011-03-23 15:29:04 -04:00
2011-05-29 20:54:36 +03:00
2011-05-26 17:12:34 -07:00
2011-04-20 17:01:19 +10:00
2011-03-31 11:26:23 -03:00
2011-03-31 11:26:23 -03:00
2005-04-16 15:20:36 -07:00
2011-01-16 13:47:07 -05:00
2011-05-26 17:12:37 -07:00
2011-03-11 15:13:26 -05:00
2011-03-31 11:26:23 -03:00
2011-05-24 12:10:51 +02:00
2011-01-13 08:03:21 -08:00
2011-03-31 11:26:23 -03:00
2011-05-13 16:31:00 -07:00
2011-06-16 21:41:53 +02:00
2011-03-31 11:26:23 -03:00
2010-10-29 04:16:31 -04:00
2010-02-10 17:47:17 -08:00
2011-01-14 02:36:43 +00:00
2011-05-05 23:16:59 -07:00
2011-03-31 11:26:23 -03:00
2010-11-15 13:24:06 -05:00
2011-05-25 08:39:19 -07:00
2010-03-12 15:53:10 -08:00
2010-10-30 12:12:50 +02:00
2011-05-24 15:22:17 +02:00
2011-03-31 11:26:23 -03:00
2011-05-26 13:38:58 +10:00
2011-05-05 11:10:14 -07:00
2011-03-31 11:26:23 -03:00
2011-03-31 11:26:23 -03:00
2011-03-31 11:26:23 -03:00
2011-02-28 18:00:31 -08:00
2011-02-02 15:28:18 +01:00
2010-11-29 08:55:25 +11:00
2010-11-29 08:55:22 +11:00
2011-03-31 11:26:23 -03:00
2010-12-20 09:37:33 +01:00
2005-04-16 15:20:36 -07:00
2011-03-31 11:26:23 -03:00
2011-03-31 11:26:23 -03:00
2011-05-30 11:14:16 +09:30
2011-03-31 11:26:23 -03:00
2011-03-31 11:26:23 -03:00
2011-01-13 08:03:24 -08:00