public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Aditya Kamath1 <Aditya.Kamath1@ibm.com>
To: Ulrich Weigand <Ulrich.Weigand@de.ibm.com>,
	Aditya Kamath1 via Gdb-patches <gdb-patches@sourceware.org>
Cc: Alan Modra <amodra@au1.ibm.com>, Alan Modra <amodra@gmail.com>,
	Sangamesh Mallayya <sangamesh.swamy@in.ibm.com>
Subject: [Patch] Fix AIX shared library load broken during fork ().
Date: Mon, 10 Jul 2023 11:35:09 +0000	[thread overview]
Message-ID: <CH2PR15MB354471EE8BAD9701059162D7D630A@CH2PR15MB3544.namprd15.prod.outlook.com> (raw)


[-- Attachment #1.1: Type: text/plain, Size: 9651 bytes --]

Respected Ulrich and GDB community members,

Hi,

Please find attached a patch. {See: 0001-Fix-AIX-shared-library-load-broken-during-fork.patch}
This is a patch to fix the loading of the shared library during the fork () event.

In the recent commit {https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=de7b90610e9e939c49290229c282eb9171c560b9} the committer mentions that he has added a add_range () function which now adds a start, end range which now guards anyone from calling or having two or more file pointer pointing to the same file in the archive. So, if this is the case, then we BFD goes to execute the following condition
+  if (bfd_seek (abfd, (namlen & 1) + SXCOFFARFMAG, SEEK_CUR) != 0
+      || !add_range (abfd, start, abfd->where + ret->parsed_size))
+    {
+      free (ret);
+      return NULL;
+    }


We will satisy the add_range () part of the OR condition and free the ret variable and return NULL. Kindly note this happens in the coff-rs6000.c file in bfd directory.

As an impact of this in our GDB code in solib-aix.c file during a fork () event, after the parent shared libraries are loaded and the child shared library in going to be loaded, when GDB executes the line.
gdb_bfd_ref_ptr object_bfd
    (gdb_bfd_openr_next_archived_file (archive_bfd.get (), NULL));

in search of the object file in the archive, but object_bfd we receive is NULL. Then the while (object_bfd != NULL) does not satisfy and we cannot load the shared the library.

As result in AIX for Example code 1 {pasted below this email}  we see the output as shown below.

------------------------------------------------------------------------------------------------------------------------------------
bash-5.1$ ./gdb ~/gdb_tests/multi-thread-fork
GNU gdb (GDB) 14.0.50.20230602-git
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "powerpc64-ibm-aix7.2.0.0".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
https://www.gnu.org/software/gdb/bugs/.
Find the GDB manual and other documentation resources online at:
    http://www.gnu.org/software/gdb/documentation/.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /home/aditya/gdb_tests/multi-thread-fork...
(gdb) set detach-on-fork off
(gdb) r
Starting program: /home/aditya/gdb_tests/multi-thread-fork
[New Thread 258]
[New Thread 515]
[New inferior 2 (process 25166094)]
warning: "/usr/lib/libpthreads.a": member "shr_comm.o" missing.
warning: "/usr/lib/libpthread.a": member "shr_xpg5.o" missing.
warning: "/usr/lib/libc.a": member "shr.o" missing.
warning: Could not load shared library symbols for 3 libraries, e.g. /usr/lib/libpthreads.a(shr_comm.o).
Use the "info sharedlibrary" command to see the complete listing.
Do you need "set solib-search-path" or "set sysroot"?
I am parent
[New process 10551700]
[New inferior 3 (process 9306438)]
warning: "/usr/lib/libpthreads.a": member "shr_comm.o" missing.
warning: "/usr/lib/libpthread.a": member "shr_xpg5.o" missing.
warning: "/usr/lib/libc.a": member "shr.o" missing.
warning: Could not load shared library symbols for 3 libraries, e.g. /usr/lib/libpthreads.a(shr_comm.o).
Use the "info sharedlibrary" command to see the complete listing.
Do you need "set solib-search-path" or "set sysroot"?
I am parent

Thread 1.4 received signal SIGINT, Interrupt.
[Switching to process 10551700]
0xd0595fb0 in _p_nsleep () from /usr/lib/libpthread.a(shr_xpg5.o)
(gdb) inferior 2
[Switching to inferior 2 [process 25166094] (/home/aditya/gdb_tests/multi-thread-fork)]
[Switching to thread 2.1 (process 25166094)]
#0  0xd0594fc8 in ?? ()
(gdb) info sharedlibrary
From        To          Syms Read   Shared Object Library
                        No          /usr/lib/libpthreads.a(shr_comm.o)
0xd05bb240  0xd05bb9a1  Yes (*)     /usr/lib/libcrypt.a(shr.o)
                        No          /usr/lib/libpthread.a(shr_xpg5.o)
                        No          /usr/lib/libc.a(shr.o)
(*): Shared library is missing debugging information.
(gdb)

------------------------------------------------------------------------------------------------------------------------------------
So, what I tried in this patch is to keep the pointers pointing to a shared object file stored in a vector and when BFD does not find any object file use the already stored pointer pointing to the shared object for the new inferior.

After applying the patch, the output is as below:-

------------------------------------------------------------------------------------------------------------------------------------
bash-5.1$ ./gdb ~/gdb_tests/multi-thread-fork
GNU gdb (GDB) 14.0.50.20230602-git
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "powerpc64-ibm-aix7.2.0.0".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
https://www.gnu.org/software/gdb/bugs/.
Find the GDB manual and other documentation resources online at:
    http://www.gnu.org/software/gdb/documentation/.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /home/aditya/gdb_tests/multi-thread-fork...
(gdb) set detach-on-fork off
(gdb) r
Starting program: /home/aditya/gdb_tests/multi-thread-fork
[New Thread 258]
[New Thread 515]
[New inferior 2 (process 27984338)]
[New process 10551730]
[New inferior 3 (process 28049732)]
I am parent
I am parent

Thread 1.4 received signal SIGINT, Interrupt.
[Switching to process 10551730]
0xd0595fb0 in _p_nsleep () from /usr/lib/libpthread.a(shr_xpg5.o)
(gdb) inferior 2
[Switching to inferior 2 [process 27984338] (/home/aditya/gdb_tests/multi-thread-fork)]
[Switching to thread 2.1 (process 27984338)]
#0  0xd0594fc8 in _sigsetmask () from /usr/lib/libpthread.a(shr_xpg5.o)
(gdb) info sharedlibrary
From        To          Syms Read   Shared Object Library
0xd05bc124  0xd05bf194  Yes (*)     /usr/lib/libpthreads.a(shr_comm.o)
0xd05bb240  0xd05bb9a1  Yes (*)     /usr/lib/libcrypt.a(shr.o)
0xd0576180  0xd05ba731  Yes (*)     /usr/lib/libpthread.a(shr_xpg5.o)
0xd0100dc0  0xd0575123  Yes (*)     /usr/lib/libcrypt.a(shr.o)
(*): Shared library is missing debugging information.
(gdb) info threads
  Id   Target Id                          Frame
  1.1  Thread 1 (tid 25625035, running)   0xd0595fb0 in _p_nsleep () from /usr/lib/libpthread.a(shr_xpg5.o)
  1.2  Thread 258 (tid 39256515, running) thread_function (arg=0x0) at /home/aditya/gdb_tests/multi-thread-fork.c:27
  1.3  Thread 515 (tid 35193173, running) thread_function (arg=warning: (Internal error: pc 0x0 in read in psymtab, but not in symtab.)

0x0) at /home/aditya/gdb_tests/multi-thread-fork.c:27
  1.4  process 10551730                   0xd0595fb0 in _p_nsleep () from /usr/lib/libpthread.a(shr_xpg5.o)
* 2.1  process 27984338                   0xd0594fc8 in _sigsetmask () from /usr/lib/libpthread.a(shr_xpg5.o)
  3.1  process 28049732                   0xd0594fc8 in _sigsetmask () from /usr/lib/libpthread.a(shr_xpg5.o)
------------------------------------------------------------------------------------------------------------------------------------

So, the idea was almost close to solving it but still at distance from it. But I see that the parent process 10551730 which was a thread target is now reflecting as a process target as an impact of the same. In fact, the thread target is being set correctly for the parent process while I debugged the issue.

So, I currently, do not know why this target mismatch has happened and is it because of using the same pointers for the child process as well.

Since you are all experts, kindly guide me on where my analysis has gone wrong and what we can do to fix this issue. Also kindly review this patch.

Waiting for a reply,

Have a nice day ahead.

Thanks and regards,
Aditya.


------------------------------------------------------------------------------------------------------------------------------------
Example Code 1:-

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <assert.h>

pthread_barrier_t barrier;

#define NUM_THREADS 2

void *
thread_function (void *arg)
{
  /* This ensures that the breakpoint is only hit after both threads
     are created, so the test can always switch to the non-event
     thread when the breakpoint triggers.  */

  pthread_barrier_wait (&barrier);
  pid_t child;

  child = fork ();
  if (child > 0)
    printf ("I am parent \n");
  else
    printf (" Iam child \n");

  while (1); /* break here */
}

int
main (void)
{
  int i;

  alarm (300);

  pthread_barrier_init (&barrier, NULL, NUM_THREADS);

  for (i = 0; i < NUM_THREADS; i++)
    {
      pthread_t thread;
      int res;

      res = pthread_create (&thread, NULL,
                            thread_function, NULL);
      assert (res == 0);
    }

  while (1)
    sleep (1);

  return 0;
}

[-- Attachment #2: 0001-Fix-AIX-shared-library-load-broken-during-fork.patch --]
[-- Type: application/octet-stream, Size: 2820 bytes --]

From dfbe9cdf99f33267a1ccf30e8f8725f40835d7c9 Mon Sep 17 00:00:00 2001
From: Aditya Vidyadhar Kamath <Aditya.Kamath1@ibm.com>
Date: Mon, 10 Jul 2023 05:57:02 -0500
Subject: [PATCH] Fix AIX shared library load broken during fork ().

This patch is a fix to the AIX shared library not loading
for a new inferior during a fork () event.  The reason being in
AIX we archive shared libraries and we are not allowed to have many
pointers pointing to the same archive file as per a recent commit in bfd.

So we keep track of every pointer pointing to a shared object in an archive
such that the new inferior can reuse them.
---
 gdb/solib-aix.c | 39 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 37 insertions(+), 2 deletions(-)

diff --git a/gdb/solib-aix.c b/gdb/solib-aix.c
index 93aa6c4e040..00c12a6e314 100644
--- a/gdb/solib-aix.c
+++ b/gdb/solib-aix.c
@@ -29,6 +29,15 @@
 #include "gdbcmd.h"
 #include "gdbsupport/scope-exit.h"
 
+/* Vector to keep the pointer to object in an archive.  */
+
+/* Once accessed we are not able to refer the same object
+   with a different pointer due to add_range () in bfd.
+   So we maintain the pointers in this vector to access
+   them during every shared library load for a new inferior.  */
+
+std::vector<gdb_bfd_ref_ptr> object_bfd_vector;
+
 /* Our private data in struct so_list.  */
 
 struct lm_info_aix : public lm_info_base
@@ -605,10 +614,33 @@ solib_aix_bfd_open (const char *pathname)
 
   gdb_bfd_ref_ptr object_bfd
     (gdb_bfd_openr_next_archived_file (archive_bfd.get (), NULL));
+  if (object_bfd == NULL)
+    {
+      auto it = object_bfd_vector.begin ();
+      while (it != object_bfd_vector.end ())
+	{
+	  gdb_bfd_ref_ptr object_bfd_tmp = *it;
+	  std::string s = bfd_get_filename (object_bfd_tmp.get ());
+	  if (s.find ('(') != std::string::npos)
+	    {
+	      int pos = s.find ('(');
+	      int len = s.find (')') - s.find ('(');
+	      /* For a new inferior which cannot access the file in 
+		 its parent would be having a pointer to the same
+		 file, we will return the parent's bdf ref ptr.  */
+	      if (s.substr (pos+1, len-1) == member_name)
+		return object_bfd_tmp;
+	    }
+	  it++;
+	}
+    }
   while (object_bfd != NULL)
     {
       if (member_name == bfd_get_filename (object_bfd.get ()))
-	break;
+	{
+	  object_bfd_vector.push_back (object_bfd);
+	  break;
+	}
 
       std::string s = bfd_get_filename (object_bfd.get ());
 
@@ -621,7 +653,10 @@ solib_aix_bfd_open (const char *pathname)
 	  int pos = s.find ('(');
 	  int len = s.find (')') - s.find ('(');
 	  if (s.substr (pos+1, len-1) == member_name)
-	    return object_bfd;
+	    {
+	      object_bfd_vector.push_back (object_bfd);
+	      return object_bfd;
+	    }
 	}
 
       object_bfd = gdb_bfd_openr_next_archived_file (archive_bfd.get (),
-- 
2.38.3


             reply	other threads:[~2023-07-10 11:35 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-10 11:35 Aditya Kamath1 [this message]
2023-07-10 14:11 ` Alan Modra
2023-07-10 14:29   ` Aditya Kamath1
2023-07-10 15:04     ` Alan Modra
2023-07-10 16:00 ` Tom Tromey
2023-07-10 23:17   ` Alan Modra
2023-07-11  5:08     ` Aditya Kamath1

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CH2PR15MB354471EE8BAD9701059162D7D630A@CH2PR15MB3544.namprd15.prod.outlook.com \
    --to=aditya.kamath1@ibm.com \
    --cc=Ulrich.Weigand@de.ibm.com \
    --cc=amodra@au1.ibm.com \
    --cc=amodra@gmail.com \
    --cc=gdb-patches@sourceware.org \
    --cc=sangamesh.swamy@in.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).