Since commit
dad36cf91992 ("gdb/dwarf: use dynamic partitioning for
DWARF CU indexing"), we get the intermittent failures:
python print (gdb.lookup_static_symbol ('rr').line)
18
(gdb) FAIL: gdb.python/py-symbol.exp: print line number of rr
python print (gdb.lookup_static_symbol ('rr').value ())
99
(gdb) FAIL: gdb.python/py-symbol.exp: print value of rr
The situation is:
- The program isn't running.
- Two compilation units define a static symbol named `rr`.
- The test does:
gdb.lookup_static_symbol ('rr')
The test expects this to return one specific (out of the two) `rr`
static symbols. Since
dad36cf91992, the call sometimes returns the
wrong symbol.
The documentation for gdb.lookup_static_symbol says this:
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 GDB is
currently stopped, as GDB 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 GDB will search all object
files in the order they appear in the debug information.
cooked_index_functions::search searches index shards linearly and
returns the first matching symbol. Before
dad36cf91992, the work was
split statically among threads, so symbols would end up in shards
deterministically. Since the first part of the debug info ends up in
the first shard, it happens to work as described in the doc.
Since
dad36cf91992, symbols end up in random shards, based on which
thread happened to pop their CU from the work queue.
I don't think that specifying which of the multiple matching static
symbols is returned is really useful, as it unnecessarily restricts the
implementation. If multiple static symbols match the criteria, I think
it makes sense that you'll get an unspecified one. Code that needs to
deal with the possibility of multiple static symbols of the same name
should use gdb.lookup_static_symbols.
I propose to remove this guarantee from gdb.lookup_static_symbol. I
understand that this is a breaking change, but I think it's easy enough
to deal with it.
Update the test to accept either symbol.
Update the doc to say that an unspecified symbol will be returned if the
program is not running and there are multiple matching symbols. The
previous text also seemed a bit wrong about its use of the term "object
file". GDB searches a static symbol for the current compilation unit
first. It then falls back to searching all symbols.
Change-Id: I22f81c186b1483a488ea7614fb81fd102db3c7f1
Approved-By: Tom Tromey <tom@tromey.com>
Reviewed-By: Tom de Vries <tdevries@suse.de>
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33518
Approved-By: Andrew Burgess <aburgess@redhat.com>
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
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
+it finds. Which symbol is found depends on where the program 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.
+symbols in the current compilation unit. If it finds no match, or if
+there is no current compilation unit (perhaps because the program is
+not running), then @code{gdb.lookup_static_symbol} will return an
+unspecified matching symbol. To safely handle the case of multiple
+static symbols with the same name, an application can use
+@code{gdb.lookup_static_symbols}.
@end defun
@defun gdb.lookup_static_symbols (name @r{[}, domain@r{]})
"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"]
-set rr_line_alt [gdb_get_line_number "line of other rr" py-symbol-2.c]
gdb_test "python print (gdb.lookup_global_symbol ('qqrr') is None)" "True" \
"lookup_global_symbol for static var"
-set cmd "python print (gdb.lookup_static_symbol ('rr').line)"
-gdb_test_multiple $cmd "print line number of rr" {
- -re -wrap "$rr_line" {
- pass $gdb_test_name
- }
- -re -wrap "$rr_line_alt" {
- if { $readnow_p } {
- setup_kfail "symtab/25857" *-*-*
- }
- fail $gdb_test_name
- }
-}
-
-set cmd "python print (gdb.lookup_static_symbol ('rr').value ())"
-gdb_test_multiple $cmd "print value of rr" {
- -re -wrap "42" {
- pass $gdb_test_name
- }
- -re -wrap "99" {
- if { $readnow_p } {
- setup_kfail "symtab/25857" *-*-*
- }
- fail $gdb_test_name
- }
-}
+# Either "rr" static symbol is a valid result.
+set rr_line_1 [gdb_get_line_number "line of rr"]
+set rr_line_2 [gdb_get_line_number "line of other rr" py-symbol-2.c]
+gdb_test "python print (gdb.lookup_static_symbol ('rr').line)" "($rr_line_1|$rr_line_2)"
+gdb_test "python print (gdb.lookup_static_symbol ('rr').value ())" "(42|99)"
gdb_test "python print (gdb.lookup_static_symbol ('rr').needs_frame)" \
"False" \