From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10010 invoked by alias); 23 Aug 2011 14:00:16 -0000 Received: (qmail 9983 invoked by uid 22791); 23 Aug 2011 14:00:14 -0000 X-SWARE-Spam-Status: No, hits=-2.5 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 23 Aug 2011 13:59:58 +0000 Received: (qmail 11917 invoked from network); 23 Aug 2011 13:59:57 -0000 Received: from unknown (HELO ?192.168.0.101?) (lgustavo@127.0.0.2) by mail.codesourcery.com with ESMTPA; 23 Aug 2011 13:59:57 -0000 Message-ID: <4E53B25B.3030009@codesourcery.com> Date: Tue, 23 Aug 2011 14:00:00 -0000 From: Luis Machado Reply-To: lgustavo@codesourcery.com User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.18) Gecko/20110617 Lightning/1.0b2 Thunderbird/3.1.11 MIME-Version: 1.0 To: gdb-patches@sourceware.org, Pedro Alves Subject: [PATCH] Stop threads when attaching to a PID that is the tgid Content-Type: multipart/mixed; boundary="------------030905040806020809040404" Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-08/txt/msg00419.txt.bz2 This is a multi-part message in MIME format. --------------030905040806020809040404 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 339 Hi, This patch teaches GDBServer how to stop threads from a TID that is also the TGID, without having to rely on GDB to list and stop them upon connection. In case the PID being attached to is not the TGID, GDBServer attaches to such a PID in the usual way, without stopping any other threads. Tested without regressions. Ok? Luis --------------030905040806020809040404 Content-Type: text/x-patch; name="stop_threads.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="stop_threads.diff" Content-length: 3367 2011-08-23 Luis Machado * linux-low.c: Include linux-procfs.h. (linux_attach_lwp_1): Update comments. (linux_attach): Scan for existing threads when attaching to a process that is the tgid. --- .pc/stop_threads.diff/gdb/gdbserver/linux-low.c 2011-08-23 10:38:50.653049001 -0300 +++ gdb/gdbserver/linux-low.c 2011-08-23 10:58:02.817049000 -0300 @@ -26,6 +26,7 @@ #include #include #include "linux-ptrace.h" +#include "linux-procfs.h" #include #include #include @@ -586,7 +587,9 @@ linux_attach_lwp_1 (unsigned long lwpid, } if (initial) - /* NOTE/FIXME: This lwp might have not been the tgid. */ + /* If lwp is the tgid, we handle adding existing threads later. + Otherwise we just add lwp without bothering about any other + threads. */ ptid = ptid_build (lwpid, lwpid, 0); else { @@ -621,8 +624,10 @@ linux_attach_lwp_1 (unsigned long lwpid, In this case we want the process thread to stop. This is handled by having linux_attach set last_resume_kind == resume_stop after we return. - ??? If the process already has several threads we leave the other - threads running. + + If the pid we are attaching to is also the tgid, we attach to and + stop all the existing threads. Otherwise, we attach to pid and + ignore any other threads in the same group as this pid. 3) GDB is connecting to gdbserver and is requesting an enumeration of all existing threads. @@ -646,9 +651,14 @@ linux_attach_lwp (unsigned long lwpid) linux_attach_lwp_1 (lwpid, 0); } +/* Attach to PID. If PID is the tgid, attach to it and all + of its threads. */ + int linux_attach (unsigned long pid) { + /* Attach to PID. We will check for other threads + soon. */ linux_attach_lwp_1 (pid, 1); linux_add_process (pid, 1); @@ -662,6 +672,65 @@ linux_attach (unsigned long pid) thread->last_resume_kind = resume_stop; } + if (linux_proc_get_tgid (pid) == pid) + { + DIR *dir; + char pathname[128]; + + sprintf (pathname, "/proc/%ld/task", pid); + + dir = opendir (pathname); + + if (!dir) + { + fprintf (stderr, "Could not open /proc/%ld/task.\n", pid); + fflush (stderr); + } + else + { + /* At this point we attached to the tgid. Scan the task for + existing threads. */ + unsigned long lwp; + int new_threads_found; + int iterations = 0; + struct dirent *dp; + + while (iterations < 2) + { + new_threads_found = 0; + /* Add all the other threads. While we go through the + threads, new threads may be spawned. Cycle through + the list of threads until we have done two iterations without + finding new threads. */ + while ((dp = readdir (dir)) != NULL) + { + /* Fetch one lwp. */ + lwp = strtoul (dp->d_name, NULL, 10); + + /* Is this a new thread? */ + if (lwp + && find_thread_ptid (ptid_build (pid, lwp, 0)) == NULL) + { + linux_attach_lwp_1 (lwp, 0); + new_threads_found++; + + if (debug_threads) + fprintf (stderr, "\ +Found and attached to new lwp %ld\n", lwp); + } + } + + if (!new_threads_found) + iterations++; + else + iterations = 0; + + rewinddir (dir); + } + closedir (dir); + } + } + return 0; } --------------030905040806020809040404--