This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH, gdbserver] Scan for existing threads during attachment on Linux


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]