gdb, gdbserver: detach fork child when detaching from fork parent
[binutils-gdb.git] / gdbserver / linux-low.h
index 819f915ea9a38e06fe4aaaaf052e9b7ba5926053..b563537216a6b2cee00c6a2855bc462ff5fa8839 100644 (file)
@@ -312,6 +312,7 @@ public:
 #endif
 
   thread_info *thread_pending_parent (thread_info *thread) override;
+  thread_info *thread_pending_child (thread_info *thread) override;
 
   bool supports_catch_syscall () override;
 
@@ -750,6 +751,32 @@ struct lwp_info
     return this->fork_relative;
   }
 
+  /* If this LWP is the parent of a fork child we haven't reported to GDB yet,
+     return that child, else nullptr.  */
+  lwp_info *pending_child () const
+  {
+    if (this->fork_relative == nullptr)
+      return nullptr;
+
+    gdb_assert (this->fork_relative->fork_relative == this);
+
+    /* In a fork parent/child relationship, the parent has a status pending and
+       the child does not, and a thread can only be in one such relationship
+       at most.  So we can recognize who is the parent based on which one has
+       a pending status.  */
+    gdb_assert (!!this->status_pending_p
+               != !!this->fork_relative->status_pending_p);
+
+    if (!this->status_pending_p)
+      return nullptr;
+
+    const target_waitstatus &ws = this->waitstatus;
+    gdb_assert (ws.kind () == TARGET_WAITKIND_FORKED
+               || ws.kind () == TARGET_WAITKIND_VFORKED);
+
+    return this->fork_relative;
+  }
+
   /* Backlink to the parent object.  */
   struct thread_info *thread = nullptr;