[patch] Multithreaded process left Stopped (T) on CTRL-C of strace

Jan Kratochvil jan.kratochvil at redhat.com
Wed May 23 16:25:12 UTC 2007


Hi,

in some cases if you hit CTRL-C to strace attached to a multithreaded
application the application gets Stopped (T, by SIGSTOP) and needs to be sent
`kill -CONT'.  Shell prints:
[1]+  Stopped                 appname args

The problem occurs if one of the tasks (the leader) gets to the zombie state
(TCB_EXITING) and current strace tries to detach it twice.

The attached testcase to reliably pass needs also the next patch from the mail:
	[patch] Hangs and/or multithreaded process left Stopped (T) on CTRL-C of strace


Regards,
Jan

Problem tracked at:
	https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=240961
-------------- next part --------------
2007-05-23  Jan Kratochvil  <jan.kratochvil at redhat.com>

	* strace.c (detach): New prototype.
	[LINUX] (detach): Call droptcb() instead of the corrupted detach() call.
	(handle_group_exit): Likewise.

--- strace-4.5.15-orig/strace.c	2006-12-13 22:55:39.000000000 +0100
+++ strace-4.5.15/strace.c	2007-05-23 16:09:24.000000000 +0200
@@ -83,6 +83,7 @@ unsigned int nprocs, tcbtabsize;
 char *progname;
 extern char **environ;
 
+static int detach P((struct tcb *tcp, int sig));
 static int trace P((void));
 static void cleanup P((void));
 static void interrupt P((int sig));
@@ -1460,8 +1461,12 @@ int sig;
 	droptcb(tcp);
 
 #ifdef LINUX
-	if (zombie != NULL)
-		error = detach(zombie) || error;
+	if (zombie != NULL) {
+		/* Never call DETACH again as both unattached and
+		   attached-unstopped processes give ESRCH and we would SIGSTOP
+		   the already unattached process.  */
+		droptcb(zombie);
+	}
 #endif
 
 	return error;
@@ -2035,7 +2040,7 @@ handle_group_exit(struct tcb *tcp, int s
 			fprintf(stderr,
 				"PANIC: handle_group_exit: %d leader %d\n",
 				tcp->pid, leader ? leader->pid : -1);
-		detach(tcp);	/* Already died.  */
+		droptcb(tcp);	/* Already died.  */
 	}
 	else {
 		/* Mark that we are taking the process down.  */
-------------- next part --------------
#include <pthread.h>
#include <signal.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

void *start (void *arg)
{
  for (;;);
}

int main (void)
{
  pthread_t thread_id;
  int i;

  printf("%d\n", (int) getpid ());

  i = pthread_create (&thread_id, NULL, start, NULL);
  assert (i == 0);
  i = pthread_join(thread_id, NULL);
  assert (i == 0);

  return EXIT_SUCCESS;
}


More information about the Strace-devel mailing list