This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [Bug symtab/8367] [RFA] performance improvement of lookup_partial_symtab
- From: Jerome Guitton <guitton at adacore dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Thu, 15 Jan 2009 10:45:11 +0100
- Subject: Re: [Bug symtab/8367] [RFA] performance improvement of lookup_partial_symtab
- References: <20090114174542.GM84382@adacore.com>
Hmm, wrong MIME type for the attachment (video/dv?). Reposting it
properly. Sorry for the noise.
Jerome Guitton (guitton@adacore.com):
> 2009-01-14 Jerome Guitton <guitton@adacore.com>
>
> * symtab.c (lookup_partial_symtab): When looking up an absolute path
> in the partial symtabs, compare the base names before checking the
> full names.
Index: symtab.c
===================================================================
RCS file: /cvs/src/src/gdb/symtab.c,v
retrieving revision 1.200
diff -u -p -r1.200 symtab.c
--- symtab.c 3 Jan 2009 05:57:53 -0000 1.200
+++ symtab.c 14 Jan 2009 17:10:27 -0000
@@ -281,8 +281,48 @@ lookup_partial_symtab (const char *name)
}
/* If the user gave us an absolute path, try to find the file in
- this symtab and use its absolute path. */
- if (full_path != NULL)
+ this symtab and use its absolute path.
+
+ psymtab_to_fullname has a significant cost as it calls
+ find_and_open_source, which itself does some I/O operation
+ (e.g. open). In cumulative, it can take several seconds with
+ large systems (around 4000 files), if the file is accessed
+ through a slow file system (e.g. NFS). Here is a shell script
+ that you can use to generate such a large system:
+
+ echo "void main () {}" > t.c
+ gcc -c -g t.c
+ previous=""
+ for i in 0 1 2 3 ; do
+ for j in 0 1 2 3 4 5 6 7 8 9 ; do
+ for k in 0 1 2 3 4 5 6 7 8 9 ; do
+ for l in 0 1 2 3 4 5 6 7 8 9 ; do
+ name="${i}${j}${k}${l}"
+ echo "void f_$name () {}" >> f_$name.c
+ gcc -c -g f_$name.c
+ ld -r f_$name.o $previous -o main_$name
+ rm f_*.o
+ rm $previous
+ previous=main_$name
+ done
+ done
+ done
+ done
+ gcc $previous t.o -o main
+
+ Using the following GDB commands should demonstrate the problem:
+ list <working directory>/f_0000.c:1
+ list <working directory>/f_3999.c:1
+
+ To reduce the cost, the full comparison is done if and only if
+ the base names are not different. This would have a low cost,
+ as it only does string manipulations. This optimisation has no
+ impact on relatives path (e.g. the more common 'list
+ f_0000.c:1'), as in this case full_path == NULL. */
+
+ if (full_path != NULL
+ && FILENAME_CMP (lbasename (full_path),
+ lbasename (pst->filename)) == 0)
{
psymtab_to_fullname (pst);
if (pst->fullname != NULL
@@ -292,7 +332,9 @@ lookup_partial_symtab (const char *name)
}
}
- if (real_path != NULL)
+ if (real_path != NULL
+ && FILENAME_CMP (lbasename (full_path),
+ lbasename (pst->filename)) == 0)
{
char *rp = NULL;
psymtab_to_fullname (pst);