Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 263751 Details for
Bug 159663
kill (SIGSTOP) does not stop all child threads
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
Comment 1 attachment fixed up.
bz159663.c (text/plain), 4.02 KB, created by
Jan Kratochvil
on 2007-11-19 18:09:48 UTC
(
hide
)
Description:
Comment 1 attachment fixed up.
Filename:
MIME Type:
Creator:
Jan Kratochvil
Created:
2007-11-19 18:09:48 UTC
Size:
4.02 KB
patch
obsolete
>#include <sys/types.h> >#include <unistd.h> >#include <pthread.h> >#include <stdlib.h> >#include <sys/ptrace.h> >#include <dirent.h> >#include <stdio.h> >#include <signal.h> >#include <errno.h> >#include <sys/wait.h> >#include <sys/poll.h> >#include <assert.h> >#include <string.h> > >#include <asm/unistd.h> >#include <unistd.h> >#define tkill(tid, sig) syscall (__NR_tkill, (tid), (sig)) > >struct lwp_stop { > int lwpid; > int num_stops; >}; > >struct lwp_stop lwp[3]; > >static >void *infLoopThreadFunc (void *args) >{ > for (;;) > ; > return NULL; >} > >static >int infThreadLoop (int n) >{ > int i = 0; > pid_t pid = fork (); > if (pid == 0) { > // want child to create n threads performing an infinite loop > pthread_t p[1000]; // up to 1000 threads > for (i = 0; i < n; ++i) { > pthread_create (&p[i], NULL, &infLoopThreadFunc, NULL); > } > > for (i = 0; i < n; ++i) > pthread_join (p[i], NULL); > > exit (0); > } > sleep (1); > return (int)pid; >} > >static void >wait_stop (pid_t pid, int do_continue) >{ > { > pid_t pid_got; > int status; > int i; > long l; > errno = 0; > > // Keep fetching the wait status until there are none left. > /* WNOHANG is racy, never use it. */ > pid_got = waitpid (pid, &status, __WALL); > assert (pid_got == pid); > assert (WIFSTOPPED (status)); > { > printf ("stop event %d on <%d>\n", WSTOPSIG (status), (int) pid); > /* There may have been already enqueued signal before PTRACE_ATTACH or > our other signal sent. Redeliver it and read the next signal in the > queue. */ > if (WSTOPSIG (status) != SIGSTOP) { > l = ptrace (PTRACE_CONT, pid, NULL, (void *) (long) WSTOPSIG (status)); > assert (l == 0); > /* Try again. */ > wait_stop (pid, do_continue); > return; > } > for (i = 0; i < 3; ++i) > if (lwp[i].lwpid == pid) > break; > assert (i < 3); > if (lwp[i].num_stops++ == 0) { > printf ("continuing first stop\n"); > l = ptrace (PTRACE_CONT, pid, NULL, 0); > assert (l == 0); > } > } > } >} > >int main () >{ > char buf [40]; > DIR *dir; > struct dirent *d; > int lwpid; > int i; > int pid = infThreadLoop (2); > long l; > > /* Wait until all the child threads get spawned. It is racy here, we should > check the number of threads in READDIR below. */ > sleep (1); > > lwp[0].lwpid = pid; > > /* Attach to new pid and the two threads */ > printf ("Attaching %d\n", pid); > l = ptrace (PTRACE_ATTACH, pid, 0, 0); > assert (l == 0); > > wait_stop (pid, 1); > > sprintf (buf, "/proc/%d/task/", pid); > > dir = opendir (buf); > > /* Skip over . and .. */ > d = readdir (dir); > assert (strcmp (d->d_name, ".") == 0); > d = readdir (dir); > assert (strcmp (d->d_name, "..") == 0); > > for (i = 0; i < 3; ++i) { > d = readdir (dir); > lwpid = atoi (d->d_name); > printf ("lwpid is %d\n", lwpid); > if (lwpid != pid) { > if (lwp[1].lwpid == 0) > lwp[1].lwpid = lwpid; > else if (lwp[2].lwpid == 0) > lwp[2].lwpid = lwpid; > else > assert (0); > printf ("Attaching %d\n", lwpid); > errno = 0; > ptrace (PTRACE_ATTACH, lwpid, 0, 0); > if (errno != 0) > perror ("attach lwpid"); > wait_stop (lwpid, 1); > } > } > > printf ("About to kill main thread\n"); > > /* Now try manually stopping threads. */ > /* kill (pid, SIGSTOP) here would: > * Try to deliver SIGSTOP to an arbitrary task of those three. > * Just get into `State: T (tracing stop)' and WAITPID back with `WSTOPSIG > (status) == SIGSTOP' for that arbitrarily chosen task. > Process under ptrace(2) no longer stops completely by a single SIGSTOP, > under ptrace(2) SIGSTOP applies only to a single task of the process > group. */ > > i = tkill (pid, SIGSTOP); > assert (i == 0); > wait_stop (pid, 0); > > i = tkill (lwp[1].lwpid, SIGSTOP); > assert (i == 0); > wait_stop (lwp[1].lwpid, 0); > > i = tkill (lwp[2].lwpid, SIGSTOP); > assert (i == 0); > wait_stop (lwp[2].lwpid, 0); > > printf ("Manually check to see what threads are stopped.\n"); > > pause (); > > closedir (dir); > > return EXIT_SUCCESS; >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 159663
:
115173
| 263751