Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH v5 1/4] Remove stale legacy code from rs6000-aix-nat.c file.
@ 2026-10-13 11:19 Aditya Vidyadhar Kamath
  2026-10-13 11:19 ` [PATCH v5 2/4] Remove obsolete getthrds and HAVE_PTRACE64 configure checks Aditya Vidyadhar Kamath
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Aditya Vidyadhar Kamath @ 2026-10-13 11:19 UTC (permalink / raw)
  To: ulrich.weigand, simon.marchi, tom
  Cc: gdb-patches, Aditya.Kamath1, sangamesh.swamy, Aditya Vidyadhar Kamath

From: Aditya Vidyadhar Kamath <aditya.kamath1@ibm.com>

GDB on AIX is built in 64-bit mode only.  A 64-bit program cannot link
against the legacy 32-bit ptrace () and ptracex () symbols; trying to
do so fails with:

  CXXLD  gdb
  ld: 0711-317 ERROR: Undefined symbol: .ptrace
  ld: 0711-345 Use the -bloadmap or -bnoquiet option to obtain more
  information.
  collect2: error: ld returned 8 exit status
  gmake[2]: *** [Makefile:2367: gdb] Error 1

A 64-bit GDB must use ptrace64 () exclusively.

The rs6000_ptrace32 () and rs6000_ptrace64 () wrappers conditionally
called ptrace (), ptracex () or ptrace64 () and relied on the ARCH3264
macro.  With 32-bit GDB builds deprecated and ptrace64 () available on
AIX 7.2 and 7.3, neither the wrappers nor ARCH3264 are needed.

The IBM documentation for ptrace64 ()
https://www.ibm.com/docs/en/aix/7.2.0?topic=p-ptrace-ptracex-ptrace64-subroutine
says that calling it with a
32-bit debuggee makes GPR/SPR requests fail with EIO.  Testing shows
that ptrace64 () handles 32-bit debuggees correctly:

1: For 32-bit debuggees, PT_READ_GPR returns the register value as the
   return value of ptrace64 (), and PT_WRITE_GPR takes the register
   value by value in the data argument.
2: For 64-bit debuggees, PT_READ_GPR and PT_WRITE_GPR use an 8-byte
   buffer passed as the 5th argument.
3: PT_READ_FPR and PT_WRITE_FPR work for both 32-bit and 64-bit
   debuggees.

The changes are:

1: Remove rs6000_ptrace32 () and rs6000_ptrace64 () and call
   ptrace64 () directly.
2: Simplify ARCH64 () to check the inferior register size, and remove
   the ARCH3264 macro.
3: Move the duplicated kernel thread ID lookup for the VSX and AltiVec
   requests into get_thread_id ().
4: Remove the dead "#if 0" block in fetch_register.

Testing

I ran the gdb.base testsuite before and after this patch, from the
gdb/testsuite directory, with 64-bit and 32-bit test programs.

64-bit:

  gmake check RUNTESTFLAGS='--directory=gdb.base \
    CC_FOR_TARGET="/opt/freeware/bin/gcc" \
    CXX_FOR_TARGET="/opt/freeware/bin/g++" \
    CXXFLAGS_FOR_TARGET="-O0 -w -g -gdwarf -maix64" \
    CFLAGS_FOR_TARGET="-O0 -w -g -gdwarf -maix64"'

32-bit (same command without -maix64):

  gmake check RUNTESTFLAGS='--directory=gdb.base \
    CC_FOR_TARGET="/opt/freeware/bin/gcc" \
    CXX_FOR_TARGET="/opt/freeware/bin/g++" \
    CXXFLAGS_FOR_TARGET="-O0 -w -g -gdwarf" \
    CFLAGS_FOR_TARGET="-O0 -w -g -gdwarf"'

                              64-bit            32-bit
                          before  after     before  after
  expected passes          41792  41802      41687  41541
  unexpected failures       2346   2343       2302   2294
  unexpected successes         1      1          1      1
  expected failures           17     17         15     15
  known failures              30     30         30     30
  unresolved testcases        30     29         11     86
  untested testcases         104    104        107    107
  unsupported tests          179    178        179    179

The number of unexpected failures does not go up in either mode.  The
failures that remain were there before this patch.  I grouped the
64-bit failures by test file to check that none of them are in code
touched here.

  Group                              Failures  Test files
  ---------------------------------  --------  --------------------------
  Casts in whatis-ptype-typedefs         1060  whatis-ptype-typedefs
    (gdb reports "Cannot access
    memory at address 0xefffffff")
  Type printing, alignment, value         336  max-depth-c, max-depth-c++,
    size and print limits                      align-c, align-c++,
                                               limited-length,
                                               max-value-size, printcmds
  Inferior function calls, stores         208  nodebug, store,
    and no-debug-info symbols                  return-nodebug, callfuncs,
                                               recurse,
                                               backtrace-through-cu-nodebug
  fork, vfork and follow-exec             158  vfork-follow-parent,
                                               multi-forks, foll-fork,
                                               catch-fork-kill,
                                               fork-running-state,
                                               kill-detach-inferiors-cmd,
                                               and 3 more
  Signals                                  98  sigstep, catch-signal,
                                               exitsignal, sigaltstack,
                                               and 4 more
  Attach, background execution and        108  attach, infcall-timeout,
    interrupt (mostly timeouts)                cli-suppress-notification,
                                               bg-execution-repeat,
                                               dprintf-detach,
                                               quit-live, and 14 more
  Everything else (83 test files)         375  dump (34), bp-permanent
                                               (24), skip-tree (22),
                                               value-history-unavailable
                                               (19), memattr (17),
                                               find (16), list-ambiguous
                                               and -readnow (28),
                                               and others
  ---------------------------------  --------
  Total                                  2343

Similarly even 32 bit failures as the above table.

---
 gdb/rs6000-aix-nat.c | 207 ++++++++++---------------------------------
 1 file changed, 47 insertions(+), 160 deletions(-)

diff --git a/gdb/rs6000-aix-nat.c b/gdb/rs6000-aix-nat.c
index 276df378824..3d1cf2542db 100644
--- a/gdb/rs6000-aix-nat.c
+++ b/gdb/rs6000-aix-nat.c
@@ -60,24 +60,9 @@
 /* Header files for alti-vec reg.  */
 #include <sys/context.h>
 
-/* On AIX4.3+, sys/ldr.h provides different versions of struct ld_info for
-   debugging 32-bit and 64-bit processes.  Define a typedef and macros for
-   accessing fields in the appropriate structures.  */
-
-/* In 32-bit compilation mode (which is the only mode from which ptrace()
-   works on 4.3), __ld_info32 is #defined as equivalent to ld_info.  */
-
-#if defined (__ld_info32) || defined (__ld_info64)
-# define ARCH3264
-#endif
-
 /* Return whether the current architecture is 64-bit.  */
 
-#ifndef ARCH3264
-# define ARCH64() 0
-#else
-# define ARCH64() (register_size (current_inferior ()->arch (), 0) == 8)
-#endif
+#define ARCH64() (register_size (current_inferior ()->arch (), 0) == 8)
 
 class rs6000_nat_target final : public inf_ptrace_target
 {
@@ -246,42 +231,20 @@ regmap (struct gdbarch *gdbarch, int regno, int *isfloat)
     return -1;
 }
 
-/* Call ptrace(REQ, ID, ADDR, DATA, BUF).  */
+/* Return the thread ID of the first kernel thread in PID, or 0 on
+   failure.  Used to call PTT_* requests which require a tid rather
+   than a pid.  */
 
-static int
-rs6000_ptrace32 (int req, int id, int *addr, int data, int *buf)
+static tid64_t
+get_thread_id (pid_t pid)
 {
-#ifdef HAVE_PTRACE64
-  int ret = ptrace64 (req, id, (uintptr_t) addr, data, buf);
-#else
-  int ret = ptrace (req, id, (int *)addr, data, buf);
-#endif
-#if 0
-  printf ("rs6000_ptrace32 (%d, %d, 0x%x, %08x, 0x%x) = 0x%x\n",
-	  req, id, (unsigned int)addr, data, (unsigned int)buf, ret);
-#endif
-  return ret;
-}
-
-/* Call ptracex(REQ, ID, ADDR, DATA, BUF).  */
+  struct thrdentry64 thrdentry;
+  tid64_t thrd_i = 0;
 
-static int
-rs6000_ptrace64 (int req, int id, long long addr, int data, void *buf)
-{
-#ifdef ARCH3264
-#  ifdef HAVE_PTRACE64
-  int ret = ptrace64 (req, id, addr, data, (PTRACE_TYPE_ARG5) buf);
-#  else
-  int ret = ptracex (req, id, addr, data, (PTRACE_TYPE_ARG5) buf);
-#  endif
-#else
-  int ret = 0;
-#endif
-#if 0
-  printf ("rs6000_ptrace64 (%d, %d, %s, %08x, 0x%x) = 0x%x\n",
-	  req, id, hex_string (addr), data, (unsigned int)buf, ret);
-#endif
-  return ret;
+  if (getthrds64 (pid, &thrdentry, sizeof (struct thrdentry64),
+		  &thrd_i, 1) == 1)
+    return thrdentry.ti_tid;
+  return 0;
 }
 
 /* Store the vsx registers.  */
@@ -292,32 +255,21 @@ store_vsx_register_aix (struct regcache *regcache, int regno)
   int ret;
   struct gdbarch *gdbarch = regcache->arch ();
   ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
-  struct thrdentry64 thrdentry;
   __vsx_context_t vsx;
   pid_t pid = inferior_ptid.pid ();
-  tid64_t thrd_i = 0;
-
-  if (getthrds64(pid, &thrdentry, sizeof(struct thrdentry64),
-		 &thrd_i, 1) == 1)
-    thrd_i = thrdentry.ti_tid;
+  tid64_t thrd_i = get_thread_id (pid);
 
   memset(&vsx, 0, sizeof(__vsx_context_t));
   if (__power_vsx() && thrd_i > 0)
     {
-      if (ARCH64 ())
-	ret = rs6000_ptrace64 (PTT_READ_VSX, thrd_i, (long long) &vsx, 0, 0);
-      else
-	ret = rs6000_ptrace32 (PTT_READ_VSX, thrd_i, (int *)&vsx, 0, 0);
+      ret = ptrace64 (PTT_READ_VSX, thrd_i, (long long) &vsx, 0, 0);
       if (ret < 0)
 	return;
 
       regcache->raw_collect (regno, &(vsx.__vsr_dw1[0])+
 			     regno - tdep->ppc_vsr0_upper_regnum);
 
-      if (ARCH64 ())
-	ret = rs6000_ptrace64 (PTT_WRITE_VSX, thrd_i, (long long) &vsx, 0, 0);
-      else
-	ret = rs6000_ptrace32 (PTT_WRITE_VSX, thrd_i, (int *) &vsx, 0, 0);
+      ret = ptrace64 (PTT_WRITE_VSX, thrd_i, (long long) &vsx, 0, 0);
 
       if (ret < 0)
 	perror_with_name (_("Unable to write VSX registers after reading it"));
@@ -332,32 +284,21 @@ store_altivec_register_aix (struct regcache *regcache, int regno)
   int ret;
   struct gdbarch *gdbarch = regcache->arch ();
   ppc_gdbarch_tdep *tdep = gdbarch_tdep<ppc_gdbarch_tdep> (gdbarch);
-  struct thrdentry64 thrdentry;
   __vmx_context_t vmx;
   pid_t pid = inferior_ptid.pid ();
-  tid64_t  thrd_i = 0;
-
-  if (getthrds64(pid, &thrdentry, sizeof(struct thrdentry64),
-		 &thrd_i, 1) == 1)
-    thrd_i = thrdentry.ti_tid;
+  tid64_t thrd_i = get_thread_id (pid);
 
   memset(&vmx, 0, sizeof(__vmx_context_t));
   if (__power_vmx() && thrd_i > 0)
     {
-      if (ARCH64 ())
-	ret = rs6000_ptrace64 (PTT_READ_VEC, thrd_i, (long long) &vmx, 0, 0);
-      else
-	ret = rs6000_ptrace32 (PTT_READ_VEC, thrd_i, (int *) &vmx, 0, 0);
+      ret = ptrace64 (PTT_READ_VEC, thrd_i, (long long) &vmx, 0, 0);
       if (ret < 0)
 	return;
 
       regcache->raw_collect (regno, &(vmx.__vr[0]) + regno
 			     - tdep->ppc_vr0_regnum);
 
-      if (ARCH64 ())
-	ret = rs6000_ptrace64 (PTT_WRITE_VEC, thrd_i, (long long) &vmx, 0, 0);
-      else
-	ret = rs6000_ptrace32 (PTT_WRITE_VEC, thrd_i, (int *) &vmx, 0, 0);
+      ret = ptrace64 (PTT_WRITE_VEC, thrd_i, (long long) &vmx, 0, 0);
       if (ret < 0)
 	perror_with_name (_("Unable to store AltiVec register after reading it"));
     }
@@ -385,22 +326,14 @@ supply_vrregset_aix (struct regcache *regcache, __vmx_context_t *vmx)
 static void
 fetch_altivec_registers_aix (struct regcache *regcache)
 {
-  struct thrdentry64 thrdentry;
   __vmx_context_t vmx;
   pid_t pid = current_inferior ()->pid;
-  tid64_t  thrd_i = 0;
-
-  if (getthrds64(pid, &thrdentry, sizeof(struct thrdentry64),
-		 &thrd_i, 1) == 1)
-    thrd_i = thrdentry.ti_tid;
+  tid64_t thrd_i = get_thread_id (pid);
 
   memset(&vmx, 0, sizeof(__vmx_context_t));
   if (__power_vmx() && thrd_i > 0)
     {
-      if (ARCH64 ())
-	rs6000_ptrace64 (PTT_READ_VEC, thrd_i, (long long) &vmx, 0, 0);
-      else
-	rs6000_ptrace32 (PTT_READ_VEC, thrd_i, (int *) &vmx, 0, 0);
+      ptrace64 (PTT_READ_VEC, thrd_i, (long long) &vmx, 0, 0);
       supply_vrregset_aix (regcache, &vmx);
     }
 }
@@ -423,38 +356,27 @@ supply_vsxregset_aix (struct regcache *regcache, __vsx_context_t *vsx)
 static void
 fetch_vsx_registers_aix (struct regcache *regcache)
 {
-  struct thrdentry64 thrdentry;
   __vsx_context_t vsx;
   pid_t pid = current_inferior ()->pid;
-  tid64_t  thrd_i = 0;
-
-  if (getthrds64(pid, &thrdentry, sizeof(struct thrdentry64),
-		 &thrd_i, 1) == 1)
-    thrd_i = thrdentry.ti_tid;
+  tid64_t thrd_i = get_thread_id (pid);
 
   memset(&vsx, 0, sizeof(__vsx_context_t));
   if (__power_vsx() && thrd_i > 0)
     {
-      if (ARCH64 ())
-	rs6000_ptrace64 (PTT_READ_VSX, thrd_i, (long long) &vsx, 0, 0);
-      else
-	rs6000_ptrace32 (PTT_READ_VSX, thrd_i, (int *) &vsx, 0, 0);
+      ptrace64 (PTT_READ_VSX, thrd_i, (long long) &vsx, 0, 0);
       supply_vsxregset_aix (regcache, &vsx);
     }
 }
 
 void rs6000_nat_target::post_startup_inferior (ptid_t ptid)
 {
-
   /* In AIX to turn on multi process debugging in ptrace
      PT_MULTI is the option to be passed,
      with the process ID which can fork () and
-     the data parameter [fourth parameter] must be 1.  */
+     the data parameter [fourth parameter] must be 1.  ptrace64 is
+     used for both 32-bit and 64-bit inferiors.  */
 
-  if (!ARCH64 ())
-    rs6000_ptrace32 (PT_MULTI, ptid.pid(), 0, 1, 0);
-  else
-    rs6000_ptrace64 (PT_MULTI, ptid.pid(), 0, 1, 0);
+  ptrace64 (PT_MULTI, ptid.pid (), 0, 1, 0);
 }
 
 void
@@ -477,10 +399,7 @@ rs6000_nat_target::follow_fork (inferior *child_inf, ptid_t child_ptid,
 
   if (detach_fork && !follow_child)
   {
-    if (ARCH64 ())
-      rs6000_ptrace64 (PT_DETACH, child_ptid.pid (), 0, 0, 0);
-    else
-      rs6000_ptrace32 (PT_DETACH, child_ptid.pid (), 0, 0, 0);
+    ptrace64 (PT_DETACH, child_ptid.pid (), 0, 0, 0);
   }
 }
 
@@ -528,7 +447,7 @@ fetch_register (struct regcache *regcache, int regno)
 
   /* Floating-point registers.  */
   if (isfloat)
-    rs6000_ptrace32 (PT_READ_FPR, pid, addr, nr, 0);
+    ptrace64 (PT_READ_FPR, pid, (long long) addr, nr, 0);
 
   /* Bogus register number.  */
   else if (nr < 0)
@@ -543,31 +462,24 @@ fetch_register (struct regcache *regcache, int regno)
   /* Fixed-point registers.  */
   else
     {
-      if (!ARCH64 ())
-	*addr = rs6000_ptrace32 (PT_READ_GPR, pid, (int *) nr, 0, 0);
-      else
+      if (ARCH64 ())
 	{
-	  /* PT_READ_GPR requires the buffer parameter to point to long long,
-	     even if the register is really only 32 bits.  */
+	  /* The buffer parameter must point to a long long area.  */
 	  long long buf;
-	  rs6000_ptrace64 (PT_READ_GPR, pid, nr, 0, &buf);
+	  ptrace64 (PT_READ_GPR, pid, nr, 0, (PTRACE_TYPE_ARG5) &buf);
 	  if (register_size (gdbarch, regno) == 8)
 	    memcpy (addr, &buf, 8);
 	  else
 	    *addr = buf;
 	}
+      else
+	*addr = ptrace64 (PT_READ_GPR, pid, nr, 0, 0);
     }
 
   if (!errno)
     regcache->raw_supply (regno, (char *) addr);
   else
-    {
-#if 0
-      /* FIXME: this happens 3 times at the start of each 64-bit program.  */
-      perror (_("ptrace read"));
-#endif
-      errno = 0;
-    }
+    errno = 0;
 }
 
 /* Store register REGNO back into the inferior.  */
@@ -602,7 +514,7 @@ store_register (struct regcache *regcache, int regno)
 
   /* Floating-point registers.  */
   if (isfloat)
-    rs6000_ptrace32 (PT_WRITE_FPR, pid, addr, nr, 0);
+    ptrace64 (PT_WRITE_FPR, pid, (long long) addr, nr, 0);
 
   /* Bogus register number.  */
   else if (nr < 0)
@@ -616,22 +528,18 @@ store_register (struct regcache *regcache, int regno)
   /* Fixed-point registers.  */
   else
     {
-      /* The PT_WRITE_GPR operation is rather odd.  For 32-bit inferiors,
-	 the register's value is passed by value, but for 64-bit inferiors,
-	 the address of a buffer containing the value is passed.  */
-      if (!ARCH64 ())
-	rs6000_ptrace32 (PT_WRITE_GPR, pid, (int *) nr, *addr, 0);
-      else
+      if (ARCH64 ())
 	{
-	  /* PT_WRITE_GPR requires the buffer parameter to point to an 8-byte
-	     area, even if the register is really only 32 bits.  */
+	  /* The buffer parameter must point to an 8-byte area.  */
 	  long long buf;
 	  if (register_size (gdbarch, regno) == 8)
 	    memcpy (&buf, addr, 8);
 	  else
 	    buf = *addr;
-	  rs6000_ptrace64 (PT_WRITE_GPR, pid, nr, 0, &buf);
+	  ptrace64 (PT_WRITE_GPR, pid, nr, 0, (PTRACE_TYPE_ARG5) &buf);
 	}
+      else
+	ptrace64 (PT_WRITE_GPR, pid, nr, *addr, 0);
     }
 
   if (errno)
@@ -760,7 +668,6 @@ rs6000_nat_target::xfer_partial (enum target_object object,
 				 ULONGEST *xfered_len)
 {
   pid_t pid = inferior_ptid.pid ();
-  int arch64 = ARCH64 ();
 
   switch (object)
     {
@@ -801,14 +708,8 @@ rs6000_nat_target::xfer_partial (enum target_object object,
 		    < rounded_offset + sizeof (PTRACE_TYPE_RET)))
 	      {
 		/* Need part of initial word -- fetch it.  */
-		if (arch64)
-		  buffer.word = rs6000_ptrace64 (PT_READ_I, pid,
-						 rounded_offset, 0, NULL);
-		else
-		  buffer.word = rs6000_ptrace32 (PT_READ_I, pid,
-						 (int *) (uintptr_t)
-						 rounded_offset,
-						 0, NULL);
+		buffer.word = ptrace64 (PT_READ_I, pid,
+					rounded_offset, 0, NULL);
 	      }
 
 	    /* Copy data to be written over corresponding part of
@@ -817,13 +718,8 @@ rs6000_nat_target::xfer_partial (enum target_object object,
 		    writebuf, partial_len);
 
 	    errno = 0;
-	    if (arch64)
-	      rs6000_ptrace64 (PT_WRITE_D, pid,
-			       rounded_offset, buffer.word, NULL);
-	    else
-	      rs6000_ptrace32 (PT_WRITE_D, pid,
-			       (int *) (uintptr_t) rounded_offset,
-			       buffer.word, NULL);
+	    ptrace64 (PT_WRITE_D, pid,
+		      rounded_offset, buffer.word, NULL);
 	    if (errno)
 	      return TARGET_XFER_EOF;
 	  }
@@ -831,13 +727,8 @@ rs6000_nat_target::xfer_partial (enum target_object object,
 	if (readbuf)
 	  {
 	    errno = 0;
-	    if (arch64)
-	      buffer.word = rs6000_ptrace64 (PT_READ_I, pid,
-					     rounded_offset, 0, NULL);
-	    else
-	      buffer.word = rs6000_ptrace32 (PT_READ_I, pid,
-					     (int *)(uintptr_t)rounded_offset,
-					     0, NULL);
+	    buffer.word = ptrace64 (PT_READ_I, pid,
+				    rounded_offset, 0, NULL);
 	    if (errno)
 	      return TARGET_XFER_EOF;
 
@@ -1014,12 +905,8 @@ rs6000_ptrace_ldinfo (ptid_t ptid)
 
   while (1)
     {
-      if (ARCH64 ())
-	rc = rs6000_ptrace64 (PT_LDINFO, pid, (unsigned long) ldi.data (),
-			      ldi.size (), NULL);
-      else
-	rc = rs6000_ptrace32 (PT_LDINFO, pid, (int *) ldi.data (),
-			      ldi.size (), NULL);
+      rc = ptrace64 (PT_LDINFO, pid, (long long) ldi.data (), ldi.size (),
+		     NULL);
 
       if (rc != -1)
 	break; /* Success, we got the entire ld_info data.  */
-- 
2.51.2


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v5 2/4] Remove obsolete getthrds and HAVE_PTRACE64 configure checks.
  2026-10-13 11:19 [PATCH v5 1/4] Remove stale legacy code from rs6000-aix-nat.c file Aditya Vidyadhar Kamath
@ 2026-10-13 11:19 ` Aditya Vidyadhar Kamath
  2026-10-13 11:19 ` [PATCH v5 3/4] Modernise aix-thread.c by combining ptrace wrappers Aditya Vidyadhar Kamath
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 12+ messages in thread
From: Aditya Vidyadhar Kamath @ 2026-10-13 11:19 UTC (permalink / raw)
  To: ulrich.weigand, simon.marchi, tom
  Cc: gdb-patches, Aditya.Kamath1, sangamesh.swamy, Aditya Vidyadhar Kamath

From: Aditya Vidyadhar Kamath <aditya.kamath1@ibm.com>

AIX 7.2 is the baseline supported AIX release.  On all supported AIX
releases, getthrds is declared in <procinfo.h>, and ptrace64 is declared
in <sys/ptrace.h> and defined in libc.a.  The configure checks for both
were added for older AIX versions that are no longer supported.

Remove AC_CHECK_DECLS (getthrds) from gdb/configure.ac and the
corresponding entry from gdb/config.in.  Remove the conditional extern
declaration in gdb/aix-thread.c that the check guarded.

Remove ptrace64 from the AC_CHECK_FUNCS list in gdbsupport/common.m4
and drop HAVE_PTRACE64 from all three config.in files.  In
gdb/aix-thread.c, remove the #ifdef HAVE_PTRACE64 guards; the ptracex
and ptrace wrapper macros now call ptrace64 unconditionally, and addr_ptr
is defined unconditionally as long long.

In gdb/nat/gdb_ptrace.h, remove the #ifdef HAVE_PTRACE64 guard and
always define the ptrace macro to call ptrace64 under PTRACE_TYPE_ARG5.
Also remove the stale HP-UX reference from the comment above that block.

No other files in the tree reference HAVE_PTRACE64 or HAVE_DECL_GETTHRDS
outside generated build files.  The gdb/configure, gdbserver/configure
and gdbsupport/configure scripts are regenerated from the updated .ac and
.m4 sources using autoconf 2.69.
---
 gdb/aix-thread.c     | 41 ++++++++++++-----------------------------
 gdb/config.in        |  7 -------
 gdb/configure        | 17 -----------------
 gdb/configure.ac     |  5 -----
 gdb/nat/gdb_ptrace.h | 20 +++++++-------------
 gdbserver/config.in  |  3 ---
 gdbserver/configure  |  1 -
 gdbsupport/common.m4 |  1 -
 gdbsupport/config.in |  3 ---
 gdbsupport/configure |  1 -
 10 files changed, 19 insertions(+), 80 deletions(-)

diff --git a/gdb/aix-thread.c b/gdb/aix-thread.c
index 869947b902f..7596bd844cf 100644
--- a/gdb/aix-thread.c
+++ b/gdb/aix-thread.c
@@ -1,4 +1,4 @@
-/* Low level interface for debugging AIX 4.3+ pthreads.
+/* Low level interface for debugging AIX 7.2+ pthreads.
 
    Copyright (C) 1999-2026 Free Software Foundation, Inc.
    Written by Nick Duffek <nsd@redhat.com>.
@@ -19,7 +19,7 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
-/* This module uses the libpthdebug.a library provided by AIX 4.3+ for
+/* This module uses the libpthdebug.a library provided by AIX 7.2+ for
    debugging pthread applications.
 
    Some name prefix conventions:
@@ -56,18 +56,9 @@
 #include <sys/pthdebug.h>
 #include <unordered_set>
 
-#if !HAVE_DECL_GETTHRDS
-extern int getthrds (pid_t, struct thrdsinfo64 *, int, tid_t *, int);
-#endif
-
 /* Whether to emit debugging output.  */
 static bool debug_aix_thread;
 
-/* In AIX 5.1, functions use pthdb_tid_t instead of tid_t.  */
-#ifndef PTHDB_VERSION_3
-#define pthdb_tid_t tid_t
-#endif
-
 /* Success and failure values returned by pthdb callbacks.  */
 
 #define PDC_SUCCESS PTHDB_SUCCESS
@@ -347,14 +338,10 @@ ptrace_check (int req, int id, int ret)
   return 0;  /* Not reached.  */
 }
 
-/* Call ptracex (REQ, ID, ADDR, DATA, BUF) or
-   ptrace64 (REQ, ID, ADDR, DATA, BUF) if HAVE_PTRACE64.
-   Return success.  */
+/* Call ptrace64 (REQ, ID, ADDR, DATA, BUF).  Return success.  */
 
-#ifdef HAVE_PTRACE64
-# define ptracex(request, pid, addr, data, buf) \
-	 ptrace64 (request, pid, addr, data, buf)
-#endif
+#define ptracex(request, pid, addr, data, buf) \
+     ptrace64 (request, pid, addr, data, buf)
 
 static int
 ptrace64aix (int req, int id, long long addr, int data, int *buf)
@@ -363,17 +350,13 @@ ptrace64aix (int req, int id, long long addr, int data, int *buf)
   return ptrace_check (req, id, ptracex (req, id, addr, data, buf));
 }
 
-/* Call ptrace (REQ, ID, ADDR, DATA, BUF) or
-   ptrace64 (REQ, ID, ADDR, DATA, BUF) if HAVE_PTRACE64.
-   Return success.  */
-
-#ifdef HAVE_PTRACE64
-# define ptrace(request, pid, addr, data, buf) \
-	 ptrace64 (request, pid, addr, data, buf)
-# define addr_ptr long long
-#else
-# define addr_ptr int *
-#endif
+/* On all supported AIX releases ptrace64 is available and addr is
+   always a long long.  addr_ptr is used as the type of the addr
+   parameter to ptrace32().  */
+
+#define ptrace(request, pid, addr, data, buf) \
+     ptrace64 (request, pid, addr, data, buf)
+#define addr_ptr long long
 
 static int
 ptrace32 (int req, int id, addr_ptr addr, int data, int *buf)
diff --git a/gdb/config.in b/gdb/config.in
index 0e5a6637c2b..dab7a3e7239 100644
--- a/gdb/config.in
+++ b/gdb/config.in
@@ -147,10 +147,6 @@
 /* Define to 1 if you have the declaration of `ffs', and to 0 if you don't. */
 #undef HAVE_DECL_FFS
 
