From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19535 invoked by alias); 23 May 2011 10:38:11 -0000 Received: (qmail 19524 invoked by uid 22791); 23 May 2011 10:38:10 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL,BAYES_00,T_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; Mon, 23 May 2011 10:37:56 +0000 Received: (qmail 7295 invoked from network); 23 May 2011 10:37:55 -0000 Received: from unknown (HELO scottsdale.localnet) (pedro@127.0.0.2) by mail.codesourcery.com with ESMTPA; 23 May 2011 10:37:55 -0000 From: Pedro Alves To: gdb-patches@sourceware.org, lgustavo@codesourcery.com Subject: Re: [PATCH, gdbserver] Scan for existing threads during attachment on Linux Date: Mon, 23 May 2011 10:38:00 -0000 User-Agent: KMail/1.13.5 (Linux/2.6.35-28-generic; KDE/4.6.2; x86_64; ; ) References: In-Reply-To: MIME-Version: 1.0 Content-Type: Text/Plain; charset="iso-8859-15" Content-Transfer-Encoding: 7bit Message-Id: <201105231137.53423.pedro@codesourcery.com> X-IsSubscribed: yes 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-05/txt/msg00517.txt.bz2 On Friday 20 May 2011 19:42:02, Luis Machado wrote: > +/* Attach to PID. If PID is the tgdi, attach to it and stop > + all of its threads. */ > + > int > linux_attach (unsigned long pid) > { > + DIR *dir; > + char pathname[128]; > + int is_tgid = 0; > + FILE *fd; > + > + /* Attach to PID. We will check for other threads > + soon. */ > linux_attach_lwp_1 (pid, 1); > - linux_add_process (pid, 1); > > - if (!non_stop) > + /* Find out what is the tgid of this lwp. */ > + sprintf (pathname, "/proc/%ld/stat", pid); Can you factor this into a standalone function, something like static int tgid_of_pid (int pid) { ... } please? > + > + fd = fopen (pathname, "r"); > + > + if (fd != NULL) > { > - struct thread_info *thread; > + int proc_id, ppid, pgrp; > + char comm[NAME_MAX + 1], state; > > - /* Don't ignore the initial SIGSTOP if we just attached to this > - process. It will be collected by wait shortly. */ > - thread = find_thread_ptid (ptid_build (pid, pid, 0)); > - thread->last_resume_kind = resume_stop; > + fscanf (fd, "%d %s %c %d %d", &proc_id, comm, &state, &ppid, &pgrp); > + fclose (fd); > + > + if (pgrp == pid) > + is_tgid = 1; > + } > + else > + { > + fprintf (stderr, "Could not open /proc/%ld/stat.\n", pid); > + fflush (stderr); > } > > + sprintf (pathname, "/proc/%ld/task", pid); > + > + dir = opendir (pathname); > + > + if (!dir) > + { > + fprintf (stderr, "Could not open /proc/%ld/task.\n", pid); > + fflush (stderr); > + } Why even try to open the dir if is_tgid is false? > + else if (is_tgid) > + { > + /* 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); > + } > + > + linux_add_process (pid, 1); > + > + /* Mark the threads as stopped. */ > + if (!non_stop) > + for_each_inferior (&all_threads, set_resume_kind_stop); > + > return 0; > } > Otherwise okay. -- Pedro Alves