This is the mail archive of the
gdb@sources.redhat.com
mailing list for the GDB project.
Re: [Fwd: gdb "call" very slow on large C++ program; 2 possible patches]
Elena Zannoni writes:
> Andrew Cagney writes:
> > This might be interesting.
> > Andrew
>
> Hmmm, I am sorry I looked. :-(
> I discovered something very strange in symtab.c:make_symbol_overload_list().
>
> What is this function supposed to do with those two for loops over the
> psymbols? It is just calling QUIT, and PSYMTAB_TO_SYMTAB over and over
> again.
>
> I am afraid somebody did a cvs commit snafu at some point (this would predate
> the creation of sourceware).
> Those two for loops are noops, as far as I can tell.
>
> I'll dig further, before I actually can make sense of all this.
>
> Your cvs archaeologist,
> Elena
>
Yes, something like that happened. I am thinking to send a patch to
restore some sanity to this function. But...
...actually, I think that if search_symbols on FUNCTION_NAMESPACES is
equivalent to make_symbol_overload_list(), we could just get rid of
make_symbol_overload_list() *and* overload_list_add_symbol().
It would be nice to clean this up.
Daniel, does search_symbols produces a correct overload list? At first
sight it would look so.
Elena
>
> > From: Richard Sharman <richard_sharman@Mitel.COM>
> > To: bug-gdb@gnu.org
> > Cc: sharman@sharmanpc.software.Mitel.COM
> > Subject: gdb "call" very slow on large C++ program; 2 possible patches
> > Date: Sat, 17 Nov 2001 22:14:28 -0500
> > Content-Type: text
> >
> > We have a largish C++ program, and when we use the gdb "call" function
> > it takes about 12 seconds for GDB to perform the operation.
> > (The function itself is very quick. In the previous C version of the
> > program the call was virtually instantaneous.)
> >
> > I have two patches. The first patch reduced the time to about 5 seconds
> > for the first call but 2 seconds for the second call; the second patch
> > reduced to time to about an eigth of a second.
> >
> > The first patch was to "overload_list_add_symbol" in symtab.c .
> > This function was taking a lot of time demangling symbols that didn't
> > match. The patch did two things:
> >
> > * See if the name to search for matched the beginning of the
> > mangled name. If it did not, then exit immediately. This saved the
> > call to cplus_demangle and the xmalloc and free calls.
> >
> > * Set the "readin" flag after the two for loops in the ALL_PSYMTABS
> > loop. This catches the cases of files that have no symbols and thus
> > never get the readin flag set. (This may seem trivial but happened
> > in 4860 files in our program so was quite significant.)
> >
> > As mentioned above, this helped signficantly, especially on the second
> > call.
> >
> > However, there was still a noticable delay before the called function
> > was executed. We noticed that the gdb "info func" on the command name
> > was executed immediately, and wondered why it didn't have the same
> > delay in finding the function name. We found it was not using the
> > "make_symbol_overload_list" function, but instead calling
> > "search_symbols". The second patch was then to "find_overload_match"
> > in valops.c, to use the "search_symbols" function.
> >
> > Both patches work for us but I am not at all familiar with the
> > workings of gdb so do not know how reliable they are. I have no idea
> > why there appear to be two functions doing essentially the same thing
> > but one takes 12 seconds and one takes 0.125 seconds.
> >
> > The second patch makes the first patch unncessary since
> > make_symbol_overload_list is not called other than in the original
> > valops.c.
> >
> > Here are the two patches. They are agains the cvs source as of
> > 14 November checked out using
> >
> > cvs -z9 -d :pserver:anoncvs@sources.redhat.com:/cvs/src co -r \
> > gdb_5_0-2000-04-10-branch gdb+dejagnu
> >
> >
> > -------------------- Patch 1 --------------------
> > *** symtab.c.orig Mon Apr 3 22:08:52 2000
> > --- symtab.c Wed Nov 14 23:23:13 2001
> > ***************
> > *** 4460,4468 ****
> > {
> > int newsize;
> > int i;
> >
> > /* Get the demangled name without parameters */
> > ! char *sym_name = cplus_demangle (SYMBOL_NAME (sym), DMGL_ARM | DMGL_ANSI);
> > if (!sym_name)
> > {
> > sym_name = (char *) xmalloc (strlen (SYMBOL_NAME (sym)) + 1);
> > --- 4460,4476 ----
> > {
> > int newsize;
> > int i;
> > + char *sym_name;
> > +
> > +
> > + /* skip symbols that cannot match */
> > + if (strncmp(SYMBOL_NAME (sym), oload_name, strlen(oload_name)) != 0)
> > + {
> > + return;
> > + }
> >
> > /* Get the demangled name without parameters */
> > ! sym_name = cplus_demangle (SYMBOL_NAME (sym), DMGL_ARM | DMGL_ANSI);
> > if (!sym_name)
> > {
> > sym_name = (char *) xmalloc (strlen (SYMBOL_NAME (sym)) + 1);
> > ***************
> > *** 4567,4574 ****
> > --- 4575,4590 ----
> > /* This will cause the symbol table to be read if it has not yet been */
> > s = PSYMTAB_TO_SYMTAB (ps);
> > }
> > +
> > + /* If no symbols were found, mark it as read anyway so that
> > + we skip it next time. */
> > + if (ps && !ps->readin)
> > + {
> > + ps->readin = 1;
> > + }
> > }
> >
> > +
> > /* Search upwards from currently selected frame (so that we can
> > complete on local vars. */
> >
> > -------------------------------------------------
> >
> > -------------------- Patch --------------------
> > *** valops.c.orig Sun Apr 9 09:02:10 2000
> > --- valops.c Thu Nov 15 15:25:36 2001
> > ***************
> > *** 2739,2744 ****
> > --- 2739,2747 ----
> > int boffset;
> > register int jj;
> > register int ix;
> > + struct symbol_search *symbols;
> > + struct symbol_search *p;
> > + struct cleanup *old_chain;
> >
> > char *obj_type_name = NULL;
> > char *func_name = NULL;
> > ***************
> > *** 2799,2807 ****
> > return 0;
> > }
> >
> > ! oload_syms = make_symbol_overload_list (fsym);
> > ! while (oload_syms[++i])
> > ! num_fns++;
> > if (!num_fns)
> > error ("Couldn't find function %s", func_name);
> > }
> > --- 2802,2821 ----
> > return 0;
> > }
> >
> > ! search_symbols (SYMBOL_NAME (fsym), FUNCTIONS_NAMESPACE, 0, (char **) NULL, &symbols);
> > ! old_chain = make_cleanup ((make_cleanup_func) free_search_symbols, symbols);
> > ! for (p = symbols; p != NULL; p = p->next)
> > ! {
> > ! num_fns++;
> > ! }
> > ! oload_syms = (struct symbol **) xmalloc ((num_fns + 1) * sizeof (struct symbol *));
> > ! i = -1;
> > ! for (p = symbols; p != NULL; p = p->next)
> > ! {
> > ! oload_syms[++i] = p->symbol;
> > ! }
> > ! do_cleanups (old_chain);
> > !
> > if (!num_fns)
> > error ("Couldn't find function %s", func_name);
> > }
> > ***************
> > *** 2946,2952 ****
> > *symp = oload_syms[oload_champ];
> > free (func_name);
> > }
> > !
> > return oload_incompatible ? 100 : (oload_non_standard ? 10 : 0);
> > }
> >
> > --- 2960,2966 ----
> > *symp = oload_syms[oload_champ];
> > free (func_name);
> > }
> > ! free(oload_syms);
> > return oload_incompatible ? 100 : (oload_non_standard ? 10 : 0);
> > }
> >
> > -------------------------------------------------
> >
> >
> > Richard Sharman
> >
> > _______________________________________________
> > Bug-gdb mailing list
> > Bug-gdb@gnu.org
> > http://mail.gnu.org/mailman/listinfo/bug-gdb
> >