]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Fix AIX thr!= NULL assertion failure during fork.
authorAditya Vidyadhar Kamath <Aditya.Kamath1@ibm.com>
Wed, 22 Nov 2023 16:13:35 +0000 (10:13 -0600)
committerUlrich Weigand <ulrich.weigand@de.ibm.com>
Wed, 22 Nov 2023 18:29:21 +0000 (19:29 +0100)
In AIX, while we followed the child process and detach on fork was on we hit thr!= NULL assertion failure.

The reason for the same was GDB core trying to switch to a child thread with tid not set that does not
exist, since child's ptid was changed to ptid_t (pid, 0, tid) in sync_threadlists() as it was threaded.

The way this happened was when a new child process is born, its object file will be loaded, calling the new_objfile ()
in aix-thread.c file from clone_program_space, which is
called from within follow_fork_inferior. Therefore it end ups syncing threadlists via pd_update ().

This patch is a fix for the same where pd_update () is called in the wait () or in update_thread_list() hook only.

gdb/aix-thread.c

index 945b7f6c6974db2f005db2e84c0dd2309c09247c..c8147defc046418570dd216b791efe8e09141ce4 100644 (file)
@@ -136,6 +136,8 @@ public:
   const char *extra_thread_info (struct thread_info *) override;
 
   ptid_t get_ada_task_ptid (long lwp, ULONGEST thread) override;
+
+  void update_thread_list () override;
 };
 
 static aix_thread_target aix_thread_ops;
@@ -1015,7 +1017,7 @@ pd_update (pid_t pid)
    If successful and there exists and we can find an event thread, return a ptid
    for that thread.  Otherwise, return a ptid-only ptid using PID.  */
 
-static ptid_t
+static void
 pd_activate (pid_t pid)
 {
   int status;
@@ -1030,9 +1032,24 @@ pd_activate (pid_t pid)
       return ptid_t (pid);
     }
   data->pd_active = 1;
-  return pd_update (pid);
+  return;
 }
 
+/* AIX implementation of update_thread_list.  */
+
+void
+aix_thread_target::update_thread_list ()
+{
+  for (inferior *inf : all_inferiors ())
+    {
+      if (inf->pid == 0)
+       continue;
+
+      pd_update (inf->pid);
+    }
+}
+
+
 /* An object file has just been loaded.  Check whether the current
    application is pthreaded, and if so, prepare for thread debugging.  */
 
@@ -1077,11 +1094,6 @@ pd_enable (inferior *inf)
   current_inferior ()->push_target (&aix_thread_ops);
   data->pd_able = 1;
 
-  /* When attaching / handling fork child, don't try activating
-     thread debugging until we know about all shared libraries.  */
-  if (inf->in_initial_library_scan)
-    return;
-
   /* If we're debugging a core file or an attached inferior, the
      pthread library may already have been initialized, so try to
      activate thread debugging.  */
@@ -1216,7 +1228,7 @@ aix_thread_target::wait (ptid_t ptid, struct target_waitstatus *status,
 
       if (regcache_read_pc (regcache)
          - gdbarch_decr_pc_after_break (gdbarch) == data->pd_brk_addr)
-       return pd_activate (ptid.pid ());
+       pd_activate (ptid.pid ());
     }
 
   return pd_update (ptid.pid ());