From b9af3062ad2037b8acb463a0bba0b8cfc6a1c405 Mon Sep 17 00:00:00 2001
From: Aditya Vidyadhar Kamath <Aditya.Kamath1@ibm.com>
Date: Sun, 13 Nov 2022 11:48:52 -0600
Subject: [PATCH] Fix multi thread debug bug in AIX

When a process is multi threaded then AIX was adding a new thread with a priv set.

This thread is the same as main process thread without a private data set.

Hence an assertion failure checked_static_cast: Assertion result != nullptr failed is seen

This patch is a fix for the same where only new threads created are added and once a program

 is multi threaded then the main process private data is set instead of adding a new thread for itself.
---
 gdb/aix-thread.c | 104 +++++++++++++++++++++--------------------------
 1 file changed, 47 insertions(+), 57 deletions(-)

diff --git a/gdb/aix-thread.c b/gdb/aix-thread.c
index e556c153576..6f910fcf847 100644
--- a/gdb/aix-thread.c
+++ b/gdb/aix-thread.c
@@ -795,69 +795,59 @@ sync_threadlists (int pid)
   g = gbuf = XNEWVEC (struct thread_info *, gcount);
   iterate_over_threads (giter_accum, &g);
   qsort (gbuf, gcount, sizeof *gbuf, gcmp);
+  
+  /* If this is the first time the process is pthreaded then
+     the main process running as one thread must have a private
+     data.  */
+ 
+  if (pcount == 1 && gcount == 0)
+  {
+    pi = 0;
+    aix_thread_info *priv = new aix_thread_info;
+    priv->pdtid = pbuf[pi].pdtid;
+    priv->tid = pbuf[pi].tid;
+    process_stratum_target *proc_target
+                = current_inferior ()->process_target ();
+    thread_info *tp = find_thread_ptid (proc_target, ptid_t (pid));
+      if (tp->priv == NULL)
+        tp->priv.reset (priv);
+  }
 
-  /* Apply differences between the two arrays to GDB's thread list.  */
-  for (pi = gi = 0; pi < pcount || gi < gcount;)
-    {
-      if (pi == pcount)
-	{
-	  delete_thread (gbuf[gi]);
-	  gi++;
-	}
-      else if (gi == gcount)
-	{
-	  aix_thread_info *priv = new aix_thread_info;
-	  priv->pdtid = pbuf[pi].pdtid;
-	  priv->tid = pbuf[pi].tid;
-
-	  process_stratum_target *proc_target
-	    = current_inferior ()->process_target ();
-	  thread = add_thread_with_info (proc_target,
-					 ptid_t (pid, 0, pbuf[pi].pthid),
-					 priv);
-
-	  pi++;
-	}
-      else
-	{
-	  ptid_t pptid, gptid;
-	  int cmp_result;
+  /* This means that new threads have been created and
+     they need to be added in the GDB threads list.  */
 
-	  pptid = ptid_t (pid, 0, pbuf[pi].pthid);
-	  gptid = gbuf[gi]->ptid;
-	  pdtid = pbuf[pi].pdtid;
-	  tid = pbuf[pi].tid;
+  else if (pcount > 1 && gcount < pcount)
+  {
+    pi = 1;
+    while (pcount - 1 != gcount)
+    {
+      aix_thread_info *priv = new aix_thread_info;
+      priv->pdtid = pbuf[pi].pdtid;
+      priv->tid = pbuf[pi].tid;
 
-	  cmp_result = ptid_cmp (pptid, gptid);
+      process_stratum_target *proc_target
+        = current_inferior ()->process_target ();
+      thread = add_thread_with_info (proc_target,
+                                     ptid_t (pid, 0, pbuf[pi].pthid),
+                                     priv);
+      pi++;
+      gcount++; 
+    }    
+  }
 
-	  if (cmp_result == 0)
-	    {
-	      aix_thread_info *priv = get_aix_thread_info (gbuf[gi]);
+  /* This condition implies the threads have exited or died.  Hence
+     we delete those exited threads.  Since we don't add a thread
+     for main process pcount must be equal to gcount + 1.  */
 
-	      priv->pdtid = pdtid;
-	      priv->tid = tid;
-	      pi++;
-	      gi++;
-	    }
-	  else if (cmp_result > 0)
-	    {
-	      delete_thread (gbuf[gi]);
-	      gi++;
-	    }
-	  else
-	    {
-	      process_stratum_target *proc_target
-		= current_inferior ()->process_target ();
-	      thread = add_thread (proc_target, pptid);
-
-	      aix_thread_info *priv = new aix_thread_info;
-	      thread->priv.reset (priv);
-	      priv->pdtid = pdtid;
-	      priv->tid = tid;
-	      pi++;
-	    }
-	}
+  else if (pcount >= 1 && gcount > pcount)
+  {
+    gi  = 0;
+    while (gcount != pcount - 1)
+    {
+      delete_thread (gbuf[gi++]);
+      gcount--;
     }
+  }
 
   xfree (pbuf);
   xfree (gbuf);
-- 
2.31.1

