From 7d0c9981dc1753663969b47221164504e71676a6 Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Fri, 17 May 2013 18:09:06 +0000 Subject: [PATCH] * NEWS: Mention new maintenance commands check-symtabs, and expand-symtabs, and renamed check-psymtabs. * psymtab.c (maintenance_check_psymtabs): Renamed from maintenance_check_symtabs. Only process already-expanded symbol tables. (_initialize_psymtab): Update. * symmisc.c (maintenance_check_symtabs): New function. (maintenance_expand_name_matcher): New function (maintenance_expand_file_matcher): New function (maintenance_expand_symtabs): New function. (_initialize_symmisc): Add "mt check-symtabs" and "mt expand-symtabs" commands. doc/ * gdb.texinfo (Maintenance Commands): Update doc for "maint check-psymtabs". Add doc for "maint check-symtabs", "maint expand-symtabs". testsuite/ * gdb.base/maint.exp: Update test for "maint check-psymtabs". Add tests for "maint check-symtabs", "maint expand-symtabs". --- gdb/ChangeLog | 15 ++++ gdb/NEWS | 6 ++ gdb/doc/ChangeLog | 6 ++ gdb/doc/gdb.texinfo | 13 ++- gdb/psymtab.c | 45 +++++----- gdb/symmisc.c | 138 +++++++++++++++++++++++++++++++ gdb/testsuite/ChangeLog | 3 + gdb/testsuite/gdb.base/maint.exp | 33 ++++++-- 8 files changed, 232 insertions(+), 27 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f6c82649c5b..0a6694434aa 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,18 @@ +2013-05-17 Doug Evans + + * NEWS: Mention new maintenance commands check-symtabs, and + expand-symtabs, and renamed check-psymtabs. + * psymtab.c (maintenance_check_psymtabs): Renamed from + maintenance_check_symtabs. Only process already-expanded symbol + tables. + (_initialize_psymtab): Update. + * symmisc.c (maintenance_check_symtabs): New function. + (maintenance_expand_name_matcher): New function + (maintenance_expand_file_matcher): New function + (maintenance_expand_symtabs): New function. + (_initialize_symmisc): Add "mt check-symtabs" and "mt expand-symtabs" + commands. + 2013-05-17 Tom Tromey * python/py-inferior.c (infpy_read_memory): Don't call diff --git a/gdb/NEWS b/gdb/NEWS index 7cd164600ac..9ea0b147d23 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -15,6 +15,12 @@ Nios II GNU/Linux nios2*-*-linux * New commands: catch rethrow Like "catch throw", but catches a re-thrown exception. +maint check-psymtabs + Renamed from old "maint check-symtabs". +maint check-symtabs + Perform consistency checks on symtabs. +maint expand-symtabs + Expand symtabs matching an optional regexp. show configuration Display the details of GDB configure-time options. diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index b14e17a010a..5222cd840ec 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,9 @@ +2013-05-17 Doug Evans + + * gdb.texinfo (Maintenance Commands): Update doc for + "maint check-psymtabs". Add doc for "maint check-symtabs", + "maint expand-symtabs". + 2013-05-15 Markus Metzger * gdb.texinfo (Process Record and Replay): Document the diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 02c24087391..1907e59cbb4 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -36356,9 +36356,20 @@ only if non-stop mode is active (@pxref{Non-Stop Mode}) and the target architecture supports displaced stepping. @end table +@kindex maint check-psymtabs +@item maint check-psymtabs +Check the consistency of currently expanded psymtabs versus symtabs. +Use this to check, for example, whether a symbol is in one but not the other. + @kindex maint check-symtabs @item maint check-symtabs -Check the consistency of psymtabs and symtabs. +Check the consistency of currently expanded symtabs. + +@kindex maint expand-symtabs +@item maint expand-symtabs [@var{regexp}] +Expand symbol tables. +If @var{regexp} is specified, only expand symbol tables for file +names matching @var{regexp}. @kindex maint cplus first_component @item maint cplus first_component @var{name} diff --git a/gdb/psymtab.c b/gdb/psymtab.c index 3a1b993fa82..10bd8449a46 100644 --- a/gdb/psymtab.c +++ b/gdb/psymtab.c @@ -2007,10 +2007,10 @@ maintenance_info_psymtabs (char *regexp, int from_tty) } } -/* Check consistency of psymtabs and symtabs. */ +/* Check consistency of currently expanded psymtabs vs symtabs. */ static void -maintenance_check_symtabs (char *ignore, int from_tty) +maintenance_check_psymtabs (char *ignore, int from_tty) { struct symbol *sym; struct partial_symbol **psym; @@ -2025,7 +2025,25 @@ maintenance_check_symtabs (char *ignore, int from_tty) { struct gdbarch *gdbarch = get_objfile_arch (objfile); - s = psymtab_to_symtab (objfile, ps); + /* We don't call psymtab_to_symtab here because that may cause symtab + expansion. When debugging a problem it helps if checkers leave + things unchanged. */ + s = ps->symtab; + + /* First do some checks that don't require the associated symtab. */ + if (ps->texthigh < ps->textlow) + { + printf_filtered ("Psymtab "); + puts_filtered (ps->filename); + printf_filtered (" covers bad range "); + fputs_filtered (paddress (gdbarch, ps->textlow), gdb_stdout); + printf_filtered (" - "); + fputs_filtered (paddress (gdbarch, ps->texthigh), gdb_stdout); + printf_filtered ("\n"); + continue; + } + + /* Now do checks requiring the associated symtab. */ if (s == NULL) continue; bv = BLOCKVECTOR (s); @@ -2063,20 +2081,8 @@ maintenance_check_symtabs (char *ignore, int from_tty) } psym++; } - if (ps->texthigh < ps->textlow) - { - printf_filtered ("Psymtab "); - puts_filtered (ps->filename); - printf_filtered (" covers bad range "); - fputs_filtered (paddress (gdbarch, ps->textlow), gdb_stdout); - printf_filtered (" - "); - fputs_filtered (paddress (gdbarch, ps->texthigh), gdb_stdout); - printf_filtered ("\n"); - continue; - } - if (ps->texthigh == 0) - continue; - if (ps->textlow < BLOCK_START (b) || ps->texthigh > BLOCK_END (b)) + if (ps->texthigh != 0 + && (ps->textlow < BLOCK_START (b) || ps->texthigh > BLOCK_END (b))) { printf_filtered ("Psymtab "); puts_filtered (ps->filename); @@ -2140,7 +2146,8 @@ This does not include information about individual partial symbols,\n\ just the symbol table structures themselves."), &maintenanceinfolist); - add_cmd ("check-symtabs", class_maintenance, maintenance_check_symtabs, - _("Check consistency of psymtabs and symtabs."), + add_cmd ("check-psymtabs", class_maintenance, maintenance_check_psymtabs, + _("\ +Check consistency of currently expanded psymtabs versus symtabs."), &maintenancelist); } diff --git a/gdb/symmisc.c b/gdb/symmisc.c index 52c934ab536..eb8bbbfb2a0 100644 --- a/gdb/symmisc.c +++ b/gdb/symmisc.c @@ -771,6 +771,134 @@ maintenance_info_symtabs (char *regexp, int from_tty) printf_filtered ("}\n"); } } + +/* Check consistency of symtabs. + An example of what this checks for is NULL blockvectors. + They can happen if there's a bug during debug info reading. + GDB assumes they are always non-NULL. + + Note: This does not check for psymtab vs symtab consistency. + Use "maint check-psymtabs" for that. */ + +static void +maintenance_check_symtabs (char *ignore, int from_tty) +{ + struct program_space *pspace; + struct objfile *objfile; + + ALL_PSPACES (pspace) + ALL_PSPACE_OBJFILES (pspace, objfile) + { + struct symtab *symtab; + + /* We don't want to print anything for this objfile until we + actually find something worth printing. */ + int printed_objfile_start = 0; + + ALL_OBJFILE_SYMTABS (objfile, symtab) + { + int found_something = 0; + + QUIT; + + if (symtab->blockvector == NULL) + found_something = 1; + /* Add more checks here. */ + + if (found_something) + { + if (! printed_objfile_start) + { + printf_filtered ("{ objfile %s ", objfile->name); + wrap_here (" "); + printf_filtered ("((struct objfile *) %s)\n", + host_address_to_string (objfile)); + printed_objfile_start = 1; + } + printf_filtered (" { symtab %s\n", + symtab_to_filename_for_display (symtab)); + if (symtab->blockvector == NULL) + printf_filtered (" NULL blockvector\n"); + printf_filtered (" }\n"); + } + } + + if (printed_objfile_start) + printf_filtered ("}\n"); + } +} + +/* Helper function for maintenance_expand_symtabs. + This is the name_matcher function for expand_symtabs_matching. */ + +static int +maintenance_expand_name_matcher (const char *symname, void *data) +{ + /* Since we're not searching on symbols, just return TRUE. */ + return 1; +} + +/* Helper function for maintenance_expand_symtabs. + This is the file_matcher function for expand_symtabs_matching. */ + +static int +maintenance_expand_file_matcher (const char *filename, void *data, + int basenames) +{ + const char *regexp = data; + + QUIT; + + /* KISS: Only apply the regexp to the complete file name. */ + if (basenames) + return 0; + + if (regexp == NULL || re_exec (filename)) + return 1; + + return 0; +} + +/* Expand all symbol tables whose name matches an optional regexp. */ + +static void +maintenance_expand_symtabs (char *args, int from_tty) +{ + struct program_space *pspace; + struct objfile *objfile; + struct cleanup *cleanups; + char **argv; + char *regexp = NULL; + + /* We use buildargv here so that we handle spaces in the regexp + in a way that allows adding more arguments later. */ + argv = gdb_buildargv (args); + cleanups = make_cleanup_freeargv (argv); + + if (argv != NULL) + { + if (argv[0] != NULL) + { + regexp = argv[0]; + if (argv[1] != NULL) + error (_("Extra arguments after regexp.")); + } + } + + if (regexp) + re_comp (regexp); + + ALL_PSPACES (pspace) + ALL_PSPACE_OBJFILES (pspace, objfile) + { + if (objfile->sf) + { + objfile->sf->qf->expand_symtabs_matching + (objfile, maintenance_expand_file_matcher, + maintenance_expand_name_matcher, ALL_DOMAIN, regexp); + } + } +} /* Return the nexting depth of a block within other blocks in its symtab. */ @@ -819,4 +947,14 @@ This does not include information about individual symbols, blocks, or\n\ linetables --- just the symbol table structures themselves.\n\ With an argument REGEXP, list the symbol tables whose names that match that."), &maintenanceinfolist); + + add_cmd ("check-symtabs", class_maintenance, maintenance_check_symtabs, + _("\ +Check consistency of currently expanded symtabs."), + &maintenancelist); + + add_cmd ("expand-symtabs", class_maintenance, maintenance_expand_symtabs, + _("Expand symbol tables.\n\ +With an argument REGEXP, only expand the symbol tables with matching names."), + &maintenancelist); } diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 312177473f3..cb940e141c5 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2013-05-17 Doug Evans + * gdb.base/maint.exp: Update test for "maint check-psymtabs". + Add tests for "maint check-symtabs", "maint expand-symtabs". + * gdb.base/maint.exp: Remove testing of individual maint command help output. diff --git a/gdb/testsuite/gdb.base/maint.exp b/gdb/testsuite/gdb.base/maint.exp index dc59b728143..96090387165 100644 --- a/gdb/testsuite/gdb.base/maint.exp +++ b/gdb/testsuite/gdb.base/maint.exp @@ -20,7 +20,9 @@ # source file used is break.c -#maintenance check-symtabs -- Check consistency of psymtabs and symtabs +#maintenance check-psymtabs -- Check consistency of psymtabs vs symtabs +#maintenance check-symtabs -- Check consistency of symtabs +#maintenance expand-symtabs -- Expand symtabs matching a file regexp #maintenance set -- Set GDB internal variables used by the GDB maintainer #maintenance show -- Show GDB internal variables used by the GDB maintainer #maintenance demangle -- Demangle a C++ mangled name @@ -82,6 +84,18 @@ gdb_file_cmd ${binfile} # program wasn't running. gdb_test "maint print registers" "Name.*Nr.*Rel.*Offset.*Size.*Type.*" +# Test "mt expand-symtabs" here as it's easier to verify before we +# run the program. +gdb_test_no_output "mt set per on" "mt set per on for expand-symtabs" +gdb_test_multiple "mt expand-symtabs $subdir/break\[.\]c$" \ + "mt expand-symtabs" { + -re "#primary symtabs: 1 \\(\[+\]1\\),.*$gdb_prompt $" { + # This should expand exactly one (primary) symtab. + pass "mt expand-symtabs" + } + } +gdb_test "mt set per off" ".*" "mt set per off for expand-symtabs" + # Tests that can or should be done with a running program gdb_load ${binfile} @@ -110,20 +124,25 @@ gdb_test_multiple "maint info sections .gdb_index" "check for .gdb_index" { # guo: on linux this command output is huge. for some reason splitting up # the regexp checks works. # -send_gdb "maint check-symtabs\n" +send_gdb "maint check-psymtabs\n" gdb_expect { - -re "^maint check-symtabs" { + -re "^maint check-psymtabs" { gdb_expect { -re "$gdb_prompt $" { - pass "maint check-symtabs" + pass "maint check-psymtabs" } - timeout { fail "(timeout) maint check-symtabs" } + timeout { fail "(timeout) maint check-psymtabs" } } } - -re ".*$gdb_prompt $" { fail "maint check-symtabs" } - timeout { fail "(timeout) maint check-symtabs" } + -re ".*$gdb_prompt $" { fail "maint check-psymtabs" } + timeout { fail "(timeout) maint check-psymtabs" } } +# This command does not produce any output unless there is some problem +# with the symtabs, so that branch will really never be covered in the +# tests here!! +gdb_test_no_output "maint check-symtabs" + gdb_test_no_output "maint set per-command on" gdb_test "maint set per-command off" \ -- 2.30.2