[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
gdb "call" very slow on large C++ program; 2 possible patches
From: |
Richard Sharman |
Subject: |
gdb "call" very slow on large C++ program; 2 possible patches |
Date: |
Sat, 17 Nov 2001 22:14:28 -0500 |
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:address@hidden:/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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- gdb "call" very slow on large C++ program; 2 possible patches,
Richard Sharman <=