Respected Alan, Ulrich, Tom and community members, Hi and Morning, >The proper place to fix this of course is in bfd. Aditya, I think the >following ought to cure the problem you're seeing. Did you open a PR? > * coff-rs6000.c (add_range): Revise comment, noting possible fail. > (_bfd_xcoff_openr_next_archived_file): Start with clean ranges. Yes, this fixes the issue. Kindly see the output pasted below this email. No, I have not opened a PR. And I also did not apply any changes I had made which I had mentioned in my first email of this thread. I only applied your changes in coff-rs6000.c .. Thank you for figuring this out. Also, let me know if you would like me to open a PR. Usually I attach the git format patch. Whichever works for you. So I think this is good to commit from our end. Thank you Alan and community for your support once again. Thank you Tom for your suggestion to not write unfreeable global vectors. Will keep it in mind for the upcoming patches soon. Have a nice day ahead. Thanks and regards, Aditya. 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 27132274)] [New inferior 3 (process 22020358)] I am parent I am parent Thread 1.1 received signal SIGINT, Interrupt. 0xd0595fb0 in _p_nsleep () from /usr/lib/libpthread.a(shr_xpg5.o) (gdb) inferior 2 [Switching to inferior 2 [process 27132274] (/home/aditya/gdb_tests/multi-thread-fork)] [Switching to thread 2.1 (process 27132274)] #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) 0xd0100e00 0xd0575123 Yes (*) /usr/lib/libc.a(shr.o) (*): Shared library is missing debugging information. (gdb) inferior 3 [Switching to inferior 3 [process 22020358] (/home/aditya/gdb_tests/multi-thread-fork)] [Switching to thread 3.1 (process 22020358)] #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) 0xd0100e00 0xd0575123 Yes (*) /usr/lib/libc.a(shr.o) (*): Shared library is missing debugging information. (gdb) q A debugging session is active. Inferior 1 [process 18350382] will be killed. Inferior 2 [process 27132274] will be killed. Inferior 3 [process 22020358] will be killed. Quit anyway? (y or n) y bash-5.1$ bash-5.1$ diff -u ../bfd/coff-rs6000.c_orig ../bfd/coff-rs6000.c --- ../bfd/coff-rs6000.c_orig 2023-07-10 09:20:47.209312912 +0000 +++ ../bfd/coff-rs6000.c 2023-07-10 23:54:41.714469979 +0000 @@ -1770,12 +1770,14 @@ { if (last_file == NULL) { + /* If we are scanning over elements twice in an open archive, + which can happen in gdb after a fork, ensure we start the + second scan with clean ranges. */ + x_artdata (archive)->ranges.start = 0; + x_artdata (archive)->ranges.end = SIZEOF_AR_FILE_HDR; + x_artdata (archive)->ranges.next = NULL; + x_artdata (archive)->ar_hdr_size = SIZEOF_AR_HDR; filestart = bfd_ardata (archive)->first_file_filepos; - if (x_artdata (archive)->ar_hdr_size == 0) - { - x_artdata (archive)->ranges.end = SIZEOF_AR_FILE_HDR; - x_artdata (archive)->ar_hdr_size = SIZEOF_AR_HDR; - } } else GET_VALUE_IN_FIELD (filestart, arch_xhdr (last_file)->nextoff, 10); @@ -1794,12 +1796,11 @@ { if (last_file == NULL) { + x_artdata (archive)->ranges.start = 0; + x_artdata (archive)->ranges.end = SIZEOF_AR_FILE_HDR_BIG; + x_artdata (archive)->ranges.next = NULL; + x_artdata (archive)->ar_hdr_size = SIZEOF_AR_HDR_BIG; filestart = bfd_ardata (archive)->first_file_filepos; - if (x_artdata (archive)->ar_hdr_size == 0) - { - x_artdata (archive)->ranges.end = SIZEOF_AR_FILE_HDR_BIG; - x_artdata (archive)->ar_hdr_size = SIZEOF_AR_HDR_BIG; - } } else GET_VALUE_IN_FIELD (filestart, arch_xhdr_big (last_file)->nextoff, 10); bash-5.1$ cat ~/gdb_tests/multi-thread-fork.c #include #include #include #include #include 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; } From: Alan Modra Date: Tuesday, 11 July 2023 at 4:47 AM To: Tom Tromey Cc: Aditya Kamath1 via Gdb-patches , Ulrich Weigand , Aditya Kamath1 , Alan Modra , Sangamesh Mallayya Subject: [EXTERNAL] Re: [Patch] Fix AIX shared library load broken during fork (). On Mon, Jul 10, 2023 at 10:00:40AM -0600, Tom Tromey wrote: > >>>>> Aditya Kamath1 via Gdb-patches writes: > > > +std::vector object_bfd_vector; > > I think it's a mistake to add a new global like this. > It seems to me that this would interact poorly with multi-inferior or > multi-target debugging. > > Also, since nothing ever clears the vector, these BFDs will never be > closed. The proper place to fix this of course is in bfd. Aditya, I think the following ought to cure the problem you're seeing. Did you open a PR? * coff-rs6000.c (add_range): Revise comment, noting possible fail. (_bfd_xcoff_openr_next_archived_file): Start with clean ranges. diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c index 271a24fff69..59b9743356f 100644 --- a/bfd/coff-rs6000.c +++ b/bfd/coff-rs6000.c @@ -1598,14 +1598,21 @@ _bfd_xcoff_archive_p (bfd *abfd) /* Track file ranges occupied by elements. Add [START,END) to the list of ranges and return TRUE if there is no overlap between the - new and any other element or the archive file header. Note that - this would seem to preclude calling _bfd_get_elt_at_filepos twice - for the same element, but we won't get to _bfd_xcoff_read_ar_hdr if - an element is read more than once. See _bfd_get_elt_at_filepos use - of _bfd_look_for_bfd_in_cache. Also, the xcoff archive code + new and any other element or the archive file header. This relies + on _bfd_xcoff_read_ar_hdr not being called more than once for the + same element, but that should be true (*). The xcoff archive code doesn't call _bfd_read_ar_hdr when reading the armap, nor does it need to use extended name tables. So those other routines in - archive.c that call _bfd_read_ar_hdr are unused. */ + archive.c that call _bfd_read_ar_hdr are unused. + + *) There is one case where this might fail, but I think it is + sufficently unusual that it doesn't seem worth fixing: When + scanning over archive elements using openr_next_archived_file, if + openr_next_archived_file is called twice with the same arguments + *and* the element returned is bfd_close'd between those calls then + we'll return false here. The _bfd_look_for_bfd_in_cache use in + _bfd_get_elt_at_filepos stops this happening in the case where an + element is not closed. */ static bool add_range (bfd *abfd, ufile_ptr start, ufile_ptr end) @@ -1770,12 +1777,14 @@ _bfd_xcoff_openr_next_archived_file (bfd *archive, bfd *last_file) { if (last_file == NULL) { + /* If we are scanning over elements twice in an open archive, + which can happen in gdb after a fork, ensure we start the + second scan with clean ranges. */ + x_artdata (archive)->ranges.start = 0; + x_artdata (archive)->ranges.end = SIZEOF_AR_FILE_HDR; + x_artdata (archive)->ranges.next = NULL; + x_artdata (archive)->ar_hdr_size = SIZEOF_AR_HDR; filestart = bfd_ardata (archive)->first_file_filepos; - if (x_artdata (archive)->ar_hdr_size == 0) - { - x_artdata (archive)->ranges.end = SIZEOF_AR_FILE_HDR; - x_artdata (archive)->ar_hdr_size = SIZEOF_AR_HDR; - } } else GET_VALUE_IN_FIELD (filestart, arch_xhdr (last_file)->nextoff, 10); @@ -1794,12 +1803,11 @@ _bfd_xcoff_openr_next_archived_file (bfd *archive, bfd *last_file) { if (last_file == NULL) { + x_artdata (archive)->ranges.start = 0; + x_artdata (archive)->ranges.end = SIZEOF_AR_FILE_HDR_BIG; + x_artdata (archive)->ranges.next = NULL; + x_artdata (archive)->ar_hdr_size = SIZEOF_AR_HDR_BIG; filestart = bfd_ardata (archive)->first_file_filepos; - if (x_artdata (archive)->ar_hdr_size == 0) - { - x_artdata (archive)->ranges.end = SIZEOF_AR_FILE_HDR_BIG; - x_artdata (archive)->ar_hdr_size = SIZEOF_AR_HDR_BIG; - } } else GET_VALUE_IN_FIELD (filestart, arch_xhdr_big (last_file)->nextoff, 10); -- Alan Modra Australia Development Lab, IBM