diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 06e5423fbeb..ca0c0c366dc 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2019-11-10 Andrew Burgess + + * python/py-symbol.c (gdbpy_lookup_static_symbol): Lookup in + static block of current object file first. Also fix typo in + header comment. + 2019-11-10 Andrew Burgess * stack.c (set_last_displayed_sal): Delete. diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index ce89ee444ea..6db17b9c8eb 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,8 @@ +2019-11-10 Andrew Burgess + + * python.texi (Symbols In Python): Extend documentation for + gdb.lookup_static_symbol. + 2019-10-31 Andrew Burgess * gdb.texinfo (Symbols): Document new 'info module variables' and diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index 13191fc9ae8..9e227deba90 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -4872,6 +4872,15 @@ Note that this function will not find function-scoped static variables. To look up such variables, iterate over the variables of the function's @code{gdb.Block} and check that @code{block.addr_class} is @code{gdb.SYMBOL_LOC_STATIC}. + +There can be multiple global symbols with static linkage with the same +name. This function will only return the first matching symbol that +it finds. Which symbol is found depends on where @value{GDBN} is +currently stopped, as @value{GDBN} will first search for matching +symbols in the current object file, and then search all other object +files. If the application is not yet running then @value{GDBN} will +search all object files in the order they appear in the debug +information. @end defun A @code{gdb.Symbol} object has the following attributes: diff --git a/gdb/python/py-symbol.c b/gdb/python/py-symbol.c index 2b10e21d872..4c88877bcbe 100644 --- a/gdb/python/py-symbol.c +++ b/gdb/python/py-symbol.c @@ -472,7 +472,7 @@ gdbpy_lookup_global_symbol (PyObject *self, PyObject *args, PyObject *kw) } /* Implementation of - gdb.lookup_static_symbol (name [, domain) -> symbol or None. */ + gdb.lookup_static_symbol (name [, domain]) -> symbol or None. */ PyObject * gdbpy_lookup_static_symbol (PyObject *self, PyObject *args, PyObject *kw) @@ -487,9 +487,32 @@ gdbpy_lookup_static_symbol (PyObject *self, PyObject *args, PyObject *kw) &domain)) return NULL; + /* In order to find static symbols associated with the "current" object + file ahead of those from other object files, we first need to see if + we can acquire a current block. If this fails however, then we still + want to search all static symbols, so don't throw an exception just + yet. */ + const struct block *block = NULL; try { - symbol = lookup_static_symbol (name, (domain_enum) domain).symbol; + struct frame_info *selected_frame + = get_selected_frame (_("No frame selected.")); + block = get_frame_block (selected_frame, NULL); + } + catch (const gdb_exception &except) + { + /* Nothing. */ + } + + try + { + if (block != nullptr) + symbol + = lookup_symbol_in_static_block (name, block, + (domain_enum) domain).symbol; + + if (symbol == nullptr) + symbol = lookup_static_symbol (name, (domain_enum) domain).symbol; } catch (const gdb_exception &except) { diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 9b7bcf64478..e170b7e7bad 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2019-11-10 Andrew Burgess + + * gdb.python/py-symbol.c: Declare and call function from new + py-symbol-2.c file. + * gdb.python/py-symbol.exp: Compile both source files, and add new + tests for gdb.lookup_static_symbol. + * gdb.python/py-symbol-2.c: New file. + 2019-11-02 Tom de Vries * gdb.base/advance.exp: Drop superfluous 3rd argument to gdb_test. diff --git a/gdb/testsuite/gdb.python/py-symbol-2.c b/gdb/testsuite/gdb.python/py-symbol-2.c new file mode 100644 index 00000000000..73ac986972c --- /dev/null +++ b/gdb/testsuite/gdb.python/py-symbol-2.c @@ -0,0 +1,24 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2019 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +static int rr = 99; /* line of other rr */ + +void +function_in_other_file (void) +{ + /* Nothing. */ +} diff --git a/gdb/testsuite/gdb.python/py-symbol.c b/gdb/testsuite/gdb.python/py-symbol.c index 06a931bf5d9..51325dcd450 100644 --- a/gdb/testsuite/gdb.python/py-symbol.c +++ b/gdb/testsuite/gdb.python/py-symbol.c @@ -38,6 +38,10 @@ namespace { }; #endif +#ifdef USE_TWO_FILES +extern void function_in_other_file (void); +#endif + int qq = 72; /* line of qq */ static int rr = 42; /* line of rr */ @@ -70,5 +74,10 @@ int main (int argc, char *argv[]) sclass.seti (42); sclass.valueofi (); #endif + +#ifdef USE_TWO_FILES + function_in_other_file (); +#endif + return 0; /* Break at end. */ } diff --git a/gdb/testsuite/gdb.python/py-symbol.exp b/gdb/testsuite/gdb.python/py-symbol.exp index 5617f127e5b..61960075565 100644 --- a/gdb/testsuite/gdb.python/py-symbol.exp +++ b/gdb/testsuite/gdb.python/py-symbol.exp @@ -18,9 +18,11 @@ load_lib gdb-python.exp -standard_testfile +standard_testfile py-symbol.c py-symbol-2.c -if {[prepare_for_testing "failed to prepare" $testfile $srcfile debug]} { +set opts { debug additional_flags=-DUSE_TWO_FILES } +if {[prepare_for_testing "failed to prepare" $testfile \ + [list $srcfile $srcfile2] $opts]} { return -1 } @@ -48,6 +50,7 @@ gdb_test "python print (gdb.lookup_global_symbol('qq').needs_frame)" \ "False" \ "print whether qq needs a frame" +# Similarly, test looking up a static symbol before we runto_main. set rr_line [gdb_get_line_number "line of rr"] gdb_test "python print (gdb.lookup_global_symbol ('rr') is None)" "True" \ "lookup_global_symbol for static var" @@ -100,10 +103,23 @@ gdb_test "python print (func.print_name)" "func" "test func.print_name" gdb_test "python print (func.linkage_name)" "func" "test func.linkage_name" gdb_test "python print (func.addr_class == gdb.SYMBOL_LOC_BLOCK)" "True" "test func.addr_class" -gdb_breakpoint [gdb_get_line_number "Break at end."] +# Stop in a second file and ensure we find its local static symbol. +gdb_breakpoint "function_in_other_file" +gdb_continue_to_breakpoint "function_in_other_file" +gdb_test "python print (gdb.lookup_static_symbol ('rr').value ())" "99" \ + "print value of rr from other file" + +# Now continue back to the first source file. +set linenum [gdb_get_line_number "Break at end."] +gdb_breakpoint "$srcfile:$linenum" gdb_continue_to_breakpoint "Break at end for variable a" ".*Break at end.*" gdb_py_test_silent_cmd "python frame = gdb.selected_frame()" "Get Frame" 0 +# Check that we find the static sybol local to this file over the +# static symbol from the second source file. +gdb_test "python print (gdb.lookup_static_symbol ('rr').value ())" "42" \ + "print value of rr from main file" + # Test is_variable attribute. gdb_py_test_silent_cmd "python a = gdb.lookup_symbol(\'a\')" "Get variable a" 0 gdb_test "python print (a\[0\].is_variable)" "True" "test a.is_variable" @@ -145,17 +161,12 @@ gdb_test "python print (t\[0\].symtab)" "${py_symbol_c}" "get symtab" # C++ tests # Recompile binary. -if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}-cxx" executable "debug c++"] != "" } { - untested "failed to compile in C++ mode" +lappend opts c++ +if {[prepare_for_testing "failed to prepare" "${binfile}-cxx" \ + [list $srcfile $srcfile2] $opts]} { return -1 } -# Start with a fresh gdb. -gdb_exit -gdb_start -gdb_reinitialize_dir $srcdir/$subdir -gdb_load ${binfile}-cxx - gdb_test "python print (gdb.lookup_global_symbol ('(anonymous namespace)::anon') is None)" \ "True" "anon is None" gdb_test "python print (gdb.lookup_static_symbol ('(anonymous namespace)::anon').value ())" \ @@ -189,7 +200,7 @@ gdb_test "python print (cplusfunc.addr_class == gdb.SYMBOL_LOC_BLOCK)" "True" "t # Test is_valid when the objfile is unloaded. This must be the last # test as it unloads the object file in GDB. # Start with a fresh gdb. -clean_restart ${testfile} +clean_restart ${binfile} if ![runto_main] then { fail "cannot run to main." return 0