Fix C++ template function matching in cooked index
[binutils-gdb.git] / gdb / testsuite / gdb.gdb / index-file.exp
blobc30f417b12808007d378b067ca7ddb00c4bd7e35
1 # Copyright 2023-2024 Free Software Foundation, Inc.
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 3 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 # Load the GDB executable, and then 'save gdb-index', and make some
17 # checks of the generated index file.
19 load_lib selftest-support.exp
21 # Can't save an index with readnow.
22 require !readnow
24 # A multiplier used to ensure slow tasks are less likely to timeout.
25 set timeout_factor 20
27 set filename [selftest_prepare]
28 if { $filename eq "" } {
29     unsupported "${gdb_test_file_name}.exp"
30     return -1
33 with_timeout_factor $timeout_factor {
34     # Start GDB, load FILENAME.
35     clean_restart $filename
38 # Record how many worker threads GDB is using.
39 set worker_threads [gdb_get_worker_threads]
41 if { $worker_threads eq "UNKNOWN" } {
42     unresolved "unable to get worker thread count"
43     return -1
46 # Generate an index file.
47 set dir1 [standard_output_file "index_1"]
48 remote_exec host "mkdir -p ${dir1}"
49 with_timeout_factor $timeout_factor {
50     set ok 0
51     gdb_test_multiple "save gdb-index $dir1" "create gdb-index file" {
52         -re -wrap "Error while writing index for \[^\r\n\]*: No debugging symbols" {
53             unsupported $gdb_test_name
54         }
55         -re -wrap "^" {
56             pass $gdb_test_name
57             set ok 1
58         }
59     }
60     if { ! $ok } {
61         return -1
62     }
64     gdb_test_no_output "save gdb-index -dwarf-5 $dir1" \
65         "create dwarf-index files"
68 # Close GDB.
69 gdb_exit
71 # Validate that the index-file FILENAME has made efficient use of its
72 # symbol hash table.  Calculate the number of symbols in the hash
73 # table and the total hash table size.  The hash table starts with
74 # 1024 entries, and then doubles each time it is filled to 75%.  At
75 # 75% filled, doubling the size takes it to 37.5% filled.
77 # Thus, the hash table is correctly filled if:
78 #  1. Its size is 1024 (i.e. it has not yet had its first doubling), or
79 #  2. Its filled percentage is over 37%
81 # We could check that it is not over filled, but I don't as that's not
82 # really an issue.  But we did once have a bug where the table was
83 # doubled incorrectly, in which case we'd see a filled percentage of
84 # around 2% in some cases, which is a huge waste of disk space.
85 proc check_symbol_table_usage { filename } {
86     # Open the file in binary mode and read-only mode.
87     set fp [open $filename rb]
89     # Configure the channel to use binary translation.
90     fconfigure $fp -translation binary
92     # Read the first 8 bytes of the file, which contain the header of
93     # the index section.
94     set header [read $fp [expr 7 * 4]]
96     # Scan the header to get the version, the CU list offset, and the
97     # types CU list offset.
98     binary scan $header iiiiii version \
99         _ _ _ symbol_table_offset shortcut_offset
101     # The length of the symbol hash table (in entries).
102     set len [expr ($shortcut_offset - $symbol_table_offset) / 8]
104     # Now walk the hash table and count how many entries are in use.
105     set offset $symbol_table_offset
106     set count 0
107     while { $offset < $shortcut_offset } {
108         seek $fp $offset
109         set entry [read $fp 8]
110         binary scan $entry ii name_ptr flags
111         if { $name_ptr != 0 } {
112             incr count
113         }
115         incr offset 8
116     }
118     # Close the file.
119     close $fp
121     # Calculate how full the cache is.
122     set pct [expr (100 * double($count)) / $len]
124     # Write our results out to the gdb.log.
125     verbose -log "Hash table size: $len"
126     verbose -log "Hash table entries: $count"
127     verbose -log "Percentage usage: $pct%"
129     # The minimum fill percentage is actually 37.5%, but we give TCL a
130     # little flexibility in case the FP maths give a result a little
131     # off.
132     gdb_assert { $len == 1024 || $pct > 37 } \
133         "symbol hash table usage"
136 set index_filename_base [file tail $filename]
137 check_symbol_table_usage "$dir1/${index_filename_base}.gdb-index"
139 # If GDB is using more than 1 worker thread then reduce the number of
140 # worker threads, regenerate the index, and check that we get the same
141 # index file back.  At one point the layout of the index would vary
142 # based on the number of worker threads used.
143 if { $worker_threads > 1 } {
144     # Start GDB, but don't load a file yet.
145     clean_restart
147     # Adjust the number of threads to use.
148     set reduced_threads [expr $worker_threads / 2]
149     gdb_test_no_output "maint set worker-threads $reduced_threads"
151     with_timeout_factor $timeout_factor {
152         # Now load the test binary.
153         gdb_file_cmd $filename
154     }
156     # Generate an index file.
157     set dir2 [standard_output_file "index_2"]
158     remote_exec host "mkdir -p ${dir2}"
159     with_timeout_factor $timeout_factor {
160         gdb_test_no_output "save gdb-index $dir2" \
161             "create second gdb-index file"
163         gdb_test_no_output "save gdb-index -dwarf-5 $dir2" \
164             "create second dwarf-index files"
165     }
167     # Close GDB.
168     gdb_exit
170     # Now check that the index files are identical.
171     foreach suffix { gdb-index debug_names debug_str } {
172         set result \
173             [remote_exec host \
174                  "cmp -s \"$dir1/${index_filename_base}.${suffix}\" \"$dir2/${index_filename_base}.${suffix}\""]
175         gdb_assert { [lindex $result 0] == 0 } \
176             "$suffix files are identical"
177     }