1 1.1.1.4 christos # Copyright 2018-2024 Free Software Foundation, Inc. 2 1.1 christos 3 1.1 christos # This program is free software; you can redistribute it and/or modify 4 1.1 christos # it under the terms of the GNU General Public License as published by 5 1.1 christos # the Free Software Foundation; either version 3 of the License, or 6 1.1 christos # (at your option) any later version. 7 1.1 christos # 8 1.1 christos # This program is distributed in the hope that it will be useful, 9 1.1 christos # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 1.1 christos # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 1.1 christos # GNU General Public License for more details. 12 1.1 christos # 13 1.1 christos # You should have received a copy of the GNU General Public License 14 1.1 christos # along with this program. If not, see <http://www.gnu.org/licenses/>. 15 1.1 christos 16 1.1 christos # This test checks that the index-cache feature generates the expected files at 17 1.1 christos # the expected location. 18 1.1 christos 19 1.1.1.4 christos standard_testfile .c -2.c 20 1.1 christos 21 1.1.1.4 christos if { [build_executable "failed to prepare" $testfile [list $srcfile $srcfile2] \ 22 1.1.1.5 christos {debug build-id}] } { 23 1.1 christos return 24 1.1 christos } 25 1.1 christos 26 1.1.1.2 christos # The index cache won't be used in certain circumstances, for which we must 27 1.1.1.2 christos # account in this test: 28 1.1.1.2 christos # 29 1.1.1.2 christos # - the binary already has an index section 30 1.1.1.2 christos # - we use the -readnow switch 31 1.1.1.2 christos set has_index_section [exec_has_index_section $binfile] 32 1.1.1.2 christos set uses_readnow [expr [string first "-readnow" $GDBFLAGS] != -1] 33 1.1.1.2 christos set expecting_index_cache_use [expr !$has_index_section && !$uses_readnow] 34 1.1.1.2 christos 35 1.1 christos # List the files in DIR on the host (where GDB-under-test runs). 36 1.1 christos # Return a list of two elements: 37 1.1 christos # - 0 on success, -1 on failure 38 1.1 christos # - the list of files on success, empty on failure 39 1.1 christos 40 1.1 christos proc ls_host { dir } { 41 1.1 christos lassign [remote_exec host ls "-1 $dir"] ret output 42 1.1 christos 43 1.1 christos if { $ret != 0 } { 44 1.1 christos fail "failed to list files on host in $dir" 45 1.1 christos return -1 46 1.1 christos } 47 1.1 christos 48 1.1 christos # ls -1 returns a list separated by \r\n. split will return a bunch of 49 1.1 christos # empty entries (it treats a sequence of split characters as separate 50 1.1 christos # fields, plus there is a \r\n at the end of the result). Ignore empty 51 1.1 christos # list elements. 52 1.1 christos set filtered {} 53 1.1 christos set files [split $output \r\n] 54 1.1 christos 55 1.1 christos foreach file $files { 56 1.1 christos if { $file != "" } { 57 1.1 christos lappend filtered $file 58 1.1 christos } 59 1.1 christos } 60 1.1 christos 61 1.1.1.2 christos return [list 0 $filtered] 62 1.1 christos } 63 1.1 christos 64 1.1 christos # Execute "show index-cache stats" and verify the output against expected 65 1.1 christos # values. 66 1.1 christos 67 1.1 christos proc check_cache_stats { expected_hits expected_misses } { 68 1.1.1.4 christos # This test wants to check the cache, so make sure it has completed 69 1.1.1.4 christos # its work. 70 1.1.1.4 christos gdb_test_no_output "maintenance wait-for-index-cache" 71 1.1.1.4 christos 72 1.1 christos set re [multi_line \ 73 1.1 christos " Cache hits .this session.: $expected_hits" \ 74 1.1 christos "Cache misses .this session.: $expected_misses" \ 75 1.1 christos ] 76 1.1 christos 77 1.1 christos gdb_test "show index-cache stats" $re "check index-cache stats" 78 1.1 christos } 79 1.1 christos 80 1.1 christos # Run CODE using a fresh GDB configured based on the other parameters. 81 1.1 christos 82 1.1 christos proc run_test_with_flags { cache_dir cache_enabled code } { 83 1.1 christos global GDBFLAGS testfile 84 1.1 christos 85 1.1 christos save_vars { GDBFLAGS } { 86 1.1 christos set GDBFLAGS "$GDBFLAGS -iex \"set index-cache directory $cache_dir\"" 87 1.1.1.3 christos set GDBFLAGS "$GDBFLAGS -iex \"set index-cache enabled $cache_enabled\"" 88 1.1 christos 89 1.1.1.5 christos clean_restart 90 1.1.1.5 christos 91 1.1.1.5 christos gdb_test_no_output "maint set dwarf synchronous on" 92 1.1.1.5 christos 93 1.1.1.5 christos gdb_load $::binfile 94 1.1 christos 95 1.1 christos uplevel 1 $code 96 1.1 christos } 97 1.1 christos } 98 1.1 christos 99 1.1 christos # Test administrative stuff. 100 1.1 christos 101 1.1 christos proc_with_prefix test_basic_stuff { } { 102 1.1 christos global testfile 103 1.1 christos 104 1.1 christos clean_restart ${testfile} 105 1.1 christos 106 1.1 christos # Check that the index cache is disabled by default. 107 1.1 christos gdb_test \ 108 1.1.1.3 christos "show index-cache enabled" \ 109 1.1.1.3 christos "The index cache is off." \ 110 1.1 christos "index-cache is disabled by default" 111 1.1 christos 112 1.1.1.3 christos # Test that we can enable it and "show index-cache enabled" reflects that. 113 1.1.1.3 christos gdb_test_no_output "set index-cache enabled on" "enable index cache" 114 1.1 christos gdb_test \ 115 1.1.1.3 christos "show index-cache enabled" \ 116 1.1.1.3 christos "The index cache is on." \ 117 1.1 christos "index-cache is now enabled" 118 1.1 christos 119 1.1.1.3 christos with_test_prefix "deprecated commands" { 120 1.1.1.3 christos gdb_test "set index-cache off" ".*is deprecated.*" "disable index cache" 121 1.1.1.3 christos gdb_test \ 122 1.1.1.3 christos "show index-cache enabled" \ 123 1.1.1.3 christos "The index cache is off." \ 124 1.1.1.3 christos "index-cache is now disabled" 125 1.1.1.3 christos gdb_test "set index-cache on" ".*is deprecated.*" "enable index cache" 126 1.1.1.3 christos gdb_test \ 127 1.1.1.3 christos "show index-cache enabled" \ 128 1.1.1.3 christos "The index cache is on." \ 129 1.1.1.3 christos "index-cache is now enabled" 130 1.1.1.3 christos } 131 1.1.1.3 christos 132 1.1 christos # Test the "set/show index-cache directory" commands. 133 1.1 christos gdb_test "set index-cache directory" "Argument required.*" "set index-cache directory without arg" 134 1.1 christos gdb_test_no_output "set index-cache directory /tmp" "change the index cache directory" 135 1.1 christos gdb_test \ 136 1.1 christos "show index-cache directory" \ 137 1.1 christos "The directory of the index cache is \"/tmp\"." \ 138 1.1 christos "show index cache directory" 139 1.1 christos } 140 1.1 christos 141 1.1 christos # Test loading a binary with the cache disabled. No file should be created. 142 1.1 christos 143 1.1.1.2 christos proc_with_prefix test_cache_disabled { cache_dir test_prefix } { 144 1.1.1.2 christos with_test_prefix $test_prefix { 145 1.1.1.2 christos lassign [ls_host $cache_dir] ret files_before 146 1.1 christos 147 1.1.1.2 christos run_test_with_flags $cache_dir off { 148 1.1.1.2 christos lassign [ls_host $cache_dir] ret files_after 149 1.1 christos 150 1.1.1.2 christos set nfiles_created [expr [llength $files_after] - [llength $files_before]] 151 1.1.1.2 christos gdb_assert "$nfiles_created == 0" "no files were created" 152 1.1 christos 153 1.1.1.4 christos # Trigger expansion of symtab containing main, if not already done. 154 1.1.1.4 christos gdb_test "ptype main" "^type = int \\(void\\)" 155 1.1.1.4 christos 156 1.1.1.4 christos # Trigger expansion of symtab not containing main. 157 1.1.1.4 christos gdb_test "ptype foo" "^type = int \\(void\\)" 158 1.1.1.4 christos 159 1.1.1.4 christos # Look for non-existent function. 160 1.1.1.4 christos gdb_test "ptype foobar" "^No symbol \"foobar\" in current context\\." 161 1.1.1.4 christos 162 1.1.1.2 christos check_cache_stats 0 0 163 1.1.1.2 christos } 164 1.1 christos } 165 1.1 christos } 166 1.1 christos 167 1.1.1.2 christos # Test a cache miss. We expect to have at least one file in the cache if the 168 1.1.1.2 christos # index cache is going to be used (see expecting_index_cache_use) and a cache 169 1.1.1.2 christos # miss in the stats. If the cache is not going to be used, we expect to have 170 1.1.1.2 christos # no files and no cache hits nor misses. 171 1.1 christos 172 1.1 christos proc_with_prefix test_cache_enabled_miss { cache_dir } { 173 1.1.1.2 christos global testfile expecting_index_cache_use 174 1.1 christos 175 1.1 christos lassign [ls_host $cache_dir] ret files_before 176 1.1 christos 177 1.1 christos run_test_with_flags $cache_dir on { 178 1.1 christos 179 1.1 christos lassign [ls_host $cache_dir] ret files_after 180 1.1 christos set nfiles_created [expr [llength $files_after] - [llength $files_before]] 181 1.1.1.2 christos if { $expecting_index_cache_use } { 182 1.1.1.2 christos gdb_assert "$nfiles_created > 0" "at least one file was created" 183 1.1.1.2 christos } else { 184 1.1.1.2 christos gdb_assert "$nfiles_created == 0" "no file was created" 185 1.1.1.2 christos } 186 1.1 christos 187 1.1 christos set build_id [get_build_id [standard_output_file ${testfile}]] 188 1.1 christos if { $build_id == "" } { 189 1.1 christos fail "couldn't get executable build id" 190 1.1 christos return 191 1.1 christos } 192 1.1 christos 193 1.1 christos set expected_created_file [list "${build_id}.gdb-index"] 194 1.1 christos set found_idx [lsearch -exact $files_after $expected_created_file] 195 1.1.1.2 christos if { $expecting_index_cache_use } { 196 1.1.1.2 christos gdb_assert "$found_idx >= 0" "expected file is there" 197 1.1.1.2 christos } else { 198 1.1.1.2 christos gdb_assert "$found_idx == -1" "no index cache file generated" 199 1.1.1.2 christos } 200 1.1 christos 201 1.1 christos remote_exec host rm "-f $cache_dir/$expected_created_file" 202 1.1 christos 203 1.1.1.4 christos # Trigger expansion of symtab containing main, if not already done. 204 1.1.1.4 christos gdb_test "ptype main" "^type = int \\(void\\)" 205 1.1.1.4 christos 206 1.1.1.4 christos # Trigger expansion of symtab not containing main. 207 1.1.1.4 christos gdb_test "ptype foo" "^type = int \\(void\\)" 208 1.1.1.4 christos 209 1.1.1.4 christos # Look for non-existent function. 210 1.1.1.4 christos gdb_test "ptype foobar" "^No symbol \"foobar\" in current context\\." 211 1.1.1.4 christos 212 1.1.1.2 christos if { $expecting_index_cache_use } { 213 1.1.1.2 christos check_cache_stats 0 1 214 1.1.1.2 christos } else { 215 1.1.1.2 christos check_cache_stats 0 0 216 1.1.1.2 christos } 217 1.1 christos } 218 1.1 christos } 219 1.1 christos 220 1.1 christos 221 1.1.1.2 christos # Test a cache hit. We should have at least one file in the cache if the index 222 1.1.1.2 christos # cache is going to be used (see expecting_index_cache_use) and a cache hit in 223 1.1.1.2 christos # the stats. If the cache is not going to be used, we expect to have no files 224 1.1.1.2 christos # and no cache hits nor misses. 225 1.1 christos 226 1.1 christos proc_with_prefix test_cache_enabled_hit { cache_dir } { 227 1.1.1.2 christos global expecting_index_cache_use 228 1.1.1.2 christos 229 1.1 christos # Just to populate the cache. 230 1.1.1.4 christos with_test_prefix "populate cache" { 231 1.1.1.4 christos run_test_with_flags $cache_dir on {} 232 1.1.1.4 christos } 233 1.1 christos 234 1.1 christos lassign [ls_host $cache_dir] ret files_before 235 1.1 christos 236 1.1 christos run_test_with_flags $cache_dir on { 237 1.1 christos lassign [ls_host $cache_dir] ret files_after 238 1.1 christos set nfiles_created [expr [llength $files_after] - [llength $files_before]] 239 1.1 christos gdb_assert "$nfiles_created == 0" "no files were created" 240 1.1 christos 241 1.1.1.4 christos # Trigger expansion of symtab containing main, if not already done. 242 1.1.1.4 christos gdb_test "ptype main" "^type = int \\(void\\)" 243 1.1.1.4 christos 244 1.1.1.4 christos # Trigger expansion of symtab not containing main. 245 1.1.1.4 christos gdb_test "ptype foo" "^type = int \\(void\\)" 246 1.1.1.4 christos 247 1.1.1.4 christos # Look for non-existent function. 248 1.1.1.4 christos gdb_test "ptype foobar" "^No symbol \"foobar\" in current context\\." 249 1.1.1.4 christos 250 1.1.1.2 christos if { $expecting_index_cache_use } { 251 1.1.1.2 christos check_cache_stats 1 0 252 1.1.1.2 christos } else { 253 1.1.1.2 christos check_cache_stats 0 0 254 1.1.1.2 christos } 255 1.1 christos } 256 1.1 christos } 257 1.1 christos 258 1.1 christos test_basic_stuff 259 1.1 christos 260 1.1 christos # The cache dir should be on the host (possibly remote), so we can't use the 261 1.1 christos # standard output directory for that (it's on the build machine). 262 1.1 christos lassign [remote_exec host mktemp -d] ret cache_dir 263 1.1 christos 264 1.1 christos if { $ret != 0 } { 265 1.1 christos fail "couldn't create temporary cache dir" 266 1.1 christos return 267 1.1 christos } 268 1.1 christos 269 1.1 christos # The ouput of mktemp contains an end of line, remove it. 270 1.1 christos set cache_dir [string trimright $cache_dir \r\n] 271 1.1 christos 272 1.1.1.2 christos test_cache_disabled $cache_dir "before populate" 273 1.1 christos test_cache_enabled_miss $cache_dir 274 1.1 christos test_cache_enabled_hit $cache_dir 275 1.1 christos 276 1.1 christos # Test again with the cache disabled, now that it is populated. 277 1.1.1.2 christos test_cache_disabled $cache_dir "after populate" 278 1.1 christos 279 1.1.1.4 christos lassign [remote_exec host "sh -c" [quote_for_host rm $cache_dir/*.gdb-index]] ret 280 1.1.1.3 christos if { $ret != 0 && $expecting_index_cache_use } { 281 1.1.1.3 christos fail "couldn't remove files in temporary cache dir" 282 1.1.1.3 christos return 283 1.1.1.3 christos } 284 1.1.1.3 christos 285 1.1.1.3 christos lassign [remote_exec host rmdir "$cache_dir"] ret 286 1.1.1.3 christos if { $ret != 0 } { 287 1.1.1.3 christos fail "couldn't remove temporary cache dir" 288 1.1.1.3 christos return 289 1.1.1.3 christos } 290