[patch] Eliminate quadratic slow-down on number of solibs (take 2).

Paul Pluzhnikov ppluzhnikov@google.com
Tue Jun 9 00:51:00 GMT 2009


On Wed, Jun 3, 2009 at 2:34 PM, Tom Tromey<tromey@redhat.com> wrote:

> Paul> The problem is that the call chain is deep:
> Yeah, but it can be simplified.

> Paul>     flags=<value optimized out>) at ../../src/gdb/symfile.c:1033
> Paul> #5  0x00000000004e3ee5 in symbol_file_add_from_bfd (abfd=0xd57fe0,
> Paul>     from_tty=0, addrs=0x0, mainline=0, flags=<value optimized out>)
> Paul>     at ../../src/gdb/symfile.c:1103
>
> These are all just forwarding calls, basically overloads.
> You could add a new overload just for this purpose.

But they may call themselves recursively.
I've added a bit to OBJF_* flags instead.

How about attached patch then?

On a 1500+ solib test case I see 20% reduction in CPU, measured as:

  time gdb -ex 'break main' -ex run -ex quit custom_test

Before (best time):

real    1m1.724s
user    0m56.776s
sys     0m4.852s

After:

real    0m51.596s
user    0m46.739s
sys     0m4.820s

Tested on Linux/x86_64, no new failures.

Thanks,
-- 
Paul Pluzhnikov

2009-06-08  Paul Pluzhnikov  <ppluzhnikov@google.com>

	* solib.c (symbol_add_stub): Add DEFER_BP_RESET parameter.
	(solib_read_symbols): Add DEFER_BP_RESET parameter.
	(solib_add): Defer breakpoint reset.
	* solib.h (solib_read_symbols): Adjust prototype.
	* symfile.c (new_symfile_objfile): Add FLAGS parameter.
	(symbol_file_add_with_addrs_or_offsets): Adjust call.
	* symfile.h (new_symfile_objfile): Adjust prototype.
	* objfile.h (OBJF_DEFER_BP_RESET): New define.
	* bsd-uthread.c (bsd_uthread_solib_loaded): Adjust call.
	* rs6000-nat.c (objfile_symbol_add): Adjust call.
-------------- next part --------------
Index: solib.h
===================================================================
RCS file: /cvs/src/src/gdb/solib.h,v
retrieving revision 1.24
diff -u -p -u -r1.24 solib.h
--- solib.h	15 May 2009 16:53:44 -0000	1.24
+++ solib.h	9 Jun 2009 00:49:30 -0000
@@ -34,7 +34,7 @@ extern void clear_solib (void);
 /* Called to add symbols from a shared library to gdb's symbol table. */
 
 extern void solib_add (char *, int, struct target_ops *, int);
-extern int solib_read_symbols (struct so_list *, int);
+extern int solib_read_symbols (struct so_list *, int, int);
 
 /* Function to be called when the inferior starts up, to discover the
    names of shared libraries that are dynamically linked, the base
Index: solib.c
===================================================================
RCS file: /cvs/src/src/gdb/solib.c,v
retrieving revision 1.119
diff -u -p -u -r1.119 solib.c
--- solib.c	3 Jun 2009 18:50:36 -0000	1.119
+++ solib.c	9 Jun 2009 00:49:31 -0000
@@ -448,30 +448,29 @@ master_so_list (void)
   return so_list_head;
 }
 
-
-/* A small stub to get us past the arg-passing pinhole of catch_errors.  */
-
-static int
-symbol_add_stub (void *arg)
+static void
+symbol_add_stub (struct so_list *so, int defer_bp_reset)
 {
-  struct so_list *so = (struct so_list *) arg;  /* catch_errs bogon */
   struct section_addr_info *sap;
+  int flags = OBJF_SHARED | OBJF_KEEPBFD;
 
   /* Have we already loaded this shared object?  */
   ALL_OBJFILES (so->objfile)
     {
       if (strcmp (so->objfile->name, so->so_name) == 0)
-	return 1;
+	return;
     }
 
   sap = build_section_addr_info_from_section_table (so->sections,
                                                     so->sections_end);
 
+  if (defer_bp_reset)
+    flags |= OBJF_DEFER_BP_RESET;
   so->objfile = symbol_file_add_from_bfd (so->abfd, so->from_tty,
-					  sap, 0, OBJF_SHARED | OBJF_KEEPBFD);
+					  sap, 0, flags);
   free_section_addr_info (sap);
 
-  return (1);
+  return;
 }
 
 /* Read in symbols for shared object SO.  If FROM_TTY is non-zero, be
@@ -479,7 +478,7 @@ symbol_add_stub (void *arg)
    loaded.  */
 
 int
