]> git.pld-linux.org Git - packages/gdb.git/blob - gdb-6.6-bz247354-leader-exit-fix.patch
- update to gdb-7.0-7.fc12.src.rpm; but leave cactus patches as these seem newer
[packages/gdb.git] / gdb-6.6-bz247354-leader-exit-fix.patch
1 2007-07-08  Jan Kratochvil  <jan.kratochvil@redhat.com>
2
3         * linux-nat.c (linux_lwp_is_zombie): New function.
4         (wait_lwp): Fix lockup on exit of the thread group leader.
5         (linux_xfer_partial): Renamed to ...
6         (linux_xfer_partial_lwp): ... here.
7         (linux_xfer_partial): New function wrapping LINUX_XFER_PARTIAL_LWP.
8
9 2008-02-24  Jan Kratochvil  <jan.kratochvil@redhat.com>
10
11         Port to GDB-6.8pre.
12
13 Index: gdb-6.8.50.20081209/gdb/linux-nat.c
14 ===================================================================
15 --- gdb-6.8.50.20081209.orig/gdb/linux-nat.c    2008-12-10 01:27:34.000000000 +0100
16 +++ gdb-6.8.50.20081209/gdb/linux-nat.c 2008-12-10 01:28:14.000000000 +0100
17 @@ -1981,6 +1981,31 @@ linux_handle_extended_wait (struct lwp_i
18                   _("unknown ptrace event %d"), event);
19  }
20  
21 +static int
22 +linux_lwp_is_zombie (long lwp)
23 +{
24 +  char buffer[MAXPATHLEN];
25 +  FILE *procfile;
26 +  int retval = 0;
27 +
28 +  sprintf (buffer, "/proc/%ld/status", lwp);
29 +  procfile = fopen (buffer, "r");
30 +  if (procfile == NULL)
31 +    {
32 +      warning (_("unable to open /proc file '%s'"), buffer);
33 +      return 0;
34 +    }
35 +  while (fgets (buffer, sizeof (buffer), procfile) != NULL)
36 +    if (strcmp (buffer, "State:\tZ (zombie)\n") == 0)
37 +      {
38 +       retval = 1;
39 +       break;
40 +      }
41 +  fclose (procfile);
42 +
43 +  return retval;
44 +}
45 +
46  /* Wait for LP to stop.  Returns the wait status, or 0 if the LWP has
47     exited.  */
48  
49 @@ -1988,16 +2013,31 @@ static int
50  wait_lwp (struct lwp_info *lp)
51  {
52    pid_t pid;
53 -  int status;
54 +  int status = 0;
55    int thread_dead = 0;
56  
57    gdb_assert (!lp->stopped);
58    gdb_assert (lp->status == 0);
59  
60 -  pid = my_waitpid (GET_LWP (lp->ptid), &status, 0);
61 -  if (pid == -1 && errno == ECHILD)
62 +  /* Thread group leader may have exited but we would lock up by WAITPID as it
63 +     waits on all its threads; __WCLONE is not applicable for the leader.
64 +     The thread leader restrictions is only a performance optimization here.
65 +     LINUX_NAT_THREAD_ALIVE cannot be used here as it requires a STOPPED
66 +     process; it gets ESRCH both for the zombie and for running processes.  */
67 +  if (is_lwp (lp->ptid) && GET_PID (lp->ptid) == GET_LWP (lp->ptid)
68 +      && linux_lwp_is_zombie (GET_LWP (lp->ptid)))
69 +    {
70 +      thread_dead = 1;
71 +      if (debug_linux_nat)
72 +       fprintf_unfiltered (gdb_stdlog, "WL: Threads leader %s vanished.\n",
73 +                           target_pid_to_str (lp->ptid));
74 +    }
75 +
76 +  if (!thread_dead)
77      {
78 -      pid = my_waitpid (GET_LWP (lp->ptid), &status, __WCLONE);
79 +      pid = my_waitpid (GET_LWP (lp->ptid), &status, 0);
80 +      if (pid == -1 && errno == ECHILD)
81 +       pid = my_waitpid (GET_LWP (lp->ptid), &status, __WCLONE);
82        if (pid == -1 && errno == ECHILD)
83         {
84           /* The thread has previously exited.  We need to delete it
85 @@ -4153,8 +4193,10 @@ linux_nat_xfer_osdata (struct target_ops
86    return len;
87  }
88  
89 +/* Transfer from the specific LWP currently set by PID of INFERIOR_PTID.  */
90 +
91  static LONGEST
92 -linux_xfer_partial (struct target_ops *ops, enum target_object object,
93 +linux_xfer_partial_lwp (struct target_ops *ops, enum target_object object,
94                      const char *annex, gdb_byte *readbuf,
95                     const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
96  {
97 @@ -4201,6 +4243,45 @@ linux_xfer_partial (struct target_ops *o
98                              offset, len);
99  }
100  
101 +/* nptl_db expects being able to transfer memory just by specifying PID.
102 +   After the thread group leader exists the Linux kernel turns the task
103 +   into zombie no longer permitting accesses to its memory.
104 +   Transfer the memory from an arbitrary LWP_LIST entry in such case.  */
105 +
106 +static LONGEST
107 +linux_xfer_partial (struct target_ops *ops, enum target_object object,
108 +                    const char *annex, gdb_byte *readbuf,
109 +                   const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
110 +{
111 +  LONGEST xfer;
112 +  struct lwp_info *lp;
113 +  /* Not using SAVE_INFERIOR_PTID already here for better performance.  */
114 +  struct cleanup *old_chain = NULL;
115 +  ptid_t inferior_ptid_orig = inferior_ptid;
116 +
117 +  errno = 0;
118 +  xfer = linux_xfer_partial_lwp (ops, object, annex, readbuf, writebuf,
119 +                                offset, len);
120 +
121 +  for (lp = lwp_list; xfer == 0 && (errno == EACCES || errno == ESRCH)
122 +                     && lp != NULL; lp = lp->next)
123 +    {
124 +      if (!is_lwp (lp->ptid) || ptid_equal (lp->ptid, inferior_ptid_orig))
125 +        continue;
126 +      
127 +      if (old_chain == NULL)
128 +       old_chain = save_inferior_ptid ();
129 +      inferior_ptid = BUILD_LWP (GET_LWP (lp->ptid), GET_LWP (lp->ptid));
130 +      errno = 0;
131 +      xfer = linux_xfer_partial_lwp (ops, object, annex, readbuf, writebuf,
132 +                                    offset, len);
133 +    }
134 +
135 +  if (old_chain != NULL)
136 +    do_cleanups (old_chain);
137 +  return xfer;
138 +}
139 +
140  /* Create a prototype generic GNU/Linux target.  The client can override
141     it with local methods.  */
142  
This page took 0.29053 seconds and 3 git commands to generate.