-/* Define to 1 if you have the declaration of `getthrds', and to 0 if you
-   don't. */
-#undef HAVE_DECL_GETTHRDS
-
 /* Define to 1 if you have the declaration of `snprintf', and to 0 if you
    don't. */
 #undef HAVE_DECL_SNPRINTF
@@ -397,9 +393,6 @@
 /* Define to 1 if you have the `pthread_sigmask' function. */
 #undef HAVE_PTHREAD_SIGMASK
 
-/* Define to 1 if you have the `ptrace64' function. */
-#undef HAVE_PTRACE64
-
 /* Define if sys/ptrace.h defines the PTRACE_GETFPXREGS request. */
 #undef HAVE_PTRACE_GETFPXREGS
 
diff --git a/gdb/configure b/gdb/configure
index 810e9ed7a37..e0ecf0ef8d6 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -20321,7 +20321,6 @@ fi
     pipe \
     pipe2 \
     poll \
-    ptrace64 \
     sbrk \
     setns \
     setpgid \
@@ -31139,22 +31138,6 @@ $as_echo "$gdb_cv_have_aix_thread_debug" >&6; }
 	 CONFIG_SRCS="${CONFIG_SRCS} aix-thread.c"
 	 CONFIG_OBS="${CONFIG_OBS} aix-thread.o"
 	 LIBS="$LIBS -lpthdebug"
