Tab completion when debugging a program binary that uses GDB index is surprisingly much slower than when GDB uses psymtabs instead. Around 1.5x/3x slower. That's surprising, because the whole point of GDB index is to speed things up... For example, with: set pagination off set $count = 0 while $count < 400 complete b string_prin # matches gdb's string_printf printf "count = %d\n", $count set $count = $count + 1 end $ time ./gdb --batch -q ./gdb-with-index -ex "source script.cmd" real 0m11.042s user 0m10.920s sys 0m0.042s $ time ./gdb --batch -q ./gdb-without-index -ex "source script.cmd" real 0m4.635s user 0m4.590s sys 0m0.037s Same but with: - complete b string_prin + complete b zzzzzz to exercise the no-matches worst case, master currently gets you something like: with index without index real 0m11.971s 0m8.413s user 0m11.912s 0m8.355s sys 0m0.035s 0m0.035s Running gdb under perf shows 80% spent inside maybe_add_partial_symtab_filename, and 20% spent in the lbasename inside that. The problem that tab completion walks over all compunit symtabs, and for each, walks the contained file symtabs. And there a huge number of file symtabs (each included system header, etc.) that appear in each compunit symtab's file symtab list. As in, when debugging GDB, I have 367381 symtabs iterated, when of those only 5371 filenames are unique... This was a regression from the earlier (nice) split of symtabs in compunit symtabs + file symtabs. The fix here is to add a cache of unique filenames per objfile so that the walk / uniquing is only done once. There's already a abstraction for this in symtab.c; this patch moves that code out to a separate file and C++ifies it bit. This makes the worst-case scenario above consistently drop to ~2.5s (1.5s for the "string_prin" hit case), making it over 3.3x times faster than psymtabs in this use case (7x in the "string_prin" hit case). gdb/ChangeLog: 2017-07-17 Pedro Alves <palves@redhat.com> * Makefile.in (COMMON_OBS): Add filename-seen-cache.o. * dwarf2read.c: Include "filename-seen-cache.h". * dwarf2read.c (dwarf2_per_objfile) <filenames_cache>: New field. (dw2_map_symbol_filenames): Build and use a filenames_seen_cache. * filename-seen-cache.c: New file. * filename-seen-cache.h: New file. * symtab.c: Include "filename-seen-cache.h". (struct filename_seen_cache, INITIAL_FILENAME_SEEN_CACHE_SIZE) (create_filename_seen_cache, clear_filename_seen_cache) (delete_filename_seen_cache, filename_seen): Delete, parts moved to filename-seen-cache.h/filename-seen-cache.c. (output_source_filename, sources_info) (maybe_add_partial_symtab_filename) (make_source_files_completion_list): Adjust to use filename_seen_cache. |
||
|---|---|---|
| bfd | ||
| binutils | ||
| config | ||
| cpu | ||
| elfcpp | ||
| etc | ||
| gas | ||
| gdb | ||
| gold | ||
| gprof | ||
| include | ||
| intl | ||
| ld | ||
| libdecnumber | ||
| libiberty | ||
| opcodes | ||
| readline | ||
| sim | ||
| texinfo | ||
| zlib | ||
| .cvsignore | ||
| .gitattributes | ||
| .gitignore | ||
| ChangeLog | ||
| compile | ||
| config-ml.in | ||
| config.guess | ||
| config.rpath | ||
| config.sub | ||
| configure | ||
| configure.ac | ||
| COPYING | ||
| COPYING3 | ||
| COPYING3.LIB | ||
| COPYING.LIB | ||
| COPYING.LIBGLOSS | ||
| COPYING.NEWLIB | ||
| depcomp | ||
| djunpack.bat | ||
| install-sh | ||
| libtool.m4 | ||
| lt~obsolete.m4 | ||
| ltgcc.m4 | ||
| ltmain.sh | ||
| ltoptions.m4 | ||
| ltsugar.m4 | ||
| ltversion.m4 | ||
| MAINTAINERS | ||
| Makefile.def | ||
| Makefile.in | ||
| Makefile.tpl | ||
| makefile.vms | ||
| missing | ||
| mkdep | ||
| mkinstalldirs | ||
| move-if-change | ||
| README | ||
| README-maintainer-mode | ||
| setup.com | ||
| src-release.sh | ||
| symlink-tree | ||
| ylwrap | ||
README for GNU development tools This directory contains various GNU compilers, assemblers, linkers, debuggers, etc., plus their support routines, definitions, and documentation. If you are receiving this as part of a GDB release, see the file gdb/README. If with a binutils release, see binutils/README; if with a libg++ release, see libg++/README, etc. That'll give you info about this package -- supported targets, how to use it, how to report bugs, etc. It is now possible to automatically configure and build a variety of tools with one command. To build all of the tools contained herein, run the ``configure'' script here, e.g.: ./configure make To install them (by default in /usr/local/bin, /usr/local/lib, etc), then do: make install (If the configure script can't determine your type of computer, give it the name as an argument, for instance ``./configure sun4''. You can use the script ``config.sub'' to test whether a name is recognized; if it is, config.sub translates it to a triplet specifying CPU, vendor, and OS.) If you have more than one compiler on your system, it is often best to explicitly set CC in the environment before running configure, and to also set CC when running make. For example (assuming sh/bash/ksh): CC=gcc ./configure make A similar example using csh: setenv CC gcc ./configure make Much of the code and documentation enclosed is copyright by the Free Software Foundation, Inc. See the file COPYING or COPYING.LIB in the various directories, for a description of the GNU General Public License terms under which you can copy the files. REPORTING BUGS: Again, see gdb/README, binutils/README, etc., for info on where and how to report problems.