gdb: Avoid using W_STOPCODE(0) as this is ambiguous on MIPS
authorAndrew Burgess <andrew.burgess@embecosm.com>
Tue, 3 Jul 2018 18:02:48 +0000 (19:02 +0100)
committerAndrew Burgess <andrew.burgess@embecosm.com>
Mon, 6 Aug 2018 07:49:39 +0000 (08:49 +0100)
The MIPS target supports 127 signals, and this can create an ambiguity
in process wait statuses.  A status value of 0x007f could potentially
indicate a process that has exited with signal 127, or a process that
has stopped with signal 0.

In uClibc-ng the interpretation of 0x007f is that the process has
exited with signal 127 rather than stopped with signal 0, and so,
WIFSTOPPED (W_STOPCODE (0)) will be false rather than true as it would
be on most other platforms.

Given that it's pretty easy to avoid using W_STOPCODE (0), lets do that.

gdb/ChangeLog:

* linux-nat.c (linux_nat_target::follow_fork): Avoid using
'W_STOPCODE (0)' as this could be ambiguous.

gdb/ChangeLog
gdb/linux-nat.c

index 43594561d50f525565598d4fe3a6c0db94f2ba85..0d38674640e19e738430eb76542a8b871fcebb59 100644 (file)
@@ -1,3 +1,9 @@
+2018-08-06  Sergey Korolev  <s.korolev@ndmsystems.com>
+           Andrew Burgess  <andrew.burgess@embecosm.com>
+
+       * linux-nat.c (linux_nat_target::follow_fork): Avoid using
+       'W_STOPCODE (0)' as this could be ambiguous.
+
 2018-08-03  Sergio Durigan Junior  <sergiodj@redhat.com>
 
        * ser-tcp.c (net_open): Fix thinko when deciding whether to
index 86d3dfd2b894c1fb6b830742abd3a05f0aae78d1..d2c88ad0cd42ad181f1382ecb5245c4da4c502da 100644 (file)
@@ -445,7 +445,6 @@ linux_nat_target::follow_fork (int follow_child, int detach_fork)
   if (!follow_child)
     {
       struct lwp_info *child_lp = NULL;
-      int status = W_STOPCODE (0);
       int has_vforked;
       ptid_t parent_ptid, child_ptid;
       int parent_pid, child_pid;
@@ -465,6 +464,8 @@ linux_nat_target::follow_fork (int follow_child, int detach_fork)
       /* Detach new forked process?  */
       if (detach_fork)
        {
+         int child_stop_signal = 0;
+         bool detach_child = true;
          struct cleanup *old_chain = make_cleanup (delete_lwp_cleanup,
                                                    child_lp);
 
@@ -484,18 +485,24 @@ linux_nat_target::follow_fork (int follow_child, int detach_fork)
          if (!gdbarch_software_single_step_p (target_thread_architecture
                                               (parent_ptid)))
            {
+             int status;
+
              linux_disable_event_reporting (child_pid);
              if (ptrace (PTRACE_SINGLESTEP, child_pid, 0, 0) < 0)
                perror_with_name (_("Couldn't do single step"));
              if (my_waitpid (child_pid, &status, 0) < 0)
                perror_with_name (_("Couldn't wait vfork process"));
+             else
+               {
+                 detach_child = WIFSTOPPED (status);
+                 child_stop_signal = WSTOPSIG (status);
+               }
            }
 
-         if (WIFSTOPPED (status))
+         if (detach_child)
            {
-             int signo;
+             int signo = child_stop_signal;
 
-             signo = WSTOPSIG (status);
              if (signo != 0
                  && !signal_pass_state (gdb_signal_from_host (signo)))
                signo = 0;