mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-16 12:28:46 +00:00
Running tclint on the test-cases in gdb.gdb shows a few problems. Fix these. Tested on x86_64-linux.
187 lines
5.7 KiB
Plaintext
187 lines
5.7 KiB
Plaintext
# Copyright 2023-2025 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 <http://www.gnu.org/licenses/>.
|
|
|
|
# Load the GDB executable, and then 'save gdb-index', and make some
|
|
# checks of the generated index file.
|
|
|
|
load_lib selftest-support.exp
|
|
|
|
# Can't save an index with readnow.
|
|
require !readnow
|
|
|
|
# A multiplier used to ensure slow tasks are less likely to timeout.
|
|
set timeout_factor 20
|
|
|
|
set filename [selftest_prepare]
|
|
if { $filename eq "" } {
|
|
unsupported "${gdb_test_file_name}.exp"
|
|
return -1
|
|
}
|
|
|
|
# If FILENAME is a libtool wrapper, then we need to get the path of the real
|
|
# executable.
|
|
set filename [selftest_libtool_get_real_gdb_executable $filename]
|
|
if { $filename eq "" } {
|
|
return -1
|
|
}
|
|
|
|
with_timeout_factor $timeout_factor {
|
|
# Start GDB, load FILENAME.
|
|
clean_restart
|
|
gdb_load $filename
|
|
}
|
|
|
|
# Record how many worker threads GDB is using.
|
|
set worker_threads [gdb_get_worker_threads]
|
|
|
|
if { $worker_threads eq "UNKNOWN" } {
|
|
unresolved "unable to get worker thread count"
|
|
return -1
|
|
}
|
|
|
|
# Generate an index file.
|
|
set dir1 [standard_output_file "index_1"]
|
|
remote_exec host "mkdir -p ${dir1}"
|
|
with_timeout_factor $timeout_factor {
|
|
set ok 0
|
|
gdb_test_multiple "save gdb-index $dir1" "create gdb-index file" {
|
|
-re -wrap "Error while writing index for \[^\r\n\]*: No debugging symbols" {
|
|
unsupported $gdb_test_name
|
|
}
|
|
-re -wrap "^" {
|
|
pass $gdb_test_name
|
|
set ok 1
|
|
}
|
|
}
|
|
if { ! $ok } {
|
|
return -1
|
|
}
|
|
|
|
gdb_test_no_output "save gdb-index -dwarf-5 $dir1" \
|
|
"create dwarf-index files"
|
|
}
|
|
|
|
# Close GDB.
|
|
gdb_exit
|
|
|
|
# Validate that the index-file FILENAME has made efficient use of its
|
|
# symbol hash table. Calculate the number of symbols in the hash
|
|
# table and the total hash table size. The hash table starts with
|
|
# 1024 entries, and then doubles each time it is filled to 75%. At
|
|
# 75% filled, doubling the size takes it to 37.5% filled.
|
|
#
|
|
# Thus, the hash table is correctly filled if:
|
|
# 1. Its size is 1024 (i.e. it has not yet had its first doubling), or
|
|
# 2. Its filled percentage is over 37%
|
|
#
|
|
# We could check that it is not over filled, but I don't as that's not
|
|
# really an issue. But we did once have a bug where the table was
|
|
# doubled incorrectly, in which case we'd see a filled percentage of
|
|
# around 2% in some cases, which is a huge waste of disk space.
|
|
proc check_symbol_table_usage { filename } {
|
|
# Open the file in binary mode and read-only mode.
|
|
set fp [open $filename rb]
|
|
|
|
# Configure the channel to use binary translation.
|
|
fconfigure $fp -translation binary
|
|
|
|
# Read the first 8 bytes of the file, which contain the header of
|
|
# the index section.
|
|
set header [read $fp [expr 7 * 4]]
|
|
|
|
# Scan the header to get the version, the CU list offset, and the
|
|
# types CU list offset.
|
|
binary scan $header iiiiii version \
|
|
_ _ _ symbol_table_offset shortcut_offset
|
|
|
|
# The length of the symbol hash table (in entries).
|
|
set len [expr {($shortcut_offset - $symbol_table_offset) / 8}]
|
|
|
|
# Now walk the hash table and count how many entries are in use.
|
|
set offset $symbol_table_offset
|
|
set count 0
|
|
while { $offset < $shortcut_offset } {
|
|
seek $fp $offset
|
|
set entry [read $fp 8]
|
|
binary scan $entry ii name_ptr flags
|
|
if { $name_ptr != 0 } {
|
|
incr count
|
|
}
|
|
|
|
incr offset 8
|
|
}
|
|
|
|
# Close the file.
|
|
close $fp
|
|
|
|
# Calculate how full the cache is.
|
|
set pct [expr {(100 * double($count)) / $len}]
|
|
|
|
# Write our results out to the gdb.log.
|
|
verbose -log "Hash table size: $len"
|
|
verbose -log "Hash table entries: $count"
|
|
verbose -log "Percentage usage: $pct%"
|
|
|
|
# The minimum fill percentage is actually 37.5%, but we give TCL a
|
|
# little flexibility in case the FP maths give a result a little
|
|
# off.
|
|
gdb_assert { $len == 1024 || $pct > 37 } \
|
|
"symbol hash table usage"
|
|
}
|
|
|
|
set index_filename_base [file tail $filename]
|
|
check_symbol_table_usage "$dir1/${index_filename_base}.gdb-index"
|
|
|
|
# If GDB is using more than 1 worker thread then reduce the number of
|
|
# worker threads, regenerate the index, and check that we get the same
|
|
# index file back. At one point the layout of the index would vary
|
|
# based on the number of worker threads used.
|
|
if { $worker_threads > 1 } {
|
|
# Start GDB, but don't load a file yet.
|
|
clean_restart
|
|
|
|
# Adjust the number of threads to use.
|
|
set reduced_threads [expr {$worker_threads / 2}]
|
|
gdb_test_no_output "maint set worker-threads $reduced_threads"
|
|
|
|
with_timeout_factor $timeout_factor {
|
|
# Now load the test binary.
|
|
gdb_file_cmd $filename
|
|
}
|
|
|
|
# Generate an index file.
|
|
set dir2 [standard_output_file "index_2"]
|
|
remote_exec host "mkdir -p ${dir2}"
|
|
with_timeout_factor $timeout_factor {
|
|
gdb_test_no_output "save gdb-index $dir2" \
|
|
"create second gdb-index file"
|
|
|
|
gdb_test_no_output "save gdb-index -dwarf-5 $dir2" \
|
|
"create second dwarf-index files"
|
|
}
|
|
|
|
# Close GDB.
|
|
gdb_exit
|
|
|
|
# Now check that the index files are identical.
|
|
foreach suffix { gdb-index debug_names debug_str } {
|
|
set result \
|
|
[remote_exec host \
|
|
"cmp -s \"$dir1/${index_filename_base}.${suffix}\" \"$dir2/${index_filename_base}.${suffix}\""]
|
|
gdb_assert { [lindex $result 0] == 0 } \
|
|
"$suffix files are identical"
|
|
}
|
|
}
|