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]
- From: Elena Zannoni <ezannoni at cygnus dot com>
- To: Andrew Cagney <ac131313 at cygnus dot com>
- Cc: gdb at sources dot redhat dot com
- Date: Thu, 6 Dec 2001 17:29:36 -0500
- Subject: Re: [Fwd: gdb "call" very slow on large C++ program; 2 possible patches]
- References: <3C0FE56A.6070203@cygnus.com>
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
> 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
>