-solib_read_symbols (struct so_list *so, int from_tty)
+solib_read_symbols (struct so_list *so, int from_tty, int defer_bp_reset)
 {
   if (so->symbols_loaded)
     {
@@ -493,15 +492,21 @@ solib_read_symbols (struct so_list *so, 
     }
   else
     {
-      if (catch_errors (symbol_add_stub, so,
-			"Error while reading shared library symbols:\n",
-			RETURN_MASK_ALL))
-	{
-	  if (from_tty && print_symbol_loading)
-	    printf_unfiltered (_("Loaded symbols for %s\n"), so->so_name);
-	  so->symbols_loaded = 1;
-	  return 1;
-	}
+      volatile struct gdb_exception exception;
+      TRY_CATCH (exception, RETURN_MASK_ALL)
+        {
+          symbol_add_stub (so, defer_bp_reset);
+        }
+      if (exception.reason != 0)
+        {
+          exception_fprintf (gdb_stderr, exception,
+                             "Error while reading shared library symbols:\n");
+          return 0;
+        }
+      if (from_tty && print_symbol_loading)
+        printf_unfiltered (_("Loaded symbols for %s\n"), so->so_name);
+      so->symbols_loaded = 1;
+      return 1;
     }
 
   return 0;
@@ -749,10 +754,13 @@ solib_add (char *pattern, int from_tty, 
             (readsyms || libpthread_solib_p (gdb));
 
 	  any_matches = 1;
-	  if (add_this_solib && solib_read_symbols (gdb, from_tty))
+	  if (add_this_solib && solib_read_symbols (gdb, from_tty, 1))
 	    loaded_any_symbols = 1;
 	}
 
+    if (loaded_any_symbols)
+      breakpoint_re_set ();
+
     if (from_tty && pattern && ! any_matches)
       printf_unfiltered
 	("No loaded shared libraries match the pattern `%s'.\n", pattern);
Index: symfile.h
===================================================================
RCS file: /cvs/src/src/gdb/symfile.h,v
retrieving revision 1.50
diff -u -p -u -r1.50 symfile.h
--- symfile.h	22 May 2009 23:49:14 -0000	1.50
+++ symfile.h	9 Jun 2009 00:49:31 -0000
@@ -214,7 +214,7 @@ extern void syms_from_objfile (struct ob
 			       struct section_addr_info *,
 			       struct section_offsets *, int, int, int);
 
-extern void new_symfile_objfile (struct objfile *, int, int);
+extern void new_symfile_objfile (struct objfile *, int, int, int);
 
 extern struct objfile *symbol_file_add (char *, int,
 					struct section_addr_info *, int, int);
Index: symfile.c
===================================================================
RCS file: /cvs/src/src/gdb/symfile.c,v
retrieving revision 1.230
diff -u -p -u -r1.230 symfile.c
--- symfile.c	4 Jun 2009 00:50:16 -0000	1.230
+++ symfile.c	9 Jun 2009 00:49:31 -0000
@@ -906,7 +906,8 @@ syms_from_objfile (struct objfile *objfi
    objfile. */
 
 void
-new_symfile_objfile (struct objfile *objfile, int mainline, int verbo)
+new_symfile_objfile (struct objfile *objfile, int mainline, int verbo,
+                     int flags)
 {
 
   /* If this is the main symbol file we have to clean up all users of the
@@ -919,7 +920,7 @@ new_symfile_objfile (struct objfile *obj
 
       clear_symtab_users ();
     }
-  else
+  else if ((flags & OBJF_DEFER_BP_RESET) == 0)
     {
       breakpoint_re_set_objfile (objfile);
     }
@@ -1081,7 +1082,7 @@ symbol_file_add_with_addrs_or_offsets (b
   if (objfile->sf == NULL)
     return objfile;	/* No symbols. */
 
-  new_symfile_objfile (objfile, mainline, from_tty);
+  new_symfile_objfile (objfile, mainline, from_tty, flags);
 
   observer_notify_new_objfile (objfile);
 
Index: objfiles.h
===================================================================
RCS file: /cvs/src/src/gdb/objfiles.h,v
retrieving revision 1.59
diff -u -p -u -r1.59 objfiles.h
--- objfiles.h	15 Jan 2009 16:35:22 -0000	1.59
+++ objfiles.h	9 Jun 2009 00:49:31 -0000
@@ -419,6 +419,9 @@ struct objfile
 
 #define OBJF_KEEPBFD	(1 << 4)	/* Do not delete bfd */
 
+/* User requested that this objfile not trigger breakpoint reset. */
+
+#define OBJF_DEFER_BP_RESET (1 << 5)    /* Defer breakpoint reset.  */
 
 /* The object file that the main symbol table was loaded from (e.g. the
    argument to the "symbol-file" or "file" command).  */
Index: bsd-uthread.c
===================================================================
RCS file: /cvs/src/src/gdb/bsd-uthread.c,v
retrieving revision 1.24
diff -u -p -u -r1.24 bsd-uthread.c
--- bsd-uthread.c	21 May 2009 15:48:41 -0000	1.24
+++ bsd-uthread.c	9 Jun 2009 00:49:31 -0000
@@ -248,7 +248,7 @@ bsd_uthread_solib_loaded (struct so_list
     {
       if (strncmp (so->so_original_name, *names, strlen (*names)) == 0)
 	{
-	  solib_read_symbols (so, so->from_tty);
+	  solib_read_symbols (so, so->from_tty, 0);
 
 	  if (bsd_uthread_activate (so->objfile))
 	    {
Index: rs6000-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/rs6000-nat.c,v
retrieving revision 1.93
diff -u -p -u -r1.93 rs6000-nat.c
--- rs6000-nat.c	3 Jun 2009 18:50:36 -0000	1.93
+++ rs6000-nat.c	9 Jun 2009 00:49:31 -0000
@@ -692,7 +692,7 @@ objfile_symbol_add (void *arg)
   struct objfile *obj = (struct objfile *) arg;
 
   syms_from_objfile (obj, NULL, 0, 0, 0, 0);
-  new_symfile_objfile (obj, 0, 0);
+  new_symfile_objfile (obj, 0, 0, 0);
   return 1;
 }
 


More information about the Gdb-patches mailing list