[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