* Solibs and objfile BFD ownership
@ 2009-07-28 15:40 Daniel Jacobowitz
2009-07-29 23:56 ` Paul Pluzhnikov
0 siblings, 1 reply; 13+ messages in thread
From: Daniel Jacobowitz @ 2009-07-28 15:40 UTC (permalink / raw)
To: Paul Pluzhnikov, gdb
I'm seeing ARM test failures caused by this patch:
2009-03-05 Paul Pluzhnikov <ppluzhnikov@google.com>
* printcmd.c (do_one_display): Reparse exp_string.
(display_uses_solib_p): New function.
(clear_dangling_display_expressions): New function.
(_initialize_printcmd): Add observer.
* solib.c (no_shared_libraries): Swap order of calls to
clear_solib and objfile_purge_solibs.
Specifically this bit:
/* The order of the two routines below is important: clear_solib notifies
the solib_unloaded observers, and some of these observers might need
access to their associated objfiles. Therefore, we can not purge the
solibs' objfiles before clear_solib has been called. */
clear_solib ();
objfile_purge_solibs ();
The problem with doing things in this order is that both the solib and
the objfile have a reference to the same BFD. The solib is
responsible for releasing it (OBJF_KEEPBFD). arm_objfile_data_cleanup
accesses objfile->obfd during free_objfile, to find the number
of sections; at that point it's already been free'd.
Any thoughts? I could change the ARM code to work around this, but
that means banning access to objfile->obfd during a not well specified
range of functions. Handing off the ownership of the BFD seems like
it would be messy.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: Solibs and objfile BFD ownership 2009-07-28 15:40 Solibs and objfile BFD ownership Daniel Jacobowitz @ 2009-07-29 23:56 ` Paul Pluzhnikov 2009-07-30 16:16 ` Tom Tromey 0 siblings, 1 reply; 13+ messages in thread From: Paul Pluzhnikov @ 2009-07-29 23:56 UTC (permalink / raw) To: Paul Pluzhnikov, gdb [-- Attachment #1: Type: text/plain, Size: 974 bytes --] On Tue, Jul 28, 2009 at 8:40 AM, Daniel Jacobowitz<drow@false.org> wrote: > clear_solib (); > objfile_purge_solibs (); > > The problem with doing things in this order is that both the solib and > the objfile have a reference to the same BFD. The solib is > responsible for releasing it (OBJF_KEEPBFD). arm_objfile_data_cleanup > accesses objfile->obfd during free_objfile, to find the number > of sections; at that point it's already been free'd. That is a problem. > Any thoughts? There doesn't appear to be a correct order of destruction :-( Attached patch restores the original order, while still keeping solib_unloaded observers from accessing danglig objfiles. I do not know if there is a better way to fix this. Tested on Linux/x86_64 with no new regressions. Thanks, -- Paul Pluzhnikov 2009-07-29 Paul Pluzhnikov <ppluzhnikov@google.com> * solib.c (clear_solib): Rename to clear_solib_1 (clear_solib): New function. (no_shared_libraries): Adjust. [-- Attachment #2: gdb-clear-solib-20090729.txt --] [-- Type: text/plain, Size: 2102 bytes --] Index: solib.c =================================================================== RCS file: /cvs/src/src/gdb/solib.c,v retrieving revision 1.122 diff -u -p -u -r1.122 solib.c --- solib.c 17 Jul 2009 17:08:23 -0000 1.122 +++ solib.c 29 Jul 2009 23:39:11 -0000 @@ -893,10 +893,8 @@ solib_name_from_address (CORE_ADDR addre return (0); } -/* Called by free_all_symtabs */ - -void -clear_solib (void) +static void +clear_solib_1 (int notify_observers) { struct target_so_ops *ops = solib_ops (target_gdbarch); @@ -928,7 +926,8 @@ clear_solib (void) { struct so_list *so = so_list_head; so_list_head = so->next; - observer_notify_solib_unloaded (so); + if (notify_observers) + observer_notify_solib_unloaded (so); if (so->abfd) remove_target_sections (so->abfd); free_so (so); @@ -937,6 +936,15 @@ clear_solib (void) ops->clear_solib (); } +/* Called by free_all_symtabs */ + +void +clear_solib (void) +{ + clear_solib_1 (1); +} + + /* GLOBAL FUNCTION solib_create_inferior_hook -- shared library startup support @@ -1018,13 +1026,20 @@ sharedlibrary_command (char *args, int f void no_shared_libraries (char *ignored, int from_tty) { - /* The order of the two routines below is important: clear_solib notifies - the solib_unloaded observers, and some of these observers might need - access to their associated objfiles. Therefore, we can not purge the - solibs' objfiles before clear_solib has been called. */ + struct so_list *so = so_list_head; + + /* We notify all solib_unloaded observers before destroying any objfiles, + because some observers need access to their associated objfiles. */ + + for (so = so_list_head; so; so = so->next) + observer_notify_solib_unloaded (so); + + /* The order of the two routines below is important: clear_solib_1 + will free/close objfile->obfd (solib owns it), but objfile_purge_solibs + needs access to it (at least on ARM, see arm_objfile_data_cleanup). */ - clear_solib (); objfile_purge_solibs (); + clear_solib_1 (0); } static void ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Solibs and objfile BFD ownership 2009-07-29 23:56 ` Paul Pluzhnikov @ 2009-07-30 16:16 ` Tom Tromey 2009-08-04 0:50 ` Paul Pluzhnikov 0 siblings, 1 reply; 13+ messages in thread From: Tom Tromey @ 2009-07-30 16:16 UTC (permalink / raw) To: Paul Pluzhnikov; +Cc: gdb >>>>> "Paul" == Paul Pluzhnikov <ppluzhnikov@google.com> writes: Paul> There doesn't appear to be a correct order of destruction :-( [...] Paul> I do not know if there is a better way to fix this. It seems to me that there are not many choices. Either we must pick a single owner, pick an order, implement something like reference counting for BFDs, or have a separate function to clean up the BFDs. Tom ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Solibs and objfile BFD ownership 2009-07-30 16:16 ` Tom Tromey @ 2009-08-04 0:50 ` Paul Pluzhnikov 2009-08-04 14:53 ` Daniel Jacobowitz 0 siblings, 1 reply; 13+ messages in thread From: Paul Pluzhnikov @ 2009-08-04 0:50 UTC (permalink / raw) To: tromey; +Cc: gdb [-- Attachment #1: Type: text/plain, Size: 730 bytes --] On Thu, Jul 30, 2009 at 9:15 AM, Tom Tromey<tromey@redhat.com> wrote: > It seems to me that there are not many choices. Either we must pick a > single owner, pick an order, implement something like reference counting > for BFDs, or have a separate function to clean up the BFDs. Right. Conveniently, 'struct bfd' has usrdata, which is unused in GDB. Here is a stab at reference-counted sharing of BFDs between solib and objfile. -- Paul Pluzhnikov 2009-08-03 Paul Pluzhnikov <ppluzhnikov@google.com> * objfiles.h (OBJF_KEEPBFD): Delete. (gdb_bfd_unref): New prototype. * objfiles.c (gdb_bfd_unref): New function. (free_objfile): Call gdb_bfd_unref. * solib.c (free_so): Likewise. (symbol_add_stub): Set refcount. [-- Attachment #2: gdb-bfd-ownership-20090803.txt --] [-- Type: text/plain, Size: 4166 bytes --] Index: objfiles.h =================================================================== RCS file: /cvs/src/src/gdb/objfiles.h,v retrieving revision 1.60 diff -u -p -u -r1.60 objfiles.h --- objfiles.h 22 Jul 2009 19:21:31 -0000 1.60 +++ objfiles.h 4 Aug 2009 00:40:55 -0000 @@ -414,12 +414,6 @@ struct objfile #define OBJF_USERLOADED (1 << 3) /* User loaded */ -/* The bfd of this objfile is used outside of the objfile (e.g. by solib). - Do not try to free it. */ - -#define OBJF_KEEPBFD (1 << 4) /* Do not delete bfd */ - - /* The object file that the main symbol table was loaded from (e.g. the argument to the "symbol-file" or "file" command). */ @@ -510,6 +504,8 @@ extern void set_objfile_data (struct obj const struct objfile_data *data, void *value); extern void *objfile_data (struct objfile *objfile, const struct objfile_data *data); + +extern void gdb_bfd_unref (struct bfd *abfd); \f /* Traverse all object files. ALL_OBJFILES_SAFE works even if you delete Index: objfiles.c =================================================================== RCS file: /cvs/src/src/gdb/objfiles.c,v retrieving revision 1.88 diff -u -p -u -r1.88 objfiles.c --- objfiles.c 28 Jul 2009 16:39:06 -0000 1.88 +++ objfiles.c 4 Aug 2009 00:40:55 -0000 @@ -452,16 +452,7 @@ free_objfile (struct objfile *objfile) /* Discard any data modules have associated with the objfile. */ objfile_free_data (objfile); - /* We always close the bfd, unless the OBJF_KEEPBFD flag is set. */ - - if (objfile->obfd != NULL && !(objfile->flags & OBJF_KEEPBFD)) - { - char *name = bfd_get_filename (objfile->obfd); - if (!bfd_close (objfile->obfd)) - warning (_("cannot close \"%s\": %s"), - name, bfd_errmsg (bfd_get_error ())); - xfree (name); - } + gdb_bfd_unref (objfile->obfd); /* Remove it from the chain of all objfiles. */ @@ -1020,3 +1011,31 @@ objfiles_changed (void) { objfiles_changed_p = 1; /* Rebuild section map next time we need it. */ } + +/* Unreference and possibly close abfd. */ +void +gdb_bfd_unref (struct bfd *abfd) +{ + int *p_refcount; + char *name; + + if (abfd == NULL) + return; + + p_refcount = abfd->usrdata; + if (p_refcount != NULL) + { + gdb_assert (*p_refcount > 0); + *p_refcount -= 1; + if (*p_refcount > 0) + return; + } + xfree (p_refcount); + abfd->usrdata = NULL; /* Paranoia. */ + + name = bfd_get_filename (abfd); + if (!bfd_close (abfd)) + warning (_("cannot close \"%s\": %s"), + name, bfd_errmsg (bfd_get_error ())); + xfree (name); +} Index: solib.c =================================================================== RCS file: /cvs/src/src/gdb/solib.c,v retrieving revision 1.122 diff -u -p -u -r1.122 solib.c --- solib.c 17 Jul 2009 17:08:23 -0000 1.122 +++ solib.c 4 Aug 2009 00:40:55 -0000 @@ -421,21 +421,11 @@ void free_so (struct so_list *so) { struct target_so_ops *ops = solib_ops (target_gdbarch); - char *bfd_filename = 0; if (so->sections) xfree (so->sections); - - if (so->abfd) - { - bfd_filename = bfd_get_filename (so->abfd); - if (! bfd_close (so->abfd)) - warning (_("cannot close \"%s\": %s"), - bfd_filename, bfd_errmsg (bfd_get_error ())); - } - if (bfd_filename) - xfree (bfd_filename); + gdb_bfd_unref (so->abfd); ops->free_so (so); @@ -454,6 +444,7 @@ static void symbol_add_stub (struct so_list *so, int flags) { struct section_addr_info *sap; + int *p_refcount; /* Have we already loaded this shared object? */ ALL_OBJFILES (so->objfile) @@ -465,8 +456,11 @@ symbol_add_stub (struct so_list *so, int sap = build_section_addr_info_from_section_table (so->sections, so->sections_end); - so->objfile = symbol_file_add_from_bfd (so->abfd, flags, - sap, OBJF_SHARED | OBJF_KEEPBFD); + so->objfile = symbol_file_add_from_bfd (so->abfd, flags, sap, OBJF_SHARED); + p_refcount = malloc (sizeof (*p_refcount)); + *p_refcount = 2; /* Both solib and objfile refer to this abfd. */ + so->abfd->usrdata = p_refcount; + free_section_addr_info (sap); return; ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Solibs and objfile BFD ownership 2009-08-04 0:50 ` Paul Pluzhnikov @ 2009-08-04 14:53 ` Daniel Jacobowitz 2009-08-04 17:37 ` Paul Pluzhnikov 0 siblings, 1 reply; 13+ messages in thread From: Daniel Jacobowitz @ 2009-08-04 14:53 UTC (permalink / raw) To: Paul Pluzhnikov; +Cc: tromey, gdb On Mon, Aug 03, 2009 at 05:49:54PM -0700, Paul Pluzhnikov wrote: > Conveniently, 'struct bfd' has usrdata, which is unused in GDB. > Here is a stab at reference-counted sharing of BFDs between solib and > objfile. I can't see a better solution, so let's use this. A comment somewhere about the usage of the usrdata field would be nice. I gather that NULL and 1 behave the same? > + p_refcount = malloc (sizeof (*p_refcount)); xmalloc -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Solibs and objfile BFD ownership 2009-08-04 14:53 ` Daniel Jacobowitz @ 2009-08-04 17:37 ` Paul Pluzhnikov 2009-08-04 18:40 ` Daniel Jacobowitz 0 siblings, 1 reply; 13+ messages in thread From: Paul Pluzhnikov @ 2009-08-04 17:37 UTC (permalink / raw) To: Paul Pluzhnikov, tromey, gdb [-- Attachment #1: Type: text/plain, Size: 725 bytes --] On Tue, Aug 4, 2009 at 7:53 AM, Daniel Jacobowitz<drow@false.org> wrote: > A comment somewhere about the usage of the usrdata field would be > nice. I gather that NULL and 1 behave the same? Yes. I added comment to gdb_bfd_unref. Updated patch attached. Tested on Linux/x86_64 with no new failures. Daniel, could you confirm that this fixes the ARM failures? Thanks, -- Paul Pluzhnikov 2009-08-04 Paul Pluzhnikov <ppluzhnikov@google.com> * objfiles.h (OBJF_KEEPBFD): Delete. (gdb_bfd_unref): New prototype. * objfiles.c (gdb_bfd_unref): New function. (free_objfile): Call gdb_bfd_unref. * solib.c (free_so): Likewise. (symbol_add_stub): Set refcount. [-- Attachment #2: gdb-bfd-ownership-20090804.txt --] [-- Type: text/plain, Size: 4357 bytes --] Index: objfiles.h =================================================================== RCS file: /cvs/src/src/gdb/objfiles.h,v retrieving revision 1.60 diff -u -p -u -r1.60 objfiles.h --- objfiles.h 22 Jul 2009 19:21:31 -0000 1.60 +++ objfiles.h 4 Aug 2009 17:22:33 -0000 @@ -414,12 +414,6 @@ struct objfile #define OBJF_USERLOADED (1 << 3) /* User loaded */ -/* The bfd of this objfile is used outside of the objfile (e.g. by solib). - Do not try to free it. */ - -#define OBJF_KEEPBFD (1 << 4) /* Do not delete bfd */ - - /* The object file that the main symbol table was loaded from (e.g. the argument to the "symbol-file" or "file" command). */ @@ -510,6 +504,8 @@ extern void set_objfile_data (struct obj const struct objfile_data *data, void *value); extern void *objfile_data (struct objfile *objfile, const struct objfile_data *data); + +extern void gdb_bfd_unref (struct bfd *abfd); \f /* Traverse all object files. ALL_OBJFILES_SAFE works even if you delete Index: objfiles.c =================================================================== RCS file: /cvs/src/src/gdb/objfiles.c,v retrieving revision 1.88 diff -u -p -u -r1.88 objfiles.c --- objfiles.c 28 Jul 2009 16:39:06 -0000 1.88 +++ objfiles.c 4 Aug 2009 17:22:33 -0000 @@ -452,16 +452,7 @@ free_objfile (struct objfile *objfile) /* Discard any data modules have associated with the objfile. */ objfile_free_data (objfile); - /* We always close the bfd, unless the OBJF_KEEPBFD flag is set. */ - - if (objfile->obfd != NULL && !(objfile->flags & OBJF_KEEPBFD)) - { - char *name = bfd_get_filename (objfile->obfd); - if (!bfd_close (objfile->obfd)) - warning (_("cannot close \"%s\": %s"), - name, bfd_errmsg (bfd_get_error ())); - xfree (name); - } + gdb_bfd_unref (objfile->obfd); /* Remove it from the chain of all objfiles. */ @@ -1020,3 +1011,35 @@ objfiles_changed (void) { objfiles_changed_p = 1; /* Rebuild section map next time we need it. */ } + +/* Unreference and possibly close abfd. */ +void +gdb_bfd_unref (struct bfd *abfd) +{ + int *p_refcount; + char *name; + + if (abfd == NULL) + return; + + p_refcount = abfd->usrdata; + + /* Valid range for p_refcount: NULL (single owner), or a pointer + to int counter, which has a value of 1 (single owner) or 2 (shared). */ + gdb_assert (p_refcount == NULL || *p_refcount == 1 || *p_refcount == 2); + + if (p_refcount != NULL) + { + *p_refcount -= 1; + if (*p_refcount > 0) + return; + } + xfree (p_refcount); + abfd->usrdata = NULL; /* Paranoia. */ + + name = bfd_get_filename (abfd); + if (!bfd_close (abfd)) + warning (_("cannot close \"%s\": %s"), + name, bfd_errmsg (bfd_get_error ())); + xfree (name); +} Index: solib.c =================================================================== RCS file: /cvs/src/src/gdb/solib.c,v retrieving revision 1.122 diff -u -p -u -r1.122 solib.c --- solib.c 17 Jul 2009 17:08:23 -0000 1.122 +++ solib.c 4 Aug 2009 17:22:33 -0000 @@ -421,21 +421,11 @@ void free_so (struct so_list *so) { struct target_so_ops *ops = solib_ops (target_gdbarch); - char *bfd_filename = 0; if (so->sections) xfree (so->sections); - - if (so->abfd) - { - bfd_filename = bfd_get_filename (so->abfd); - if (! bfd_close (so->abfd)) - warning (_("cannot close \"%s\": %s"), - bfd_filename, bfd_errmsg (bfd_get_error ())); - } - if (bfd_filename) - xfree (bfd_filename); + gdb_bfd_unref (so->abfd); ops->free_so (so); @@ -454,6 +444,7 @@ static void symbol_add_stub (struct so_list *so, int flags) { struct section_addr_info *sap; + int *p_refcount; /* Have we already loaded this shared object? */ ALL_OBJFILES (so->objfile) @@ -465,8 +456,11 @@ symbol_add_stub (struct so_list *so, int sap = build_section_addr_info_from_section_table (so->sections, so->sections_end); - so->objfile = symbol_file_add_from_bfd (so->abfd, flags, - sap, OBJF_SHARED | OBJF_KEEPBFD); + so->objfile = symbol_file_add_from_bfd (so->abfd, flags, sap, OBJF_SHARED); + p_refcount = xmalloc (sizeof (*p_refcount)); + *p_refcount = 2; /* Both solib and objfile refer to this abfd. */ + so->abfd->usrdata = p_refcount; + free_section_addr_info (sap); return; ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Solibs and objfile BFD ownership 2009-08-04 17:37 ` Paul Pluzhnikov @ 2009-08-04 18:40 ` Daniel Jacobowitz 2009-08-04 18:47 ` Paul Pluzhnikov 0 siblings, 1 reply; 13+ messages in thread From: Daniel Jacobowitz @ 2009-08-04 18:40 UTC (permalink / raw) To: Paul Pluzhnikov; +Cc: tromey, gdb On Tue, Aug 04, 2009 at 10:37:24AM -0700, Paul Pluzhnikov wrote: > On Tue, Aug 4, 2009 at 7:53 AM, Daniel Jacobowitz<drow@false.org> wrote: > > > A comment somewhere about the usage of the usrdata field would be > > nice. Â I gather that NULL and 1 behave the same? > > Yes. I added comment to gdb_bfd_unref. > Updated patch attached. Tested on Linux/x86_64 with no new failures. > > Daniel, could you confirm that this fixes the ARM failures? Yes - looks much better with this patch! > 2009-08-04 Paul Pluzhnikov <ppluzhnikov@google.com> > > * objfiles.h (OBJF_KEEPBFD): Delete. > (gdb_bfd_unref): New prototype. > * objfiles.c (gdb_bfd_unref): New function. > (free_objfile): Call gdb_bfd_unref. > * solib.c (free_so): Likewise. > (symbol_add_stub): Set refcount. OK. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Solibs and objfile BFD ownership 2009-08-04 18:40 ` Daniel Jacobowitz @ 2009-08-04 18:47 ` Paul Pluzhnikov 2009-08-18 5:56 ` Paul Pluzhnikov 0 siblings, 1 reply; 13+ messages in thread From: Paul Pluzhnikov @ 2009-08-04 18:47 UTC (permalink / raw) To: Paul Pluzhnikov, tromey, gdb On Tue, Aug 4, 2009 at 11:40 AM, Daniel Jacobowitz<drow@false.org> wrote: >> Daniel, could you confirm that this fixes the ARM failures? > Yes - looks much better with this patch! So committed. Thanks, -- Paul Pluzhnikov ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Solibs and objfile BFD ownership 2009-08-04 18:47 ` Paul Pluzhnikov @ 2009-08-18 5:56 ` Paul Pluzhnikov 2009-08-19 22:29 ` Tom Tromey 0 siblings, 1 reply; 13+ messages in thread From: Paul Pluzhnikov @ 2009-08-18 5:56 UTC (permalink / raw) To: Paul Pluzhnikov, tromey, gdb [-- Attachment #1: Type: text/plain, Size: 1445 bytes --] On Tue, Aug 4, 2009 at 11:47 AM, Paul Pluzhnikov<ppluzhnikov@google.com> wrote: > So committed. Thanks, I seem to have hit a rough patch with my patches :-( The BFD refcounting patch from 2009-08-04 causes GDB to crash when I attach to a process with many solibs, then (while GDB is reading solib symbols) change my mind about attaching and hit Control-C, then 'run'. This is happening because in symbol_add_stub refcount may not be set: so->objfile = symbol_file_add_from_bfd (so->abfd, flags, sap, OBJF_SHARED); ---> QUIT could be executed deep inside symbol_file_add_from_bfd, and ---> bfd_userdata below is never set. p_refcount = xmalloc (sizeof (*p_refcount)); *p_refcount = 2; /* Both solib and objfile refer to this abfd. */ bfd_usrdata (so->abfd) = p_refcount; Later, we re-enter symbol_add_stub, and this: ALL_OBJFILES (so->objfile) { if (strcmp (so->objfile->name, so->so_name) == 0) return; re-connects the so with the objfile, but never sets the bfd_usrdata. Later still (during execution of 'run'), we go through clear_solib and objfile_purge_solibs, and the latter crashes trying to bfd_close the abfd which has already been bfd_close()d by the former. Here is a proposed patch. Tested on Linux/x86_64 with no new failures. Thanks, -- Paul Pluzhnikov 2009-08-17 Paul Pluzhnikov <ppluzhnikov@google.com> * solib.c (set_ref_count): New function. (symbol_add_stub): Call it. [-- Attachment #2: gdb-bfd-ownership-20090817.txt --] [-- Type: text/plain, Size: 1914 bytes --] Index: solib.c =================================================================== RCS file: /cvs/src/src/gdb/solib.c,v retrieving revision 1.124 diff -u -p -u -r1.124 solib.c --- solib.c 10 Aug 2009 22:09:22 -0000 1.124 +++ solib.c 17 Aug 2009 22:27:07 -0000 @@ -440,26 +440,53 @@ master_so_list (void) return so_list_head; } +/* Set reference count on ABFD to COUNT. */ + +static void +set_ref_count (struct bfd *abfd, int count) +{ + int *p_refcount = (int *) xmalloc (sizeof (*p_refcount)); + *p_refcount = count; + + gdb_assert (bfd_usrdata (abfd) == NULL); + bfd_usrdata (abfd) = p_refcount; +} + static void symbol_add_stub (struct so_list *so, int flags) { struct section_addr_info *sap; - int *p_refcount; + struct objfile *objfile; /* Have we already loaded this shared object? */ - ALL_OBJFILES (so->objfile) + ALL_OBJFILES (objfile) { - if (strcmp (so->objfile->name, so->so_name) == 0) - return; + if (strcmp (objfile->name, so->so_name) == 0) + { + if (objfile != so->objfile) + { + /* This could happen when symbol_file_add_from_bfd + below is interrupted. */ + + gdb_assert (so->objfile == NULL); + gdb_assert (bfd_usrdata (so->abfd) == NULL); + + so->objfile = objfile; /* Reconnect. */ + + /* Both solib and objfile refer to this abfd. */ + set_ref_count (so->abfd, 2); + } + return; + } } sap = build_section_addr_info_from_section_table (so->sections, so->sections_end); so->objfile = symbol_file_add_from_bfd (so->abfd, flags, sap, OBJF_SHARED); - p_refcount = xmalloc (sizeof (*p_refcount)); - *p_refcount = 2; /* Both solib and objfile refer to this abfd. */ - bfd_usrdata (so->abfd) = p_refcount; + + /* Both solib and objfile refer to this abfd. */ + set_ref_count (so->abfd, 2); free_section_addr_info (sap); ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Solibs and objfile BFD ownership 2009-08-18 5:56 ` Paul Pluzhnikov @ 2009-08-19 22:29 ` Tom Tromey 2009-08-20 1:50 ` Paul Pluzhnikov 0 siblings, 1 reply; 13+ messages in thread From: Tom Tromey @ 2009-08-19 22:29 UTC (permalink / raw) To: Paul Pluzhnikov; +Cc: gdb >>>>> "Paul" == Paul Pluzhnikov <ppluzhnikov@google.com> writes: Paul> I seem to have hit a rough patch with my patches :-( Yeah, that happens to me too. Paul> This is happening because in symbol_add_stub refcount may not be set: so-> objfile = symbol_file_add_from_bfd (so->abfd, flags, sap, OBJF_SHARED); ---> QUIT could be executed deep inside symbol_file_add_from_bfd, and ---> bfd_userdata below is never set. Paul> p_refcount = xmalloc (sizeof (*p_refcount)); Paul> *p_refcount = 2; /* Both solib and objfile refer to this abfd. */ Paul> bfd_usrdata (so->abfd) = p_refcount; I haven't had time to read this patch fully and try to understand it. It just struck me from a first reading that it would be simpler, and more conventional, to have a "gdb_bfd_ref" function, to go along with gdb_bfd_unref, which we call whenever we assign a 'bfd*' to a field somewhere. What do you think? Tom ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Solibs and objfile BFD ownership 2009-08-19 22:29 ` Tom Tromey @ 2009-08-20 1:50 ` Paul Pluzhnikov 2009-08-21 17:32 ` Tom Tromey 0 siblings, 1 reply; 13+ messages in thread From: Paul Pluzhnikov @ 2009-08-20 1:50 UTC (permalink / raw) To: Tom Tromey; +Cc: gdb [-- Attachment #1: Type: text/plain, Size: 1196 bytes --] On Wed, Aug 19, 2009 at 3:11 PM, Tom Tromey<tromey@redhat.com> wrote: > Paul> *p_refcount = 2; /* Both solib and objfile refer to this abfd. */ > Paul> bfd_usrdata (so->abfd) = p_refcount; > > I haven't had time to read this patch fully and try to understand it. > > It just struck me from a first reading that it would be simpler, and > more conventional, to have a "gdb_bfd_ref" function, to go along with > gdb_bfd_unref, which we call whenever we assign a 'bfd*' to a field > somewhere. It would be slightly wasteful to set refcount to 1 everywhere, since solib is the only place where sharing could (currently) occur. But maybe it *is* a good idea anyway. Here is a proposed fix. Tested on Linux/x86_64 with no new failures. Also tested to fix the crash I observed. Thanks, -- Paul Pluzhnikov 2009-08-19 Paul Pluzhnikov <ppluzhnikov@google.com> * objfiles.h (gdb_bfd_ref): New prototype. * objfiles.c (gdb_bfd_ref): New function. (allocate_objfile): Call it. (gdb_bfd_unref): Adjust assertion. * solib.c (solib_map_sections): Add reference. (symbol_add_stub): Don't add reference here. * symfile.c (reread_symbols): Add reference. [-- Attachment #2: gdb-bfd-ownership-20090819.txt --] [-- Type: text/plain, Size: 4362 bytes --] Index: objfiles.h =================================================================== RCS file: /cvs/src/src/gdb/objfiles.h,v retrieving revision 1.61 diff -u -p -u -r1.61 objfiles.h --- objfiles.h 4 Aug 2009 18:46:05 -0000 1.61 +++ objfiles.h 19 Aug 2009 23:30:43 -0000 @@ -505,6 +505,7 @@ extern void set_objfile_data (struct obj extern void *objfile_data (struct objfile *objfile, const struct objfile_data *data); +extern struct bfd *gdb_bfd_ref (struct bfd *abfd); extern void gdb_bfd_unref (struct bfd *abfd); \f Index: objfiles.c =================================================================== RCS file: /cvs/src/src/gdb/objfiles.c,v retrieving revision 1.92 diff -u -p -u -r1.92 objfiles.c --- objfiles.c 17 Aug 2009 11:16:13 -0000 1.92 +++ objfiles.c 19 Aug 2009 23:30:43 -0000 @@ -181,7 +181,7 @@ allocate_objfile (bfd *abfd, int flags) that any data that is reference is saved in the per-objfile data region. */ - objfile->obfd = abfd; + objfile->obfd = gdb_bfd_ref (abfd); if (objfile->name != NULL) { xfree (objfile->name); @@ -1062,7 +1062,26 @@ objfiles_changed (void) objfiles_changed_p = 1; /* Rebuild section map next time we need it. */ } -/* Unreference and possibly close abfd. */ +/* Add reference to ABFD. Returns ABFD. */ +struct bfd * +gdb_bfd_ref (struct bfd *abfd) +{ + int *p_refcount = bfd_usrdata (abfd); + + if (p_refcount != NULL) + { + *p_refcount += 1; + return abfd; + } + + p_refcount = xmalloc (sizeof (*p_refcount)); + *p_refcount = 1; + bfd_usrdata (abfd) = p_refcount; + + return abfd; +} + +/* Unreference and possibly close ABFD. */ void gdb_bfd_unref (struct bfd *abfd) { @@ -1074,16 +1093,14 @@ gdb_bfd_unref (struct bfd *abfd) p_refcount = bfd_usrdata (abfd); - /* Valid range for p_refcount: NULL (single owner), or a pointer - to int counter, which has a value of 1 (single owner) or 2 (shared). */ - gdb_assert (p_refcount == NULL || *p_refcount == 1 || *p_refcount == 2); + /* Valid range for p_refcount: a pointer to int counter, which has a + value of 1 (single owner) or 2 (shared). */ + gdb_assert (*p_refcount == 1 || *p_refcount == 2); + + *p_refcount -= 1; + if (*p_refcount > 0) + return; - if (p_refcount != NULL) - { - *p_refcount -= 1; - if (*p_refcount > 0) - return; - } xfree (p_refcount); bfd_usrdata (abfd) = NULL; /* Paranoia. */ Index: solib.c =================================================================== RCS file: /cvs/src/src/gdb/solib.c,v retrieving revision 1.124 diff -u -p -u -r1.124 solib.c --- solib.c 10 Aug 2009 22:09:22 -0000 1.124 +++ solib.c 19 Aug 2009 23:30:44 -0000 @@ -361,7 +361,7 @@ solib_map_sections (void *arg) do_cleanups (old_chain); /* Leave bfd open, core_xfer_memory and "info files" need it. */ - so->abfd = abfd; + so->abfd = gdb_bfd_ref (abfd); /* copy full path name into so_name, so that later symbol_file_add can find it */ @@ -444,7 +444,6 @@ static void symbol_add_stub (struct so_list *so, int flags) { struct section_addr_info *sap; - int *p_refcount; /* Have we already loaded this shared object? */ ALL_OBJFILES (so->objfile) @@ -457,10 +456,6 @@ symbol_add_stub (struct so_list *so, int so->sections_end); so->objfile = symbol_file_add_from_bfd (so->abfd, flags, sap, OBJF_SHARED); - p_refcount = xmalloc (sizeof (*p_refcount)); - *p_refcount = 2; /* Both solib and objfile refer to this abfd. */ - bfd_usrdata (so->abfd) = p_refcount; - free_section_addr_info (sap); return; Index: symfile.c =================================================================== RCS file: /cvs/src/src/gdb/symfile.c,v retrieving revision 1.243 diff -u -p -u -r1.243 symfile.c --- symfile.c 17 Aug 2009 20:09:38 -0000 1.243 +++ symfile.c 19 Aug 2009 23:30:45 -0000 @@ -2333,6 +2333,8 @@ reread_symbols (void) objfile->obfd = bfd_openr (obfd_filename, gnutarget); if (objfile->obfd == NULL) error (_("Can't open %s to read symbols."), objfile->name); + else + objfile->obfd = gdb_bfd_ref (objfile->obfd); /* bfd_openr sets cacheable to true, which is what we want. */ if (!bfd_check_format (objfile->obfd, bfd_object)) error (_("Can't read symbols from %s: %s."), objfile->name, ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Solibs and objfile BFD ownership 2009-08-20 1:50 ` Paul Pluzhnikov @ 2009-08-21 17:32 ` Tom Tromey 2009-08-21 18:04 ` Paul Pluzhnikov 0 siblings, 1 reply; 13+ messages in thread From: Tom Tromey @ 2009-08-21 17:32 UTC (permalink / raw) To: Paul Pluzhnikov; +Cc: gdb >>>>> "Paul" == Paul Pluzhnikov <ppluzhnikov@google.com> writes: Paul> It would be slightly wasteful to set refcount to 1 everywhere, Paul> since solib is the only place where sharing could (currently) Paul> occur. Yeah, I suppose. But it seems clearer and more future-proof to me. Paul> 2009-08-19 Paul Pluzhnikov <ppluzhnikov@google.com> Paul> * objfiles.h (gdb_bfd_ref): New prototype. Paul> * objfiles.c (gdb_bfd_ref): New function. Paul> (allocate_objfile): Call it. Paul> (gdb_bfd_unref): Adjust assertion. Paul> * solib.c (solib_map_sections): Add reference. Paul> (symbol_add_stub): Don't add reference here. Paul> * symfile.c (reread_symbols): Add reference. This is ok. Thanks. Paul> + gdb_assert (*p_refcount == 1 || *p_refcount == 2); This assertion is a bit strange, but I suppose it is harmless. If we ever want more sharing, we can always just remove it. In the meantime I suppose it is checking that we don't over-share somehow. Tom ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: Solibs and objfile BFD ownership 2009-08-21 17:32 ` Tom Tromey @ 2009-08-21 18:04 ` Paul Pluzhnikov 0 siblings, 0 replies; 13+ messages in thread From: Paul Pluzhnikov @ 2009-08-21 18:04 UTC (permalink / raw) To: tromey; +Cc: gdb On Fri, Aug 21, 2009 at 10:29 AM, Tom Tromey<tromey@redhat.com> wrote: > This is ok. Thanks. So committed. > Paul> + gdb_assert (*p_refcount == 1 || *p_refcount == 2); > > This assertion is a bit strange, but I suppose it is harmless. If we > ever want more sharing, we can always just remove it. In the meantime I > suppose it is checking that we don't over-share somehow. The assertion was intended to catch somebody else in GDB using bfd_usrdata for some other purpose (in a way I didn't find). I think it's safe to leave it in for now. Thanks, -- Paul Pluzhnikov ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2009-08-21 17:57 UTC | newest] Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2009-07-28 15:40 Solibs and objfile BFD ownership Daniel Jacobowitz 2009-07-29 23:56 ` Paul Pluzhnikov 2009-07-30 16:16 ` Tom Tromey 2009-08-04 0:50 ` Paul Pluzhnikov 2009-08-04 14:53 ` Daniel Jacobowitz 2009-08-04 17:37 ` Paul Pluzhnikov 2009-08-04 18:40 ` Daniel Jacobowitz 2009-08-04 18:47 ` Paul Pluzhnikov 2009-08-18 5:56 ` Paul Pluzhnikov 2009-08-19 22:29 ` Tom Tromey 2009-08-20 1:50 ` Paul Pluzhnikov 2009-08-21 17:32 ` Tom Tromey 2009-08-21 18:04 ` Paul Pluzhnikov
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox