Home | History | Annotate | Download | only in base
      1 /* Copyright (c) 2005-2007, Google Inc.
      2  * All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  *
     30  * ---
     31  * Author: Markus Gutschke
     32  */
     33 
     34 #include "base/linuxthreads.h"
     35 
     36 #ifdef THREADS
     37 #ifdef __cplusplus
     38 extern "C" {
     39 #endif
     40 
     41 #include <sched.h>
     42 #include <signal.h>
     43 #include <stdlib.h>
     44 #include <string.h>
     45 #include <fcntl.h>
     46 #include <sys/socket.h>
     47 #include <sys/wait.h>
     48 
     49 #include "base/linux_syscall_support.h"
     50 #include "base/thread_lister.h"
     51 
     52 #ifndef CLONE_UNTRACED
     53 #define CLONE_UNTRACED 0x00800000
     54 #endif
     55 
     56 
     57 /* Synchronous signals that should not be blocked while in the lister thread.
     58  */
     59 static const int sync_signals[]  = { SIGABRT, SIGILL, SIGFPE, SIGSEGV, SIGBUS,
     60                                      SIGXCPU, SIGXFSZ };
     61 
     62 /* itoa() is not a standard function, and we cannot safely call printf()
     63  * after suspending threads. So, we just implement our own copy. A
     64  * recursive approach is the easiest here.
     65  */
     66 static char *local_itoa(char *buf, int i) {
     67   if (i < 0) {
     68     *buf++ = '-';
     69     return local_itoa(buf, -i);
     70   } else {
     71     if (i >= 10)
     72       buf = local_itoa(buf, i/10);
     73     *buf++ = (i%10) + '0';
     74     *buf   = '\000';
     75     return buf;
     76   }
     77 }
     78 
     79 
     80 /* Wrapper around clone() that runs "fn" on the same stack as the
     81  * caller! Unlike fork(), the cloned thread shares the same address space.
     82  * The caller must be careful to use only minimal amounts of stack until
     83  * the cloned thread has returned.
     84  * There is a good chance that the cloned thread and the caller will share
     85  * the same copy of errno!
     86  */
     87 #ifdef __GNUC__
     88 #if __GNUC__ == 3 && __GNUC_MINOR__ >= 1 || __GNUC__ > 3
     89 /* Try to force this function into a separate stack frame, and make sure
     90  * that arguments are passed on the stack.
     91  */
     92 static int local_clone (int (*fn)(void *), void *arg, ...)
     93   __attribute__ ((noinline));
     94 #endif
     95 #endif
     96 
     97 static int local_clone (int (*fn)(void *), void *arg, ...) {
     98   /* Leave 4kB of gap between the callers stack and the new clone. This
     99    * should be more than sufficient for the caller to call waitpid() until
    100    * the cloned thread terminates.
    101    *
    102    * It is important that we set the CLONE_UNTRACED flag, because newer
    103    * versions of "gdb" otherwise attempt to attach to our thread, and will
    104    * attempt to reap its status codes. This subsequently results in the
    105    * caller hanging indefinitely in waitpid(), waiting for a change in
    106    * status that will never happen. By setting the CLONE_UNTRACED flag, we
    107    * prevent "gdb" from stealing events, but we still expect the thread
    108    * lister to fail, because it cannot PTRACE_ATTACH to the process that
    109    * is being debugged. This is OK and the error code will be reported
    110    * correctly.
    111    */
    112   return sys_clone(fn, (char *)&arg - 4096,
    113                    CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_UNTRACED, arg, 0, 0, 0);
    114 }
    115 
    116 
    117 /* Local substitute for the atoi() function, which is not necessarily safe
    118  * to call once threads are suspended (depending on whether libc looks up
    119  * locale information,  when executing atoi()).
    120  */
    121 static int local_atoi(const char *s) {
    122   int n   = 0;
    123   int neg = *s == '-';
    124   if (neg)
    125     s++;
    126   while (*s >= '0' && *s <= '9')
    127     n = 10*n + (*s++ - '0');
    128   return neg ? -n : n;
    129 }
    130 
    131 
    132 /* Re-runs fn until it doesn't cause EINTR
    133  */
    134 #define NO_INTR(fn)   do {} while ((fn) < 0 && errno == EINTR)
    135 
    136 
    137 /* Wrap a class around system calls, in order to give us access to
    138  * a private copy of errno. This only works in C++, but it has the
    139  * advantage of not needing nested functions, which are a non-standard
    140  * language extension.
    141  */
    142 #ifdef __cplusplus
    143 namespace {
    144   class SysCalls {
    145    public:
    146     #define SYS_CPLUSPLUS
    147     #define SYS_ERRNO     my_errno
    148     #define SYS_INLINE    inline
    149     #define SYS_PREFIX    -1
    150     #undef  SYS_LINUX_SYSCALL_SUPPORT_H
    151     #include "linux_syscall_support.h"
    152     SysCalls() : my_errno(0) { }
    153     int my_errno;
    154   };
    155 }
    156 #define ERRNO sys.my_errno
    157 #else
    158 #define ERRNO my_errno
    159 #endif
    160 
    161 
    162 /* Wrapper for open() which is guaranteed to never return EINTR.
    163  */
    164 static int c_open(const char *fname, int flags, int mode) {
    165   ssize_t rc;
    166   NO_INTR(rc = sys_open(fname, flags, mode));
    167   return rc;
    168 }
    169 
    170 
    171 /* abort() is not safely reentrant, and changes it's behavior each time
    172  * it is called. This means, if the main application ever called abort()
    173  * we cannot safely call it again. This would happen if we were called
    174  * from a SIGABRT signal handler in the main application. So, document
    175  * that calling SIGABRT from the thread lister makes it not signal safe
    176  * (and vice-versa).
    177  * Also, since we share address space with the main application, we
    178  * cannot call abort() from the callback and expect the main application
    179  * to behave correctly afterwards. In fact, the only thing we can do, is
    180  * to terminate the main application with extreme prejudice (aka
    181  * PTRACE_KILL).
    182  * We set up our own SIGABRT handler to do this.
    183  * In order to find the main application from the signal handler, we
    184  * need to store information about it in global variables. This is
    185  * safe, because the main application should be suspended at this
    186  * time. If the callback ever called ResumeAllProcessThreads(), then
    187  * we are running a higher risk, though. So, try to avoid calling
    188  * abort() after calling ResumeAllProcessThreads.
    189  */
    190 static volatile int *sig_pids, sig_num_threads, sig_proc, sig_marker;
    191 
    192 
    193 /* Signal handler to help us recover from dying while we are attached to
    194  * other threads.
    195  */
    196 static void SignalHandler(int signum, siginfo_t *si, void *data) {
    197   if (sig_pids != NULL) {
    198     if (signum == SIGABRT) {
    199       while (sig_num_threads-- > 0) {
    200         /* Not sure if sched_yield is really necessary here, but it does not */
    201         /* hurt, and it might be necessary for the same reasons that we have */
    202         /* to do so in sys_ptrace_detach().                                  */
    203         sys_sched_yield();
    204         sys_ptrace(PTRACE_KILL, sig_pids[sig_num_threads], 0, 0);
    205       }
    206     } else if (sig_num_threads > 0) {
    207       ResumeAllProcessThreads(sig_num_threads, (int *)sig_pids);
    208     }
    209   }
    210   sig_pids = NULL;
    211   if (sig_marker >= 0)
    212     NO_INTR(sys_close(sig_marker));
    213   sig_marker = -1;
    214   if (sig_proc >= 0)
    215     NO_INTR(sys_close(sig_proc));
    216   sig_proc = -1;
    217 
    218   sys__exit(signum == SIGABRT ? 1 : 2);
    219 }
    220 
    221 
    222 /* Try to dirty the stack, and hope that the compiler is not smart enough
    223  * to optimize this function away. Or worse, the compiler could inline the
    224  * function and permanently allocate the data on the stack.
    225  */
    226 static void DirtyStack(size_t amount) {
    227   char buf[amount];
    228   memset(buf, 0, amount);
    229   sys_read(-1, buf, amount);
    230 }
    231 
    232 
    233 /* Data structure for passing arguments to the lister thread.
    234  */
    235 #define ALT_STACKSIZE (MINSIGSTKSZ + 4096)
    236 
    237 struct ListerParams {
    238   int         result, err;
    239   char        *altstack_mem;
    240   ListAllProcessThreadsCallBack callback;
    241   void        *parameter;
    242   va_list     ap;
    243 };
    244 
    245 
    246 static void ListerThread(struct ListerParams *args) {
    247   int                found_parent = 0;
    248   pid_t              clone_pid  = sys_gettid(), ppid = sys_getppid();
    249   char               proc_self_task[80], marker_name[48], *marker_path;
    250   const char         *proc_paths[3];
    251   const char *const  *proc_path = proc_paths;
    252   int                proc = -1, marker = -1, num_threads = 0;
    253   int                max_threads = 0, sig;
    254   struct kernel_stat marker_sb, proc_sb;
    255   stack_t            altstack;
    256 
    257   /* Create "marker" that we can use to detect threads sharing the same
    258    * address space and the same file handles. By setting the FD_CLOEXEC flag
    259    * we minimize the risk of misidentifying child processes as threads;
    260    * and since there is still a race condition,  we will filter those out
    261    * later, anyway.
    262    */
    263   if ((marker = sys_socket(PF_LOCAL, SOCK_DGRAM, 0)) < 0 ||
    264       sys_fcntl(marker, F_SETFD, FD_CLOEXEC) < 0) {
    265   failure:
    266     args->result = -1;
    267     args->err    = errno;
    268     if (marker >= 0)
    269       NO_INTR(sys_close(marker));
    270     sig_marker = marker = -1;
    271     if (proc >= 0)
    272       NO_INTR(sys_close(proc));
    273     sig_proc = proc = -1;
    274     sys__exit(1);
    275   }
    276 
    277   /* Compute search paths for finding thread directories in /proc            */
    278   local_itoa(strrchr(strcpy(proc_self_task, "/proc/"), '\000'), ppid);
    279   strcpy(marker_name, proc_self_task);
    280   marker_path = marker_name + strlen(marker_name);
    281   strcat(proc_self_task, "/task/");
    282   proc_paths[0] = proc_self_task; /* /proc/$$/task/                          */
    283   proc_paths[1] = "/proc/";       /* /proc/                                  */
    284   proc_paths[2] = NULL;
    285 
    286   /* Compute path for marker socket in /proc                                 */
    287   local_itoa(strcpy(marker_path, "/fd/") + 4, marker);
    288   if (sys_stat(marker_name, &marker_sb) < 0) {
    289     goto failure;
    290   }
    291 
    292   /* Catch signals on an alternate pre-allocated stack. This way, we can
    293    * safely execute the signal handler even if we ran out of memory.
    294    */
    295   memset(&altstack, 0, sizeof(altstack));
    296   altstack.ss_sp    = args->altstack_mem;
    297   altstack.ss_flags = 0;
    298   altstack.ss_size  = ALT_STACKSIZE;
    299   sys_sigaltstack(&altstack, (const stack_t *)NULL);
    300 
    301   /* Some kernels forget to wake up traced processes, when the
    302    * tracer dies.  So, intercept synchronous signals and make sure
    303    * that we wake up our tracees before dying. It is the caller's
    304    * responsibility to ensure that asynchronous signals do not
    305    * interfere with this function.
    306    */
    307   sig_marker = marker;
    308   sig_proc   = -1;
    309   for (sig = 0; sig < sizeof(sync_signals)/sizeof(*sync_signals); sig++) {
    310     struct kernel_sigaction sa;
    311     memset(&sa, 0, sizeof(sa));
    312     sa.sa_sigaction_ = SignalHandler;
    313     sys_sigfillset(&sa.sa_mask);
    314     sa.sa_flags      = SA_ONSTACK|SA_SIGINFO|SA_RESETHAND;
    315     sys_sigaction(sync_signals[sig], &sa, (struct kernel_sigaction *)NULL);
    316   }
    317 
    318   /* Read process directories in /proc/...                                   */
    319   for (;;) {
    320     /* Some kernels know about threads, and hide them in "/proc"
    321      * (although they are still there, if you know the process
    322      * id). Threads are moved into a separate "task" directory. We
    323      * check there first, and then fall back on the older naming
    324      * convention if necessary.
    325      */
    326     if ((sig_proc = proc = c_open(*proc_path, O_RDONLY|O_DIRECTORY, 0)) < 0) {
    327       if (*++proc_path != NULL)
    328         continue;
    329       goto failure;
    330     }
    331     if (sys_fstat(proc, &proc_sb) < 0)
    332       goto failure;
    333 
    334     /* Since we are suspending threads, we cannot call any libc
    335      * functions that might acquire locks. Most notably, we cannot
    336      * call malloc(). So, we have to allocate memory on the stack,
    337      * instead. Since we do not know how much memory we need, we
    338      * make a best guess. And if we guessed incorrectly we retry on
    339      * a second iteration (by jumping to "detach_threads").
    340      *
    341      * Unless the number of threads is increasing very rapidly, we
    342      * should never need to do so, though, as our guestimate is very
    343      * conservative.
    344      */
    345     if (max_threads < proc_sb.st_nlink + 100)
    346       max_threads = proc_sb.st_nlink + 100;
    347 
    348     /* scope */ {
    349       pid_t pids[max_threads];
    350       int   added_entries = 0;
    351       sig_num_threads     = num_threads;
    352       sig_pids            = pids;
    353       for (;;) {
    354         struct kernel_dirent *entry;
    355         char buf[4096];
    356         ssize_t nbytes = sys_getdents(proc, (struct kernel_dirent *)buf,
    357                                       sizeof(buf));
    358         if (nbytes < 0)
    359           goto failure;
    360         else if (nbytes == 0) {
    361           if (added_entries) {
    362             /* Need to keep iterating over "/proc" in multiple
    363              * passes until we no longer find any more threads. This
    364              * algorithm eventually completes, when all threads have
    365              * been suspended.
    366              */
    367             added_entries = 0;
    368             sys_lseek(proc, 0, SEEK_SET);
    369             continue;
    370           }
    371           break;
    372         }
    373         for (entry = (struct kernel_dirent *)buf;
    374              entry < (struct kernel_dirent *)&buf[nbytes];
    375              entry = (struct kernel_dirent *)((char *)entry+entry->d_reclen)) {
    376           if (entry->d_ino != 0) {
    377             const char *ptr = entry->d_name;
    378             pid_t pid;
    379 
    380             /* Some kernels hide threads by preceding the pid with a '.'     */
    381             if (*ptr == '.')
    382               ptr++;
    383 
    384             /* If the directory is not numeric, it cannot be a
    385              * process/thread
    386              */
    387             if (*ptr < '0' || *ptr > '9')
    388               continue;
    389             pid = local_atoi(ptr);
    390 
    391             /* Attach (and suspend) all threads                              */
    392             if (pid && pid != clone_pid) {
    393               struct kernel_stat tmp_sb;
    394               char fname[entry->d_reclen + 48];
    395               strcat(strcat(strcpy(fname, "/proc/"),
    396                             entry->d_name), marker_path);
    397 
    398               /* Check if the marker is identical to the one we created      */
    399               if (sys_stat(fname, &tmp_sb) >= 0 &&
    400                   marker_sb.st_ino == tmp_sb.st_ino) {
    401                 long i, j;
    402 
    403                 /* Found one of our threads, make sure it is no duplicate    */
    404                 for (i = 0; i < num_threads; i++) {
    405                   /* Linear search is slow, but should not matter much for
    406                    * the typically small number of threads.
    407                    */
    408                   if (pids[i] == pid) {
    409                     /* Found a duplicate; most likely on second pass         */
    410                     goto next_entry;
    411                   }
    412                 }
    413 
    414                 /* Check whether data structure needs growing                */
    415                 if (num_threads >= max_threads) {
    416                   /* Back to square one, this time with more memory          */
    417                   NO_INTR(sys_close(proc));
    418                   goto detach_threads;
    419                 }
    420 
    421                 /* Attaching to thread suspends it                           */
    422                 pids[num_threads++] = pid;
    423                 sig_num_threads     = num_threads;
    424                 if (sys_ptrace(PTRACE_ATTACH, pid, (void *)0,
    425                                (void *)0) < 0) {
    426                   /* If operation failed, ignore thread. Maybe it
    427                    * just died?  There might also be a race
    428                    * condition with a concurrent core dumper or
    429                    * with a debugger. In that case, we will just
    430                    * make a best effort, rather than failing
    431                    * entirely.
    432                    */
    433                   num_threads--;
    434                   sig_num_threads = num_threads;
    435                   goto next_entry;
    436                 }
    437                 while (sys_waitpid(pid, (int *)0, __WALL) < 0) {
    438                   if (errno != EINTR) {
    439                     sys_ptrace_detach(pid);
    440                     num_threads--;
    441                     sig_num_threads = num_threads;
    442                     goto next_entry;
    443                   }
    444                 }
    445 
    446                 if (sys_ptrace(PTRACE_PEEKDATA, pid, &i, &j) || i++ != j ||
    447                     sys_ptrace(PTRACE_PEEKDATA, pid, &i, &j) || i   != j) {
    448                   /* Address spaces are distinct, even though both
    449                    * processes show the "marker". This is probably
    450                    * a forked child process rather than a thread.
    451                    */
    452                   sys_ptrace_detach(pid);
    453                   num_threads--;
    454                   sig_num_threads = num_threads;
    455                 } else {
    456                   found_parent |= pid == ppid;
    457                   added_entries++;
    458                 }
    459               }
    460             }
    461           }
    462         next_entry:;
    463         }
    464       }
    465       NO_INTR(sys_close(proc));
    466       sig_proc = proc = -1;
    467 
    468       /* If we failed to find any threads, try looking somewhere else in
    469        * /proc. Maybe, threads are reported differently on this system.
    470        */
    471       if (num_threads > 1 || !*++proc_path) {
    472         NO_INTR(sys_close(marker));
    473         sig_marker = marker = -1;
    474 
    475         /* If we never found the parent process, something is very wrong.
    476          * Most likely, we are running in debugger. Any attempt to operate
    477          * on the threads would be very incomplete. Let's just report an
    478          * error to the caller.
    479          */
    480         if (!found_parent) {
    481           ResumeAllProcessThreads(num_threads, pids);
    482           sys__exit(3);
    483         }
    484 
    485         /* Now we are ready to call the callback,
    486          * which takes care of resuming the threads for us.
    487          */
    488         args->result = args->callback(args->parameter, num_threads,
    489                                       pids, args->ap);
    490         args->err = errno;
    491 
    492         /* Callback should have resumed threads, but better safe than sorry  */
    493         if (ResumeAllProcessThreads(num_threads, pids)) {
    494           /* Callback forgot to resume at least one thread, report error     */
    495           args->err    = EINVAL;
    496           args->result = -1;
    497         }
    498 
    499         sys__exit(0);
    500       }
    501     detach_threads:
    502       /* Resume all threads prior to retrying the operation                  */
    503       ResumeAllProcessThreads(num_threads, pids);
    504       sig_pids = NULL;
    505       num_threads = 0;
    506       sig_num_threads = num_threads;
    507       max_threads += 100;
    508     }
    509   }
    510 }
    511 
    512 
    513 /* This function gets the list of all linux threads of the current process
    514  * passes them to the 'callback' along with the 'parameter' pointer; at the
    515  * call back call time all the threads are paused via
    516  * PTRACE_ATTACH.
    517  * The callback is executed from a separate thread which shares only the
    518  * address space, the filesystem, and the filehandles with the caller. Most
    519  * notably, it does not share the same pid and ppid; and if it terminates,
    520  * the rest of the application is still there. 'callback' is supposed to do
    521  * or arrange for ResumeAllProcessThreads. This happens automatically, if
    522  * the thread raises a synchronous signal (e.g. SIGSEGV); asynchronous
    523  * signals are blocked. If the 'callback' decides to unblock them, it must
    524  * ensure that they cannot terminate the application, or that
    525  * ResumeAllProcessThreads will get called.
    526  * It is an error for the 'callback' to make any library calls that could
    527  * acquire locks. Most notably, this means that most system calls have to
    528  * avoid going through libc. Also, this means that it is not legal to call
    529  * exit() or abort().
    530  * We return -1 on error and the return value of 'callback' on success.
    531  */
    532 int ListAllProcessThreads(void *parameter,
    533                           ListAllProcessThreadsCallBack callback, ...) {
    534   char                   altstack_mem[ALT_STACKSIZE];
    535   struct ListerParams    args;
    536   pid_t                  clone_pid;
    537   int                    dumpable = 1, sig;
    538   struct kernel_sigset_t sig_blocked, sig_old;
    539 
    540   va_start(args.ap, callback);
    541 
    542   /* If we are short on virtual memory, initializing the alternate stack
    543    * might trigger a SIGSEGV. Let's do this early, before it could get us
    544    * into more trouble (i.e. before signal handlers try to use the alternate
    545    * stack, and before we attach to other threads).
    546    */
    547   memset(altstack_mem, 0, sizeof(altstack_mem));
    548 
    549   /* Some of our cleanup functions could conceivable use more stack space.
    550    * Try to touch the stack right now. This could be defeated by the compiler
    551    * being too smart for it's own good, so try really hard.
    552    */
    553   DirtyStack(32768);
    554 
    555   /* Make this process "dumpable". This is necessary in order to ptrace()
    556    * after having called setuid().
    557    */
    558   dumpable = sys_prctl(PR_GET_DUMPABLE, 0);
    559   if (!dumpable)
    560     sys_prctl(PR_SET_DUMPABLE, 1);
    561 
    562   /* Fill in argument block for dumper thread                                */
    563   args.result       = -1;
    564   args.err          = 0;
    565   args.altstack_mem = altstack_mem;
    566   args.parameter    = parameter;
    567   args.callback     = callback;
    568 
    569   /* Before cloning the thread lister, block all asynchronous signals, as we */
    570   /* are not prepared to handle them.                                        */
    571   sys_sigfillset(&sig_blocked);
    572   for (sig = 0; sig < sizeof(sync_signals)/sizeof(*sync_signals); sig++) {
    573     sys_sigdelset(&sig_blocked, sync_signals[sig]);
    574   }
    575   if (sys_sigprocmask(SIG_BLOCK, &sig_blocked, &sig_old)) {
    576     args.err = errno;
    577     args.result = -1;
    578     goto failed;
    579   }
    580 
    581   /* scope */ {
    582     /* After cloning, both the parent and the child share the same instance
    583      * of errno. We must make sure that at least one of these processes
    584      * (in our case, the parent) uses modified syscall macros that update
    585      * a local copy of errno, instead.
    586      */
    587     #ifdef __cplusplus
    588       #define sys0_sigprocmask sys.sigprocmask
    589       #define sys0_waitpid     sys.waitpid
    590       SysCalls sys;
    591     #else
    592       int my_errno;
    593       #define SYS_ERRNO        my_errno
    594       #define SYS_INLINE       inline
    595       #define SYS_PREFIX       0
    596       #undef  SYS_LINUX_SYSCALL_SUPPORT_H
    597       #include "linux_syscall_support.h"
    598     #endif
    599 
    600     int clone_errno;
    601     clone_pid = local_clone((int (*)(void *))ListerThread, &args);
    602     clone_errno = errno;
    603 
    604     sys_sigprocmask(SIG_SETMASK, &sig_old, &sig_old);
    605 
    606     if (clone_pid >= 0) {
    607       int status, rc;
    608       while ((rc = sys0_waitpid(clone_pid, &status, __WALL)) < 0 &&
    609              ERRNO == EINTR) {
    610              /* Keep waiting                                                 */
    611       }
    612       if (rc < 0) {
    613         args.err = ERRNO;
    614         args.result = -1;
    615       } else if (WIFEXITED(status)) {
    616         switch (WEXITSTATUS(status)) {
    617           case 0: break;             /* Normal process termination           */
    618           case 2: args.err = EFAULT; /* Some fault (e.g. SIGSEGV) detected   */
    619                   args.result = -1;
    620                   break;
    621           case 3: args.err = EPERM;  /* Process is already being traced      */
    622                   args.result = -1;
    623                   break;
    624           default:args.err = ECHILD; /* Child died unexpectedly              */
    625                   args.result = -1;
    626                   break;
    627         }
    628       } else if (!WIFEXITED(status)) {
    629         args.err    = EFAULT;        /* Terminated due to an unhandled signal*/
    630         args.result = -1;
    631       }
    632     } else {
    633       args.result = -1;
    634       args.err    = clone_errno;
    635     }
    636   }
    637 
    638   /* Restore the "dumpable" state of the process                             */
    639 failed:
    640   if (!dumpable)
    641     sys_prctl(PR_SET_DUMPABLE, dumpable);
    642 
    643   va_end(args.ap);
    644 
    645   errno = args.err;
    646   return args.result;
    647 }
    648 
    649 /* This function resumes the list of all linux threads that
    650  * ListAllProcessThreads pauses before giving to its callback.
    651  * The function returns non-zero if at least one thread was
    652  * suspended and has now been resumed.
    653  */
    654 int ResumeAllProcessThreads(int num_threads, pid_t *thread_pids) {
    655   int detached_at_least_one = 0;
    656   while (num_threads-- > 0) {
    657     detached_at_least_one |= sys_ptrace_detach(thread_pids[num_threads]) >= 0;
    658   }
    659   return detached_at_least_one;
    660 }
    661 
    662 #ifdef __cplusplus
    663 }
    664 #endif
    665 #endif
    666