-
-	 # Older versions of AIX do not provide the declaration for
-	 # the getthrds function (it appears that it was introduced
-	 # with AIX 6.x).
-	 ac_fn_c_check_decl "$LINENO" "getthrds" "ac_cv_have_decl_getthrds" "#include <procinfo.h>
-"
-if test "x$ac_cv_have_decl_getthrds" = xyes; then :
-  ac_have_decl=1
-else
-  ac_have_decl=0
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_GETTHRDS $ac_have_decl
-_ACEOF
-
       fi
       ;;
    esac
diff --git a/gdb/configure.ac b/gdb/configure.ac
index 0d88a280b16..684ce8e21fb 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -1915,11 +1915,6 @@ if test "${build}" = "${host}" -a "${host}" = "${target}" ; then
 	 CONFIG_SRCS="${CONFIG_SRCS} aix-thread.c"
 	 CONFIG_OBS="${CONFIG_OBS} aix-thread.o"
 	 LIBS="$LIBS -lpthdebug"
-
-	 # Older versions of AIX do not provide the declaration for
-	 # the getthrds function (it appears that it was introduced
-	 # with AIX 6.x).
-	 AC_CHECK_DECLS(getthrds, [], [], [[#include <procinfo.h>]])
       fi
       ;;
    esac
diff --git a/gdb/nat/gdb_ptrace.h b/gdb/nat/gdb_ptrace.h
index e0607164260..c8ae89cd19e 100644
--- a/gdb/nat/gdb_ptrace.h
+++ b/gdb/nat/gdb_ptrace.h
@@ -121,21 +121,15 @@
 # endif
 #endif
 
-/* Some systems, at least AIX and HP-UX have a ptrace with five
-   arguments.  Since we never use the fifth argument, define a ptrace
-   macro that calls the real ptrace with the last argument set to
-   zero.  */
+/* AIX has a ptrace with five arguments.  Since we never use the fifth
+   argument, define a ptrace macro that calls ptrace64 with the last
+   argument set to zero.  */
 
 #ifdef PTRACE_TYPE_ARG5
-# ifdef HAVE_PTRACE64
-#  define ptrace(request, pid, addr, data) \
-	  ptrace64 (request, pid, addr, data, 0)
-#  undef PTRACE_TYPE_ARG3
-#  define PTRACE_TYPE_ARG3 long long
-# else
-#  define ptrace(request, pid, addr, data) \
-	  ptrace (request, pid, addr, data, 0)
-# endif
+# define ptrace(request, pid, addr, data) \
+      ptrace64 (request, pid, addr, data, 0)
+# undef PTRACE_TYPE_ARG3
+# define PTRACE_TYPE_ARG3 long long
 #else
 /* Wrapper that avoids adding a pointless cast to all callers.  */
 # define ptrace(request, pid, addr, data) \
diff --git a/gdbserver/config.in b/gdbserver/config.in
index ead66ce7a57..4223c68d4af 100644
--- a/gdbserver/config.in
+++ b/gdbserver/config.in
@@ -245,9 +245,6 @@
 /* Define to 1 if you have the `pthread_sigmask' function. */
 #undef HAVE_PTHREAD_SIGMASK
 
-/* Define to 1 if you have the `ptrace64' function. */
-#undef HAVE_PTRACE64
-
 /* Define if the target supports PTRACE_GETFPXREGS for extended register
    access. */
 #undef HAVE_PTRACE_GETFPXREGS
diff --git a/gdbserver/configure b/gdbserver/configure
index dd749fcb55b..327f3fec124 100755
--- a/gdbserver/configure
+++ b/gdbserver/configure
@@ -8525,7 +8525,6 @@ fi
     pipe \
     pipe2 \
     poll \
-    ptrace64 \
     sbrk \
     setns \
     setpgid \
diff --git a/gdbsupport/common.m4 b/gdbsupport/common.m4
index 6bf15fff670..bce8f19e803 100644
--- a/gdbsupport/common.m4
+++ b/gdbsupport/common.m4
@@ -71,7 +71,6 @@ AC_CHECK_HEADERS([ \
     pipe \
     pipe2 \
     poll \
-    ptrace64 \
     sbrk \
     setns \
     setpgid \
diff --git a/gdbsupport/config.in b/gdbsupport/config.in
index 2957ee0f030..321e1aaecf8 100644
--- a/gdbsupport/config.in
+++ b/gdbsupport/config.in
@@ -202,9 +202,6 @@
 /* Define to 1 if you have the `pthread_sigmask' function. */
 #undef HAVE_PTHREAD_SIGMASK
 
-/* Define to 1 if you have the `ptrace64' function. */
-#undef HAVE_PTRACE64
-
 /* Define to 1 if you have the <ptrace.h> header file. */
 #undef HAVE_PTRACE_H
 
diff --git a/gdbsupport/configure b/gdbsupport/configure
index 0bc9ff1db9a..df932c4c5dd 100755
--- a/gdbsupport/configure
+++ b/gdbsupport/configure
@@ -11424,7 +11424,6 @@ fi
     pipe \
     pipe2 \
     poll \
-    ptrace64 \
     sbrk \
     setns \
     setpgid \
-- 
2.51.2


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v5 3/4] Modernise aix-thread.c by combining ptrace wrappers.
  2026-10-13 11:19 [PATCH v5 1/4] Remove stale legacy code from rs6000-aix-nat.c file Aditya Vidyadhar Kamath
  2026-10-13 11:19 ` [PATCH v5 2/4] Remove obsolete getthrds and HAVE_PTRACE64 configure checks Aditya Vidyadhar Kamath
@ 2026-10-13 11:19 ` Aditya Vidyadhar Kamath
  2026-10-13 11:19 ` [PATCH v5 4/4] Fix 32-bit GPR and SPR register reads/writes in pthdb callbacks Aditya Vidyadhar Kamath
  2026-10-13 12:00 ` [PATCH v5 1/4] Remove stale legacy code from rs6000-aix-nat.c file Ulrich Weigand
  3 siblings, 0 replies; 12+ messages in thread
From: Aditya Vidyadhar Kamath @ 2026-10-13 11:19 UTC (permalink / raw)
  To: ulrich.weigand, simon.marchi, tom
  Cc: gdb-patches, Aditya.Kamath1, sangamesh.swamy, Aditya Vidyadhar Kamath

From: Aditya Vidyadhar Kamath <aditya.kamath1@ibm.com>

AIX 7.2 is now the minimum supported release.  64-bit GDB on AIX
always calls ptrace64, so remove 32-bit and 64-bit ptrace
wrappers.

Merge ptrace_check () into ptrace64aix ().  ptrace64aix () now calls
ptrace64 itself and handles the error cases directly, removing a layer
of indirection.

The VMX and VSX paths in pdc_read_regs () and pdc_write_regs () no
longer need separate arch64 branches, since both paths were already
identical after the ptrace32 () stub was made to call ptrace64.

Remove the struct ptsprs workaround in store_regs_kernel_thread ().
The fields were "unsigned long" up to AIX 5.2 but are "unsigned int"
on all supported releases.  fill_sprs32 () now writes straight into
sprs32 without temporaries.  The related comment and gdb_assert are
removed.

This cleanup also shows duplicated code between aix-thread.c and
rs6000-aix-nat.c (AltiVec/VSX supply and collect routines, and
GPR/FPR/SPR handling).  Moving it into shared AIX helpers is left for
a follow-up patch.

Testing

I ran the gdb.threads testsuite before and after this patch, from the
gdb/testsuite directory, with 64-bit and 32-bit test programs.

64-bit:

  gmake check RUNTESTFLAGS='--directory=gdb.threads \
    CC_FOR_TARGET="/opt/freeware/bin/gcc" \
    CXX_FOR_TARGET="/opt/freeware/bin/g++" \
    CXXFLAGS_FOR_TARGET="-O0 -w -g -gdwarf -maix64" \
    CFLAGS_FOR_TARGET="-O0 -w -g -gdwarf -maix64"'

32-bit (same command without -maix64):

  gmake check RUNTESTFLAGS='--directory=gdb.threads \
    CC_FOR_TARGET="/opt/freeware/bin/gcc" \
    CXX_FOR_TARGET="/opt/freeware/bin/g++" \
    CXXFLAGS_FOR_TARGET="-O0 -w -g -gdwarf" \
    CFLAGS_FOR_TARGET="-O0 -w -g -gdwarf"'

                              64-bit            32-bit
                          before  after     before  after
  expected passes           2125   2154       2138   2179
  unexpected failures        749    677        747    665
  expected failures            4      4          4      4
  known failures              20     20         20     20
  unresolved testcases         1      1          1      1
  untested testcases          10     13         11     13
  unsupported tests           84     81         83     83

The number of unexpected failures decreases in both modes.  The
failures that remain are pre-existing.  I grouped the 677 64-bit
failures by test file:

  Group                                    Failures  Test files
  ---------------------------------------  --------  -------------------
  Fork, vfork and exec with other          276       foll-fork-other-
    threads                                          thread (135),
                                                     vfork-multi-
                                                     inferior (43),
                                                     next-fork-exec-
                                                     other-thread (20),
                                                     next-fork-other-
                                                     thread (18), and
                                                     others
  Step-over, break-while-running,          231       detach-step-over
    signal and async                                 (52), multiple-
                                                     step-overs (38),
                                                     break-while-
                                                     running (22),
                                                     step-over-lands-
                                                     on-breakpoint (21),
                                                     async (6), and
                                                     others
  Inferior calls from breakpoint           102       infcall-from-bp-
    conditions                                       cond-other-thread-
                                                     event (32),
                                                     infcall-from-bp-
                                                     cond-timeout (24),
                                                     and others
  Multi-inferior and detach                 40       process-dies-while-
                                                     detaching (24),
                                                     threadapply (16)
  Thread-local storage                      14       tls (10), tls-core,
                                                     tls-var, tls-nodebug,
                                                     tls-nodebug-pie
  Other                                     14       pthreads (9),
                                                     threadcrash (3),
                                                     and others
  ---------------------------------------  --------
  Total                                    677

The 32-bit run has the same shape: 665 failures in the same test files.

One thing is scheduler lock on AIX is yet to be implemented and TLS
is work in progress.  Async related test cases have failures on AIX.
Detach has issues while working with multiple threads.

None of the failure categories above are related to the changes in
this patch.
---
 gdb/aix-thread.c | 224 +++++++++++------------------------------------
 1 file changed, 50 insertions(+), 174 deletions(-)

diff --git a/gdb/aix-thread.c b/gdb/aix-thread.c
index 7596bd844cf..795948424b2 100644
--- a/gdb/aix-thread.c
+++ b/gdb/aix-thread.c
@@ -295,13 +295,16 @@ pd_status2str (int status)
     }
 }
 
-/* A call to ptrace(REQ, ID, ...) just returned RET.  Check for
-   exceptional conditions and either return nonlocally or else return
-   1 for success and 0 for failure.  */
+/* Call ptrace64 (REQ, ID, ADDR, DATA, BUF).  Check for exceptional
+   conditions and either return nonlocally or else return 1 for success
+   and 0 for failure (or -1 where applicable).  */
 
 static int
-ptrace_check (int req, int id, int ret)
+ptrace64aix (int req, int id, long long addr, int data, int *buf)
 {
+  errno = 0;
+  int ret = ptrace64 (req, id, addr, data, buf);
+
   if (ret == 0 && !errno)
     return 1;
 
@@ -338,34 +341,6 @@ ptrace_check (int req, int id, int ret)
   return 0;  /* Not reached.  */
 }
 
-/* Call ptrace64 (REQ, ID, ADDR, DATA, BUF).  Return success.  */
-
-#define ptracex(request, pid, addr, data, buf) \
-     ptrace64 (request, pid, addr, data, buf)
-
-static int
-ptrace64aix (int req, int id, long long addr, int data, int *buf)
-{
-  errno = 0;
-  return ptrace_check (req, id, ptracex (req, id, addr, data, buf));
-}
-
-/* On all supported AIX releases ptrace64 is available and addr is
-   always a long long.  addr_ptr is used as the type of the addr
-   parameter to ptrace32().  */
-
-#define ptrace(request, pid, addr, data, buf) \
-     ptrace64 (request, pid, addr, data, buf)
-#define addr_ptr long long
-
-static int
-ptrace32 (int req, int id, addr_ptr addr, int data, int *buf)
-{
-  errno = 0;
-  return ptrace_check (req, id,
-		       ptrace (req, id, addr, data, buf));
-}
-
 /* If *PIDP is a composite process/thread id, convert it to a
    process id.  */
 
@@ -460,14 +435,13 @@ pdc_read_regs (pthdb_user_t user_current_pid,
     {
       if (data->arch64)
 	{
-	  if (!ptrace64aix (PTT_READ_GPRS, tid,
-			    (unsigned long) gprs64, 0, NULL))
+	  if (!ptrace64aix (PTT_READ_GPRS, tid, (long long) gprs64, 0, NULL))
 	    memset (gprs64, 0, sizeof (gprs64));
 	  memcpy (context->gpr, gprs64, sizeof (gprs64));
 	}
       else
 	{
-	  if (!ptrace32 (PTT_READ_GPRS, tid, (uintptr_t) gprs32, 0, NULL))
+	  if (!ptrace64aix (PTT_READ_GPRS, tid, (long long) gprs32, 0, NULL))
 	    memset (gprs32, 0, sizeof (gprs32));
 	  memcpy (context->gpr, gprs32, sizeof (gprs32));
 	}
@@ -476,7 +450,7 @@ pdc_read_regs (pthdb_user_t user_current_pid,
   /* Floating-point registers.  */
   if (flags & PTHDB_FLAG_FPRS)
     {
-      if (!ptrace32 (PTT_READ_FPRS, tid, (uintptr_t) fprs, 0, NULL))
+      if (!ptrace64aix (PTT_READ_FPRS, tid, (long long) fprs, 0, NULL))
 	memset (fprs, 0, sizeof (fprs));
       memcpy (context->fpr, fprs, sizeof (fprs));
     }
@@ -486,14 +460,13 @@ pdc_read_regs (pthdb_user_t user_current_pid,
     {
       if (data->arch64)
 	{
-	  if (!ptrace64aix (PTT_READ_SPRS, tid,
-			    (unsigned long) &sprs64, 0, NULL))
+	  if (!ptrace64aix (PTT_READ_SPRS, tid, (long long) &sprs64, 0, NULL))
 	    memset (&sprs64, 0, sizeof (sprs64));
 	  memcpy (&context->msr, &sprs64, sizeof (sprs64));
 	}
       else
 	{
-	  if (!ptrace32 (PTT_READ_SPRS, tid, (uintptr_t) &sprs32, 0, NULL))
+	  if (!ptrace64aix (PTT_READ_SPRS, tid, (long long) &sprs32, 0, NULL))
 	    memset (&sprs32, 0, sizeof (sprs32));
 	  memcpy (&context->msr, &sprs32, sizeof (sprs32));
 	}
@@ -503,36 +476,18 @@ pdc_read_regs (pthdb_user_t user_current_pid,
   __vmx_context_t vmx;
   if (__power_vmx () && (flags & PTHDB_FLAG_REGS))
     {
-      if (data->arch64)
-	{
-	  if (!ptrace64aix (PTT_READ_VEC, tid, (long long) &vmx, 0, 0))
-	    memset (&vmx, 0, sizeof (vmx));
-	  memcpy (&context->vmx, &vmx, sizeof (__vmx_context_t));
-	}
-      else
-	{
-	  if (!ptrace32 (PTT_READ_VEC, tid, (long long) &vmx, 0, 0))
-	    memset (&vmx, 0, sizeof (vmx));
-	  memcpy (&context->vmx, &vmx, sizeof (__vmx_context_t));
-	}
+      if (!ptrace64aix (PTT_READ_VEC, tid, (long long) &vmx, 0, 0))
+	memset (&vmx, 0, sizeof (vmx));
+      memcpy (&context->vmx, &vmx, sizeof (__vmx_context_t));
     }
 
   /* vsx registers.  */
   __vsx_context_t vsx;
   if (__power_vsx () && (flags & PTHDB_FLAG_REGS))
     {
-      if (data->arch64)
-	{
-	  if (!ptrace64aix (PTT_READ_VSX, tid, (long long) &vsx, 0, 0))
-	    memset (&vsx, 0, sizeof (vsx));
-	  memcpy (&context->vsx, &vsx, sizeof (__vsx_context_t));
-	}
-      else
-	{
-	  if (!ptrace32 (PTT_READ_VSX, tid, (long long) &vsx, 0, 0))
-	    memset (&vsx, 0, sizeof (vsx));
-	  memcpy (&context->vsx, &vsx, sizeof (__vsx_context_t));
-	}
+      if (!ptrace64aix (PTT_READ_VSX, tid, (long long) &vsx, 0, 0))
+	memset (&vsx, 0, sizeof (vsx));
+      memcpy (&context->vsx, &vsx, sizeof (__vsx_context_t));
     }
   return 0;
 }
@@ -553,61 +508,29 @@ pdc_write_regs (pthdb_user_t user_current_pid,
      this is needed, I have implemented what I think it should do,
      however this code is untested.  */
 
-  struct aix_thread_variables *data;
-
-  data = get_thread_data_helper_for_pid (user_current_pid);
-
   if (debug_aix_thread)
     gdb_printf (gdb_stdlog, "pdc_write_regs tid=%d flags=%s\n",
 		(int) tid, hex_string (flags));
 
   /* General-purpose registers.  */
   if (flags & PTHDB_FLAG_GPRS)
-    {
-      if (data->arch64)
-	ptrace64aix (PTT_WRITE_GPRS, tid,
-		     (unsigned long) context->gpr, 0, NULL);
-      else
-	ptrace32 (PTT_WRITE_GPRS, tid, (uintptr_t) context->gpr, 0, NULL);
-    }
+    ptrace64aix (PTT_WRITE_GPRS, tid, (long long) context->gpr, 0, NULL);
 
- /* Floating-point registers.  */
+  /* Floating-point registers.  */
   if (flags & PTHDB_FLAG_FPRS)
-    {
-      ptrace32 (PTT_WRITE_FPRS, tid, (uintptr_t) context->fpr, 0, NULL);
-    }
+    ptrace64aix (PTT_WRITE_FPRS, tid, (long long) context->fpr, 0, NULL);
 
   /* Special-purpose registers.  */
   if (flags & PTHDB_FLAG_SPRS)
-    {
-      if (data->arch64)
-	{
-	  ptrace64aix (PTT_WRITE_SPRS, tid,
-		       (unsigned long) &context->msr, 0, NULL);
-	}
-      else
-	{
-	  ptrace32 (PTT_WRITE_SPRS, tid, (uintptr_t) &context->msr, 0, NULL);
-	}
-    }
+    ptrace64aix (PTT_WRITE_SPRS, tid, (long long) &context->msr, 0, NULL);
 
   /* vector registers.  */
   if (__power_vmx () && (flags & PTHDB_FLAG_REGS))
-    {
-      if (data->arch64)
-	ptrace64aix (PTT_WRITE_VEC, tid, (unsigned long) &context->vmx, 0, 0);
-      else
-	ptrace32 (PTT_WRITE_VEC, tid, (uintptr_t) &context->vmx, 0, 0);
-    }
+    ptrace64aix (PTT_WRITE_VEC, tid, (long long) &context->vmx, 0, 0);
 
   /* vsx registers.  */
   if (__power_vsx () && (flags & PTHDB_FLAG_REGS))
-    {
-      if (data->arch64)
-	ptrace64aix (PTT_WRITE_VSX, tid, (unsigned long) &context->vsx, 0, 0);
-      else
-	ptrace32 (PTT_WRITE_VSX, tid, (uintptr_t) &context->vsx, 0, 0);
-    }
+    ptrace64aix (PTT_WRITE_VSX, tid, (long long) &context->vsx, 0, 0);
   return 0;
 }
 
@@ -1070,9 +993,6 @@ aix_thread_target::resume (ptid_t ptid, int step, enum gdb_signal sig)
 {
   struct thread_info *thread;
   pthdb_tid_t tid[2];
-  struct aix_thread_variables *data;
-
-  data = get_thread_data_helper_for_ptid (ptid);
 
   if (ptid.tid () == 0)
     {
@@ -1096,12 +1016,8 @@ aix_thread_target::resume (ptid_t ptid, int step, enum gdb_signal sig)
 	       ptid.lwp ());
       tid[1] = 0;
 
-      if (data->arch64)
-	ptrace64aix (PTT_CONTINUE, tid[0], (long long) 1,
-		     gdb_signal_to_host (sig), (PTRACE_TYPE_ARG5) tid);
-      else
-	ptrace32 (PTT_CONTINUE, tid[0], (addr_ptr) 1,
-		  gdb_signal_to_host (sig), (PTRACE_TYPE_ARG5) tid);
+      ptrace64aix (PTT_CONTINUE, tid[0], (long long) 1,
+		   gdb_signal_to_host (sig), (PTRACE_TYPE_ARG5) tid);
     }
 }
 
@@ -1375,14 +1291,13 @@ fetch_regs_kernel_thread (struct regcache *regcache, int regno,
     {
       if (data->arch64)
 	{
-	  if (!ptrace64aix (PTT_READ_GPRS, tid,
-			    (unsigned long) gprs64, 0, NULL))
+	  if (!ptrace64aix (PTT_READ_GPRS, tid, (long long) gprs64, 0, NULL))
 	    memset (gprs64, 0, sizeof (gprs64));
 	  supply_gprs64 (regcache, gprs64);
 	}
       else
 	{
-	  if (!ptrace32 (PTT_READ_GPRS, tid, (uintptr_t) gprs32, 0, NULL))
+	  if (!ptrace64aix (PTT_READ_GPRS, tid, (long long) gprs32, 0, NULL))
 	    memset (gprs32, 0, sizeof (gprs32));
 	  for (i = 0; i < ppc_num_gprs; i++)
 	    supply_reg32 (regcache, tdep->ppc_gp0_regnum + i, gprs32[i]);
@@ -1394,10 +1309,7 @@ fetch_regs_kernel_thread (struct regcache *regcache, int regno,
     {
       int ret = 0;
       __vmx_context_t vmx;
-      if (data->arch64)
-	ret = ptrace64aix (PTT_READ_VEC, tid, (long long) &vmx, 0, 0);
-      else
-	ret = ptrace32 (PTT_READ_VEC, tid, (uintptr_t) &vmx, 0, 0);
+      ret = ptrace64aix (PTT_READ_VEC, tid, (long long) &vmx, 0, 0);
       if (ret < 0)
 	memset (&vmx, 0, sizeof (__vmx_context_t));
       for (i = 0; i < ppc_num_vrs; i++)
@@ -1411,10 +1323,7 @@ fetch_regs_kernel_thread (struct regcache *regcache, int regno,
     {
       __vsx_context_t vsx;
       int ret = 0;
-      if (data->arch64)
-	ret = ptrace64aix (PTT_READ_VSX, tid, (long long) &vsx, 0, 0);
-      else
-	ret = ptrace32 (PTT_READ_VSX, tid, (long long) &vsx, 0, 0);
+      ret = ptrace64aix (PTT_READ_VSX, tid, (long long) &vsx, 0, 0);
       if (ret < 0)
 	memset (&vsx, 0, sizeof (__vsx_context_t));
       for (i = 0; i < ppc_num_vshrs; i++)
@@ -1428,7 +1337,7 @@ fetch_regs_kernel_thread (struct regcache *regcache, int regno,
 	  || (regno >= tdep->ppc_fp0_regnum
 	      && regno < tdep->ppc_fp0_regnum + ppc_num_fprs)))
     {
-      if (!ptrace32 (PTT_READ_FPRS, tid, (uintptr_t) fprs, 0, NULL))
+      if (!ptrace64aix (PTT_READ_FPRS, tid, (long long) fprs, 0, NULL))
 	memset (fprs, 0, sizeof (fprs));
       supply_fprs (regcache, fprs);
     }
@@ -1439,8 +1348,7 @@ fetch_regs_kernel_thread (struct regcache *regcache, int regno,
     {
       if (data->arch64)
 	{
-	  if (!ptrace64aix (PTT_READ_SPRS, tid,
-			    (unsigned long) &sprs64, 0, NULL))
+	  if (!ptrace64aix (PTT_READ_SPRS, tid, (long long) &sprs64, 0, NULL))
 	    memset (&sprs64, 0, sizeof (sprs64));
 	  supply_sprs64 (regcache, sprs64.pt_iar, sprs64.pt_msr,
 			 sprs64.pt_cr, sprs64.pt_lr, sprs64.pt_ctr,
@@ -1448,7 +1356,7 @@ fetch_regs_kernel_thread (struct regcache *regcache, int regno,
 	}
       else
 	{
-	  if (!ptrace32 (PTT_READ_SPRS, tid, (uintptr_t) &sprs32, 0, NULL))
+	  if (!ptrace64aix (PTT_READ_SPRS, tid, (long long) &sprs32, 0, NULL))
 	    memset (&sprs32, 0, sizeof (sprs32));
 	  supply_sprs32 (regcache, sprs32.pt_iar, sprs32.pt_msr, sprs32.pt_cr,
 			 sprs32.pt_lr, sprs32.pt_ctr, sprs32.pt_xer,
@@ -1803,16 +1711,16 @@ store_regs_kernel_thread (const struct regcache *regcache, int regno,
       if (data->arch64)
 	{
 	  /* Pre-fetch: some regs may not be in the cache.  */
-	  ptrace64aix (PTT_READ_GPRS, tid, (unsigned long) gprs64, 0, NULL);
+	  ptrace64aix (PTT_READ_GPRS, tid, (long long) gprs64, 0, NULL);
 	  fill_gprs64 (regcache, gprs64);
-	  ptrace64aix (PTT_WRITE_GPRS, tid, (unsigned long) gprs64, 0, NULL);
+	  ptrace64aix (PTT_WRITE_GPRS, tid, (long long) gprs64, 0, NULL);
 	}
       else
 	{
 	  /* Pre-fetch: some regs may not be in the cache.  */
-	  ptrace32 (PTT_READ_GPRS, tid, (uintptr_t) gprs32, 0, NULL);
+	  ptrace64aix (PTT_READ_GPRS, tid, (long long) gprs32, 0, NULL);
 	  fill_gprs32 (regcache, gprs32);
-	  ptrace32 (PTT_WRITE_GPRS, tid, (uintptr_t) gprs32, 0, NULL);
+	  ptrace64aix (PTT_WRITE_GPRS, tid, (long long) gprs32, 0, NULL);
 	}
     }
 
@@ -1824,9 +1732,9 @@ store_regs_kernel_thread (const struct regcache *regcache, int regno,
 	      && regno < tdep->ppc_fp0_regnum + ppc_num_fprs)))
     {
       /* Pre-fetch: some regs may not be in the cache.  */
-      ptrace32 (PTT_READ_FPRS, tid, (uintptr_t) fprs, 0, NULL);
+      ptrace64aix (PTT_READ_FPRS, tid, (long long) fprs, 0, NULL);
       fill_fprs (regcache, fprs);
-      ptrace32 (PTT_WRITE_FPRS, tid, (uintptr_t) fprs, 0, NULL);
+      ptrace64aix (PTT_WRITE_FPRS, tid, (long long) fprs, 0, NULL);
     }
 
   /* Special-purpose registers.  */
@@ -1836,47 +1744,27 @@ store_regs_kernel_thread (const struct regcache *regcache, int regno,
       if (data->arch64)
 	{
 	  /* Pre-fetch: some registers won't be in the cache.  */
-	  ptrace64aix (PTT_READ_SPRS, tid,
-		       (unsigned long) &sprs64, 0, NULL);
+	  ptrace64aix (PTT_READ_SPRS, tid, (long long) &sprs64, 0, NULL);
 	  fill_sprs64 (regcache, &sprs64.pt_iar, &sprs64.pt_msr,
 		       &sprs64.pt_cr, &sprs64.pt_lr, &sprs64.pt_ctr,
 		       &sprs64.pt_xer, &sprs64.pt_fpscr);
-	  ptrace64aix (PTT_WRITE_SPRS, tid,
-		       (unsigned long) &sprs64, 0, NULL);
+	  ptrace64aix (PTT_WRITE_SPRS, tid, (long long) &sprs64, 0, NULL);
 	}
       else
 	{
-	  /* The contents of "struct ptspr" were declared as "unsigned
-	     long" up to AIX 5.2, but are "unsigned int" since 5.3.
-	     Use temporaries to work around this problem.  Also, add an
-	     assert here to make sure we fail if the system header files
-	     use "unsigned long", and the size of that type is not what
-	     the headers expect.  */
-	  uint32_t tmp_iar, tmp_msr, tmp_cr, tmp_lr, tmp_ctr, tmp_xer,
-		   tmp_fpscr;
-
-	  gdb_assert (sizeof (sprs32.pt_iar) == 4);
-
 	  /* Pre-fetch: some registers won't be in the cache.  */
-	  ptrace32 (PTT_READ_SPRS, tid, (uintptr_t) &sprs32, 0, NULL);
-
-	  fill_sprs32 (regcache, &tmp_iar, &tmp_msr, &tmp_cr, &tmp_lr,
-		       &tmp_ctr, &tmp_xer, &tmp_fpscr);
+	  ptrace64aix (PTT_READ_SPRS, tid, (long long) &sprs32, 0, NULL);
 
-	  sprs32.pt_iar = tmp_iar;
-	  sprs32.pt_msr = tmp_msr;
-	  sprs32.pt_cr = tmp_cr;
-	  sprs32.pt_lr = tmp_lr;
-	  sprs32.pt_ctr = tmp_ctr;
-	  sprs32.pt_xer = tmp_xer;
-	  sprs32.pt_fpscr = tmp_fpscr;
+	  fill_sprs32 (regcache, &sprs32.pt_iar, &sprs32.pt_msr, &sprs32.pt_cr,
+		       &sprs32.pt_lr, &sprs32.pt_ctr, &sprs32.pt_xer,
+		       &sprs32.pt_fpscr);
 
 	  if (tdep->ppc_mq_regnum >= 0)
 	    if (REG_VALID == regcache->get_register_status
 		(tdep->ppc_mq_regnum))
 	      regcache->raw_collect (tdep->ppc_mq_regnum, &sprs32.pt_mq);
 
-	  ptrace32 (PTT_WRITE_SPRS, tid, (uintptr_t) &sprs32, 0, NULL);
+	  ptrace64aix (PTT_WRITE_SPRS, tid, (long long) &sprs32, 0, NULL);
 	}
     }
 
@@ -1889,17 +1777,11 @@ store_regs_kernel_thread (const struct regcache *regcache, int regno,
       __vmx_context_t vmx;
       if (__power_vmx ())
 	{
-	  if (data->arch64)
-	    ret = ptrace64aix (PTT_READ_VEC, tid, (long long) &vmx, 0, 0);
-	  else
-	    ret = ptrace32 (PTT_READ_VEC, tid, (long long) &vmx, 0, 0);
+	  ret = ptrace64aix (PTT_READ_VEC, tid, (long long) &vmx, 0, 0);
 	  if (ret > 0)
 	    {
 	      fill_altivec (regcache, &vmx);
-	      if (data->arch64)
-		ret = ptrace64aix (PTT_WRITE_VEC, tid, (long long) &vmx, 0, 0);
-	      else
-		ret = ptrace32 (PTT_WRITE_VEC, tid, (long long) &vmx, 0, 0);
+	      ret = ptrace64aix (PTT_WRITE_VEC, tid, (long long) &vmx, 0, 0);
 	      if (ret < 0)
 		perror_with_name (_("Unable to store AltiVec register after read"));
 	    }
@@ -1915,17 +1797,11 @@ store_regs_kernel_thread (const struct regcache *regcache, int regno,
       __vsx_context_t vsx;
       if (__power_vsx ())
 	{
-	  if (data->arch64)
-	    ret = ptrace64aix (PTT_READ_VSX, tid, (long long) &vsx, 0, 0);
-	  else
-	    ret = ptrace32 (PTT_READ_VSX, tid, (long long) &vsx, 0, 0);
+	  ret = ptrace64aix (PTT_READ_VSX, tid, (long long) &vsx, 0, 0);
 	  if (ret > 0)
 	    {
 	      fill_vsx (regcache, &vsx);
-	      if (data->arch64)
-		ret = ptrace64aix (PTT_WRITE_VSX, tid, (long long) &vsx, 0, 0);
-	      else
-		ret = ptrace32 (PTT_WRITE_VSX, tid, (long long) &vsx, 0, 0);
+	      ret = ptrace64aix (PTT_WRITE_VSX, tid, (long long) &vsx, 0, 0);
 	      if (ret < 0)
 		perror_with_name (_("Unable to store VSX register after read"));
 	    }
-- 
2.51.2


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v5 4/4] Fix 32-bit GPR and SPR register reads/writes in pthdb callbacks.
  2026-10-13 11:19 [PATCH v5 1/4] Remove stale legacy code from rs6000-aix-nat.c file Aditya Vidyadhar Kamath
  2026-10-13 11:19 ` [PATCH v5 2/4] Remove obsolete getthrds and HAVE_PTRACE64 configure checks Aditya Vidyadhar Kamath
  2026-10-13 11:19 ` [PATCH v5 3/4] Modernise aix-thread.c by combining ptrace wrappers Aditya Vidyadhar Kamath
@ 2026-10-13 11:19 ` Aditya Vidyadhar Kamath
  2026-10-13 12:00 ` [PATCH v5 1/4] Remove stale legacy code from rs6000-aix-nat.c file Ulrich Weigand
  3 siblings, 0 replies; 12+ messages in thread
From: Aditya Vidyadhar Kamath @ 2026-10-13 11:19 UTC (permalink / raw)
  To: ulrich.weigand, simon.marchi, tom
  Cc: gdb-patches, Aditya.Kamath1, sangamesh.swamy, Aditya Vidyadhar Kamath

From: Aditya Vidyadhar Kamath <aditya.kamath1@ibm.com>

pdc_read_regs reads GPRs into a uint32_t[32] local array when the
thread is 32-bit, then copies it into pthdb_context_t::gpr which is
uint64_t[32].  The memcpy treated the uint32_t[] data as if it were
already uint64_t, so each 32-bit value was silently widened with
whatever happened to be adjacent in memory.  Replace the memcpy with
an element-wise assignment so each value is correctly zero-extended.

pdc_read_regs also reads the 32-bit SPR set into a struct ptsprs and
copies it with memcpy into &context->msr.  The field order in struct
ptsprs is iar, msr, cr, lr, ctr, xer, mq, while pthdb_context_t
has msr, iar, lr, ctr, cr, xer, fpscr, fpscrx, mq.  The memcpy
therefore wrote every SPR into the wrong context field and corrupted
the fields that follow msr.  Replace the memcpy with explicit
field-by-field assignments.

pdc_write_regs has the symmetric bugs for the write direction.  Add
the arch64 branch that was missing for GPRs and SPRs:

  64-bit: pass context->gpr / &context->msr directly.
  32-bit GPRs: truncate each context->gpr[i] (uint64_t) into a local
    uint32_t gprs32[] array, then call ptrace64aix.
  32-bit SPRs: pre-fetch the current struct ptsprs to preserve any
    reserved fields, fill in the named fields from the context, then
    call ptrace64aix.

Also reword the "untested" comment in both pdc_read_regs and
pdc_write_regs.  The callbacks do not appear to be invoked during
normal debugging, but they must be registered: without them the OS
refuses to initialise the pthdb session and several thread-debug
functions fail.

Note: pt_mq in struct ptsprs is the legacy Multiply/Quotient register
from the original POWER architecture.  It is present in the struct on
all supported AIX releases and is included for completeness.
---
 gdb/aix-thread.c | 69 ++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 55 insertions(+), 14 deletions(-)

diff --git a/gdb/aix-thread.c b/gdb/aix-thread.c
index 795948424b2..f732f5167ff 100644
--- a/gdb/aix-thread.c
+++ b/gdb/aix-thread.c
@@ -411,11 +411,10 @@ pdc_read_regs (pthdb_user_t user_current_pid,
 	       unsigned long long flags,
 	       pthdb_context_t *context)
 {
-  /* This function doesn't appear to be used, so we could probably
-   just return 0 here.  HOWEVER, if it is not defined, the OS will
-   complain and several thread debug functions will fail.  In case
-   this is needed, I have implemented what I think it should do,
-   however this code is untested.  */
+  /* This function does not appear to be called during normal debugging,
+     but it must be registered: if the callback is absent the OS refuses
+     to initialise the pthdb session and several thread-debug functions
+     fail.  */
 
   uint64_t gprs64[ppc_num_gprs];
   uint32_t gprs32[ppc_num_gprs];
@@ -443,7 +442,8 @@ pdc_read_regs (pthdb_user_t user_current_pid,
 	{
 	  if (!ptrace64aix (PTT_READ_GPRS, tid, (long long) gprs32, 0, NULL))
 	    memset (gprs32, 0, sizeof (gprs32));
-	  memcpy (context->gpr, gprs32, sizeof (gprs32));
+	  for (int i = 0; i < ppc_num_gprs; i++)
+	    context->gpr[i] = gprs32[i];
 	}
     }
 
@@ -468,7 +468,15 @@ pdc_read_regs (pthdb_user_t user_current_pid,
 	{
 	  if (!ptrace64aix (PTT_READ_SPRS, tid, (long long) &sprs32, 0, NULL))
 	    memset (&sprs32, 0, sizeof (sprs32));
-	  memcpy (&context->msr, &sprs32, sizeof (sprs32));
+	  context->iar = sprs32.pt_iar;
+	  context->msr = sprs32.pt_msr;
+	  context->cr = sprs32.pt_cr;
+	  context->lr = sprs32.pt_lr;
+	  context->ctr = sprs32.pt_ctr;
+	  context->xer = sprs32.pt_xer;
+	  context->fpscr = sprs32.pt_fpscr;
+	  context->fpscrx = sprs32.pt_fpscrx;
+	  context->mq = sprs32.pt_mq;
 	}
     }
 
@@ -502,11 +510,13 @@ pdc_write_regs (pthdb_user_t user_current_pid,
 		unsigned long long flags,
 		pthdb_context_t *context)
 {
-  /* This function doesn't appear to be used, so we could probably
-     just return 0 here.  HOWEVER, if it is not defined, the OS will
-     complain and several thread debug functions will fail.  In case
-     this is needed, I have implemented what I think it should do,
-     however this code is untested.  */
+  /* This function does not appear to be called during normal debugging,
+     but it must be registered: if the callback is absent the OS refuses
+     to initialise the pthdb session and several thread-debug functions
+     fail.  */
+
+  struct aix_thread_variables *data;
+  data = get_thread_data_helper_for_pid (user_current_pid);
 
   if (debug_aix_thread)
     gdb_printf (gdb_stdlog, "pdc_write_regs tid=%d flags=%s\n",
@@ -514,7 +524,17 @@ pdc_write_regs (pthdb_user_t user_current_pid,
 
   /* General-purpose registers.  */
   if (flags & PTHDB_FLAG_GPRS)
-    ptrace64aix (PTT_WRITE_GPRS, tid, (long long) context->gpr, 0, NULL);
+    {
+      if (data->arch64)
+	ptrace64aix (PTT_WRITE_GPRS, tid, (long long) context->gpr, 0, NULL);
+      else
+	{
+	  uint32_t gprs32[ppc_num_gprs];
+	  for (int i = 0; i < ppc_num_gprs; i++)
+	    gprs32[i] = context->gpr[i];
+	  ptrace64aix (PTT_WRITE_GPRS, tid, (long long) gprs32, 0, NULL);
+	}
+    }
 
   /* Floating-point registers.  */
   if (flags & PTHDB_FLAG_FPRS)
@@ -522,7 +542,28 @@ pdc_write_regs (pthdb_user_t user_current_pid,
 
   /* Special-purpose registers.  */
   if (flags & PTHDB_FLAG_SPRS)
-    ptrace64aix (PTT_WRITE_SPRS, tid, (long long) &context->msr, 0, NULL);
+    {
+      if (data->arch64)
+	ptrace64aix (PTT_WRITE_SPRS, tid, (long long) &context->msr, 0, NULL);
+      else
+	{
+	  struct ptsprs sprs32;
+
+	  /* Pre-fetch so the reserved fields are preserved.  */
+	  if (!ptrace64aix (PTT_READ_SPRS, tid, (long long) &sprs32, 0, NULL))
+	    memset (&sprs32, 0, sizeof (sprs32));
+	  sprs32.pt_iar = context->iar;
+	  sprs32.pt_msr = context->msr;
+	  sprs32.pt_cr = context->cr;
+	  sprs32.pt_lr = context->lr;
+	  sprs32.pt_ctr = context->ctr;
+	  sprs32.pt_xer = context->xer;
+	  sprs32.pt_fpscr = context->fpscr;
+	  sprs32.pt_fpscrx = context->fpscrx;
+	  sprs32.pt_mq = context->mq;	/* MQ is legacy; present in ptsprs.  */
+	  ptrace64aix (PTT_WRITE_SPRS, tid, (long long) &sprs32, 0, NULL);
+	}
+    }
 
   /* vector registers.  */
   if (__power_vmx () && (flags & PTHDB_FLAG_REGS))
-- 
2.51.2


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v5 1/4] Remove stale legacy code from rs6000-aix-nat.c file.
  2026-10-13 11:19 [PATCH v5 1/4] Remove stale legacy code from rs6000-aix-nat.c file Aditya Vidyadhar Kamath
                   ` (2 preceding siblings ...)
  2026-10-13 11:19 ` [PATCH v5 4/4] Fix 32-bit GPR and SPR register reads/writes in pthdb callbacks Aditya Vidyadhar Kamath
@ 2026-10-13 12:00 ` Ulrich Weigand
  2026-10-13 12:55   ` Aditya Kamath
  3 siblings, 1 reply; 12+ messages in thread
From: Ulrich Weigand @ 2026-10-13 12:00 UTC (permalink / raw)
  To: Aditya Vidyadhar Kamath, simon.marchi, tom
  Cc: gdb-patches, Aditya Kamath, SANGAMESH MALLAYYA

Aditya Vidyadhar Kamath <akamath996@gmail.com> wrote:

>                              64-bit            32-bit
>                          before  after     before  after
>  expected passes          41792  41802      41687  41541
>  unexpected failures       2346   2343       2302   2294
>  unexpected successes         1      1          1      1
>  expected failures           17     17         15     15
>  known failures              30     30         30     30
>  unresolved testcases        30     29         11     86

I'm a bit concerned about the significant increase of
unresolved testcases on 32-bit.  This might indicate that
some of the assumptions about the behavior of ptrace64
with 32-bit inferiors could be inaccurate.

Can you look into the root cause of those unresolved cases?

Thanks,
Ulrich

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v5 1/4] Remove stale legacy code from rs6000-aix-nat.c file.
  2026-10-13 12:00 ` [PATCH v5 1/4] Remove stale legacy code from rs6000-aix-nat.c file Ulrich Weigand
@ 2026-10-13 12:55   ` Aditya Kamath
  2026-10-13 13:31     ` Ulrich Weigand
  0 siblings, 1 reply; 12+ messages in thread
From: Aditya Kamath @ 2026-10-13 12:55 UTC (permalink / raw)
  To: Ulrich Weigand, Aditya Vidyadhar Kamath, simon.marchi, tom
  Cc: gdb-patches, SANGAMESH MALLAYYA

[-- Attachment #1: Type: text/plain, Size: 3726 bytes --]

Hi Ulrich and community members,

>>                              64-bit            32-bit
>>                          before  after     before  after
>>  expected passes          41792  41802      41687  41541
>>  unexpected failures       2346   2343       2302   2294
>>  unexpected successes         1      1          1      1
>>  expected failures           17     17         15     15
>>  known failures              30     30         30     30
>>  unresolved testcases        30     29         11     86

>I'm a bit concerned about the significant increase of
>unresolved testcases on 32-bit.  This might indicate that
>some of the assumptions about the behavior of ptrace64
>with 32-bit inferiors could be inaccurate.

>Can you look into the root cause of those unresolved cases?


I looked at the 32-bit results from the post-patch run (gdb.base-32.log). The increase in unresolved testcases doesn't look related to ptrace64 or 32-bit inferior handling.


Of the 86 unresolved testcases, 75 come from a single test file, gdb.base/shell.exp. The other 11 are one each from attach, bp-cmds-continue-ctrl-c, execl-update-breakpoints, gdb-sigterm, interrupt-daemon-attach, jit-bfd-name, jit-elf-fork, jit-elf, longjmp-until-in-main, longjmp and tls-nothreads.


That is the same count as the baseline run, and the same set that shows up in the 64-bit log, so the whole increase comes from shell.exp.

The first pipe test in that file, "|p 123| exit 0", failed with:

      ERROR: GDB process no longer exists

      GDB process exited with wait status ... CHILDKILLED SIGPIPE

      UNRESOLVED: gdb.base/shell.exp: |p 123| exit 0


Once GDB died, every later test in the file failed with "Couldn't send ... to GDB". That accounts the 75 unresolved results and most of the drop in expected passes.


The likely cause is in pipe_command in gdb/cli/cli-cmds.c. It uses popen (<args>, "w") and writes the command output to the child. In this test the child command is simply exit 0. If it exits before GDB writes, the write raises SIGPIPE and GDB itself exits. Unlike some other code paths (for example gdb/compile/compile.c), pipe_command doesn't use scoped_ignore_sigpipe.


Also, shell.exp runs without a program loaded, so it doesn't exercise any code changed by the aix-thread or rs6000-aix-nat patches.


 I was also able to reproduce the race manually by running the equivalent command in a loop, from the gdb build directory:

      for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20;

            do

                  printf 'pipe p 123 | exit 0\nquit\n' | ./gdb -q -nx >/dev/null 2>&1

                  echo "$?”

            done

One of the 20 runs exited with status 141 (128 + SIGPIPE), and the other 19 exited with 0.


Here is the output:

0 0 0 0 0 0 0 0 0 0 0 0 141 0 0 0 0 0 0 0

I also re-ran shell.exp alone six times, from gdb/testsuite:

 gmake check RUNTESTFLAGS="gdb.base/shell.exp"


Results were the same in all six runs:

 # of expected passes 112

 # of unexpected failures 4


There were no unresolved results in any of the six runs. The 4 unexpected failures were the "shell interrupt" and "pipe interrupt" exitcode/exitsignal tests, which use "kill -2 $$". I haven't investigated why they fail on AIX. They are not related to this series.


Therefore, this appears to be a pre-existing race in pipe_command rather than an effect of this patch series.

Let me know if you need more details.

Thanks and regards,

Aditya.

[-- Attachment #2: Type: text/html, Size: 18714 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v5 1/4] Remove stale legacy code from rs6000-aix-nat.c file.
  2026-10-13 12:55   ` Aditya Kamath
@ 2026-10-13 13:31     ` Ulrich Weigand
  2026-10-13 17:16       ` Simon Marchi
  0 siblings, 1 reply; 12+ messages in thread
From: Ulrich Weigand @ 2026-10-13 13:31 UTC (permalink / raw)
  To: Aditya Kamath, Aditya Vidyadhar Kamath, simon.marchi, tom
  Cc: gdb-patches, SANGAMESH MALLAYYA

Aditya Kamath <Aditya.Kamath1@ibm.com> wrote:

>Therefore, this appears to be a pre-existing race inpipe_command
>rather than an effect of this patch series.

Interesting, thanks for double-checking.  I agree that this seems
unrelated to the current patch series then.

Bye,
Ulrich

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v5 1/4] Remove stale legacy code from rs6000-aix-nat.c file.
  2026-10-13 13:31     ` Ulrich Weigand
@ 2026-10-13 17:16       ` Simon Marchi
  2026-10-14  9:15         ` Aditya Kamath
  0 siblings, 1 reply; 12+ messages in thread
From: Simon Marchi @ 2026-10-13 17:16 UTC (permalink / raw)
  To: Ulrich Weigand, Aditya Kamath, Aditya Vidyadhar Kamath, tom
  Cc: gdb-patches, SANGAMESH MALLAYYA

On 10/13/26 9:31 AM, Ulrich Weigand wrote:
> Aditya Kamath <Aditya.Kamath1@ibm.com> wrote:
> 
>> Therefore, this appears to be a pre-existing race inpipe_command
>> rather than an effect of this patch series.
> 
> Interesting, thanks for double-checking.  I agree that this seems
> unrelated to the current patch series then.
> 
> Bye,
> Ulrich

Thanks for digging into the pipe issue, it is indeed reproducible on
Linux.  Please see this small 2-patch series that hopefully fixes it for
you too and makes testing less noisy

https://inbox.sourceware.org/gdb-patches/20261013171340.1748775-1-simon.marchi@efficios.com/T/#m50cf93bf2bbe1a9fd9c7ac7237519570df8a5ceb

Simon

^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: [PATCH v5 1/4] Remove stale legacy code from rs6000-aix-nat.c file.
  2026-10-13 17:16       ` Simon Marchi
@ 2026-10-14  9:15         ` Aditya Kamath
  2026-10-14 10:44           ` Ulrich Weigand
  0 siblings, 1 reply; 12+ messages in thread
From: Aditya Kamath @ 2026-10-14  9:15 UTC (permalink / raw)
  To: Simon Marchi, Ulrich Weigand, Aditya Vidyadhar Kamath, tom
  Cc: gdb-patches, SANGAMESH MALLAYYA

[-- Attachment #1: Type: text/plain, Size: 1499 bytes --]


Hi Simon,

>Thanks for digging into the pipe issue, it is indeed reproducible on
>Linux.  Please see this small 2-patch series that hopefully fixes it for
>you too and makes testing less noisy

>https://urldefense.proofpoint.com/v2/url?u=https-3A__inbox.sourceware.org_gdb-2Dpatches_20261013171340.1748775-2D1-2Dsimon.marchi-40efficios.com_T_-23m50cf93bf2bbe1a9fd9c7ac7237519570df8a5ceb&d=DwICaQ&c=BSDicqBQBDjDI9RkVyTcHQ&r=f-oUQ8ByG1nZ71OI9p76qywCPh7mxzU69hBYnkP9Nis&m=a00eP242E_D4VAASU_j8zMu2t_Vf29AIAghQEZll_XzeU_APW-TVoCat0riBcaj3&s=82cvPgaYrtuANiE_ZnSQXU71WChpKrAdgNMXzRKKCwg&e=

Thanks for the patch.

I re-ran the full gdb.base testsuite in 32-bit mode with your
patches applied.  Here are the 32-bit numbers from before my series,
after my series, and after my series plus your patches:

                          32-bit
                                    before   after    after + your patches
  expected passes             41687   41541    41640
  unexpected failures         2302    2294     2308
  unexpected successes           1       1        1
  expected failures                     15      15       15
  known failures                   30      30       30
  unresolved testcases            11      86       11
  untested testcases           107     107      108
  unsupported tests             179     179      178


Will give more information in that patch thread.

Have a nice day ahead.

Regards,
Aditya.

[-- Attachment #2: Type: text/html, Size: 6118 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v5 1/4] Remove stale legacy code from rs6000-aix-nat.c file.
  2026-10-14  9:15         ` Aditya Kamath
@ 2026-10-14 10:44           ` Ulrich Weigand
  2026-10-15 13:38             ` Aditya Kamath
  0 siblings, 1 reply; 12+ messages in thread
From: Ulrich Weigand @ 2026-10-14 10:44 UTC (permalink / raw)
  To: Aditya Kamath, Simon Marchi, Aditya Vidyadhar Kamath, tom
  Cc: gdb-patches, SANGAMESH MALLAYYA

Aditya Kamath <Aditya.Kamath1@ibm.com> wrote:

>                          32-bit
>                                    before   after    after + your
patches
>  expected passes             41687   41541    41640
>  unexpected failures         2302    2294     2308
>  unexpected successes           1       1        1
>  expected failures                     15      15       15
>  known failures                   30      30       30
>  unresolved testcases            11      86       11
>  untested testcases           107     107      108
>  unsupported tests             179     179      178

That looks better, thanks!   It is still surprising to see
the differences in untested vs. unsupported tests - do you
know what this is about?

Also it is slightly concerning to see the increase in
unexpected failures - is this caused by different sets
of tests being run, or just noise?

Bye,
Ulrich

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v5 1/4] Remove stale legacy code from rs6000-aix-nat.c file.
  2026-10-14 10:44           ` Ulrich Weigand
@ 2026-10-15 13:38             ` Aditya Kamath
  2026-10-15 14:37               ` Ulrich Weigand
  0 siblings, 1 reply; 12+ messages in thread
From: Aditya Kamath @ 2026-10-15 13:38 UTC (permalink / raw)
  To: Ulrich Weigand, Simon Marchi, Aditya Vidyadhar Kamath, tom
  Cc: gdb-patches, SANGAMESH MALLAYYA

[-- Attachment #1: Type: text/plain, Size: 4923 bytes --]

Hi Ulrich and community members,

>>                          32-bit
>>                                    before   after    after + your
patches
>>  expected passes             41687   41541    41640
>>  unexpected failures         2302    2294     2308
>>  unexpected successes           1       1        1
>>  expected failures                     15      15       15
>>  known failures                   30      30       30
>>  unresolved testcases            11      86       11
>>  untested testcases           107     107      108
>>  unsupported tests             179     179      178

>That looks better, thanks!   It is still surprising to see
>the differences in untested vs. unsupported tests - do you
>know what this is about?

>Also it is slightly concerning to see the increase in
>unexpected failures - is this caused by different sets
>of tests being run, or just noise?

I git fetched and git merged my repository this morning since there were commits made like here<https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=bf842a2e8d6e9eb7429444904b1b31c8b85d5fb2> that can change the numbers.

Here are the new numbers.  "before" is without the v5 aix-thread patches,
"after" is with them.  Both columns include the fixes below (wchar,
shell.exp, bigcore, filename-completion).

                          64-bit            32-bit
                          before  after     before  after
  expected passes          41820  41828      41629  41628
  unexpected failures       2341   2338       2294   2295
  unexpected successes         1      1          1      1
  expected failures           17     17         15     15
  known failures              30     30         30     30
  unresolved testcases        16     16         11     11
  untested testcases         105    105        108    108
  unsupported tests          179    179        179    179

What changed since the last numbers:

 1: wchar.exp crashed GDB in 64-bit.  The AIX target used UTF-16 as the
    wide charset while wchar_t is 4 bytes in 64-bit mode, so
    wide strings were decoded wrongly and GDB hit a SIGSEGV on the next
    print.  64-bit now uses UTF-32.  This removed 15 of the
    unresolved results.
 2: shell.exp: accepts ksh88's exit (130) for the "kill -2 $$" tests, which
    fixed the 4 interrupt failures.
 3: bigcore.exp and filename-completion.exp are skipped on AIX.

I will be sending a patch for all 3 soon. These 3 patches are the reason the numbers are as above.

 Regarding the UNTESTED:  Of the 105 (64-bit) / 108 (32-bit), 83 / 84 are build or   link failures on AIX, mostly shared-library builds (ld: 0706-005 and "cannot open
 as COFF file").  7 are "memory at address 0 is possibly executable”, 2 are "can't generate a core file", and the others are missing compiler or tool features (__float128, _FloatN, stap probes, gdb index).

Regarding the UNSUPPORTED: the test needs something AIX target does not have.  Of the 179, 71 are "require failed" (Linux-only features, Python, hardware watchpoints, displaced stepping), 20 are "non-stop mode not supported", and 8 are "address zero is readable".

Both kinds reflect AIX limits.  The 32-bit run has 3 more untested than the 64-bit run: longest-types and the two ptype-offsets tests, which only run on lp64.

Regarding the unexpected failures -  The count is noise from timing-dependent tests, not a regression which is summarized as below :

 - 32-bit: 2294 -> 2295.  No test name that appears in both runs changes
   status.  The extra failure is in vfork-follow-parent, whose failing
   names change from run to run (suffixes such as "(timeout)" and "(the
   program is no longer running)").
 - 64-bit: 2341 -> 2338.  The only changes are in vfork-follow-parent
   (47 -> 44 FAILs) and gdb-sigterm (1 -> 0), plus a multi-forks swap
   (detach 4 and detach 5 swap PASS/FAIL, 50 FAILs in both runs).
 - The FAIL counts per test file are identical, except for those two files in
   64-bit.  The attach, foll-fork, sigstep and bg-exec families have the same
   FAIL counts before and after the patches.
 - About 100 FAILs in each run are "(timeout)": 107/106 in 64-bit,
   98/97 in 32-bit.  They are in the fork, vfork and attach tests.
 - The largest sources of failures are the same in every run and
   are unrelated to the patches: whatis-ptype-typedefs (1062),
   max-depth-c++ (91), nodebug (89), align-c++ (70), sigstep (60).


I hope this answers the questions. Based on these results, none of the observed differences appear to be related to this patch series. Please let me know if you would like me to investigate any of the remaining differences in more detail. I will update the numbers in patch 1/4 before the next revision if there are no further concerns.

Have a nice day ahead.

Thanks and regards,
Aditya.



[-- Attachment #2: Type: text/html, Size: 14608 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v5 1/4] Remove stale legacy code from rs6000-aix-nat.c file.
  2026-10-15 13:38             ` Aditya Kamath
@ 2026-10-15 14:37               ` Ulrich Weigand
  0 siblings, 0 replies; 12+ messages in thread
From: Ulrich Weigand @ 2026-10-15 14:37 UTC (permalink / raw)
  To: Aditya Kamath, Simon Marchi, Aditya Vidyadhar Kamath, tom
  Cc: gdb-patches, SANGAMESH MALLAYYA

Aditya Kamath <Aditya.Kamath1@ibm.com> wrote:

>I hope this answers the questions. Based on these results, none of the
>observed differences appear to be related to this patch series. Please
>let me know if you would like me to investigate any of the remaining
>differences in more detail. I will update the numbers in patch 1/4
>before the next revision if there are no further concerns.

Thanks for the detailed analysis.  I agree that with these numbers
there should be no cause for concern about this patch series.

Any follow-on effort to further improve the test suite results
can certainly be done separately.

Bye,
Ulrich

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2026-10-15 14:38 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-13 11:19 [PATCH v5 1/4] Remove stale legacy code from rs6000-aix-nat.c file Aditya Vidyadhar Kamath
2026-10-13 11:19 ` [PATCH v5 2/4] Remove obsolete getthrds and HAVE_PTRACE64 configure checks Aditya Vidyadhar Kamath
2026-10-13 11:19 ` [PATCH v5 3/4] Modernise aix-thread.c by combining ptrace wrappers Aditya Vidyadhar Kamath
2026-10-13 11:19 ` [PATCH v5 4/4] Fix 32-bit GPR and SPR register reads/writes in pthdb callbacks Aditya Vidyadhar Kamath
2026-10-13 12:00 ` [PATCH v5 1/4] Remove stale legacy code from rs6000-aix-nat.c file Ulrich Weigand
2026-10-13 12:55   ` Aditya Kamath
2026-10-13 13:31     ` Ulrich Weigand
2026-10-13 17:16       ` Simon Marchi
2026-10-14  9:15         ` Aditya Kamath
2026-10-14 10:44           ` Ulrich Weigand
2026-10-15 13:38             ` Aditya Kamath
2026-10-15 14:37               ` Ulrich Weigand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox