]> granicus.if.org Git - strace/commitdiff
2003-01-08 Roland McGrath <roland@redhat.com>
authorRoland McGrath <roland@redhat.com>
Thu, 9 Jan 2003 06:53:27 +0000 (06:53 +0000)
committerRoland McGrath <roland@redhat.com>
Thu, 9 Jan 2003 06:53:27 +0000 (06:53 +0000)
Support for new Linux 2.5 thread features.
* defs.h [LINUX]: Define __NR_exit_group if not defined.
(struct tcb): New members nclone_threads, nclone_detached,
and nclone_waiting.
(TCB_CLONE_DETACHED, TCB_CLONE_THREAD, TCB_GROUP_EXITING): New macros.
(waiting_parent): Macro removed.
(pid2tcb): Declare it.
* process.c (internal_clone) [TCB_CLONE_THREAD]: Reparent the new
child to our parent if we are a CLONE_THREAD child ourselves.
Maintain TCB_CLONE_THREAD and TCB_CLONE_DETACHED flags and counts.
(internal_wait) [TCB_CLONE_THREAD]: Factor out detached children when
determining if we have any.  If TCB_CLONE_THREAD is set, check
parent's children instead of our own, and bump nclone_waiting count.
(internal_exit) [__NR_exit_group]: Set the TCB_GROUP_EXITING flag if
the syscall was exit_group.
* syscall.c (internal_syscall): Use internal_exit for exit_group.
* strace.c (pid2tcb): No longer static.
(alloctcb) [TCB_CLONE_THREAD]: Initialize new fields.
(droptcb) [TCB_CLONE_THREAD]: Maintain new fields.
If we have thread children, set TCB_EXITING and don't clear the TCB.
(resume) [TCB_CLONE_THREAD]: Decrement parent's nclone_waiting.
(detach) [TCB_CLONE_THREAD]: When calling resume, check all thread
children of our parent that might be waiting for us too.
[TCB_GROUP_EXITING] (handle_group_exit): New function.
(trace) [TCB_GROUP_EXITING]: Use that in place of detach or droptcb.

defs.h
syscall.c

diff --git a/defs.h b/defs.h
index fecafee172a1f8e7d8fff95f6c9488f14508dbbb..11d0877d41bf212af3b030722e5a46987464e94a 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -261,6 +261,11 @@ struct tcb {
        struct tcb *parent;     /* Parent of this process */
        int nchildren;          /* # of traced children */
        int waitpid;            /* pid(s) this process is waiting for */
+#ifdef LINUX
+       int nclone_threads;     /* # of nchildren with CLONE_THREAD */
+       int nclone_detached;    /* # of nchildren with CLONE_DETACHED */
+       int nclone_waiting;     /* clone threads in wait4 (TCB_SUSPENDED) */
+#endif
                                /* (1st arg of wait4()) */
        long baddr;             /* `Breakpoint' address */
        long inst[2];           /* Instructions on above */
@@ -297,6 +302,26 @@ struct tcb {
 # if defined(ALPHA) || defined(SPARC) || defined(POWERPC) || defined(IA64) || defined(HPPA) || defined(SH)
 #  define TCB_WAITEXECVE 02000 /* ignore SIGTRAP after exceve */
 # endif
+# define TCB_CLONE_DETACHED 04000 /* CLONE_DETACHED set in creating syscall */
+# define TCB_CLONE_THREAD  010000 /* CLONE_THREAD set in creating syscall */
+# define TCB_GROUP_EXITING 020000 /* TCB_EXITING was exit_group, not _exit */
+# include <sys/syscall.h>
+# ifndef __NR_exit_group
+# /* Hack: Most headers around are too old to have __NR_exit_group.  */
+#  ifdef ALPHA
+#   define __NR_exit_group 405
+#  elif defined I386
+#   define __NR_exit_group 252
+#  elif defined IA64
+#   define __NR_exit_group 1236
+#  elif defined POWERPC
+#   define __NR_exit_group 234
+#  elif defined S390 || defined S390X
+#   define __NR_exit_group 248
+#  elif defined SPARC
+#   define __NR_exit_group 188
+#  endif /* ALPHA et al */
+# endif        /* !__NR_exit_group */
 #endif /* LINUX */
 
 /* qualifier flags */
@@ -314,10 +339,6 @@ struct tcb {
 #define syserror(tcp)  ((tcp)->u_error != 0)
 #define verbose(tcp)   (qual_flags[(tcp)->scno] & QUAL_VERBOSE)
 #define abbrev(tcp)    (qual_flags[(tcp)->scno] & QUAL_ABBREV)
-#define waiting_parent(tcp) \
-               (tcp->parent && \
-               (tcp->parent->flags & TCB_SUSPENDED) && \
-               (tcp->parent->waitpid <= 0 || tcp->parent->waitpid == tcp->pid))
 
 struct xlat {
        int val;
@@ -371,6 +392,7 @@ extern struct tcb *tcp_last;
 extern int set_personality P((int personality));
 extern char *xlookup P((struct xlat *, int));
 extern struct tcb *alloctcb P((int));
+extern struct tcb *pid2tcb P((int));
 extern void droptcb P((struct tcb *));
 
 extern void set_sortby P((char *));
index 204b8ace7037030b5f5ac23935c37638a1e35bb9..578db441c62c8f4b023f56dfed094c2d068734db 100644 (file)
--- a/syscall.c
+++ b/syscall.c
@@ -669,6 +669,9 @@ struct tcb *tcp;
 #endif
 #ifdef SYS32_exit
        case SYS32_exit:
+#endif
+#ifdef __NR_exit_group
+       case __NR_exit_group:
 #endif
                internal_exit(tcp);
                break;