1# Copyright 2018-2020 Free Software Foundation, Inc. 2 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. 7# 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. 12# 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/>. 15 16# This test checks that the index-cache feature generates the expected files at 17# the expected location. 18 19standard_testfile 20 21if { [prepare_for_testing "failed to prepare" $testfile $srcfile \ 22 {debug additional_flags=-Wl,--build-id}] } { 23 return 24} 25 26# The index cache won't be used in certain circumstances, for which we must 27# account in this test: 28# 29# - the binary already has an index section 30# - we use the -readnow switch 31set has_index_section [exec_has_index_section $binfile] 32set uses_readnow [expr [string first "-readnow" $GDBFLAGS] != -1] 33set expecting_index_cache_use [expr !$has_index_section && !$uses_readnow] 34 35# List the files in DIR on the host (where GDB-under-test runs). 36# Return a list of two elements: 37# - 0 on success, -1 on failure 38# - the list of files on success, empty on failure 39 40proc ls_host { dir } { 41 lassign [remote_exec host ls "-1 $dir"] ret output 42 43 if { $ret != 0 } { 44 fail "failed to list files on host in $dir" 45 return -1 46 } 47 48 # ls -1 returns a list separated by \r\n. split will return a bunch of 49 # empty entries (it treats a sequence of split characters as separate 50 # fields, plus there is a \r\n at the end of the result). Ignore empty 51 # list elements. 52 set filtered {} 53 set files [split $output \r\n] 54 55 foreach file $files { 56 if { $file != "" } { 57 lappend filtered $file 58 } 59 } 60 61 return [list 0 $filtered] 62} 63 64# Execute "show index-cache stats" and verify the output against expected 65# values. 66 67proc check_cache_stats { expected_hits expected_misses } { 68 set re [multi_line \ 69 " Cache hits .this session.: $expected_hits" \ 70 "Cache misses .this session.: $expected_misses" \ 71 ] 72 73 gdb_test "show index-cache stats" $re "check index-cache stats" 74} 75 76# Run CODE using a fresh GDB configured based on the other parameters. 77 78proc run_test_with_flags { cache_dir cache_enabled code } { 79 global GDBFLAGS testfile 80 81 save_vars { GDBFLAGS } { 82 set GDBFLAGS "$GDBFLAGS -iex \"set index-cache directory $cache_dir\"" 83 set GDBFLAGS "$GDBFLAGS -iex \"set index-cache $cache_enabled\"" 84 85 clean_restart ${testfile} 86 87 uplevel 1 $code 88 } 89} 90 91# Test administrative stuff. 92 93proc_with_prefix test_basic_stuff { } { 94 global testfile 95 96 clean_restart ${testfile} 97 98 # Check that the index cache is disabled by default. 99 gdb_test \ 100 "show index-cache" \ 101 " is currently disabled." \ 102 "index-cache is disabled by default" 103 104 # Test that we can enable it and "show index-cache" reflects that. 105 gdb_test_no_output "set index-cache on" "enable index cache" 106 gdb_test \ 107 "show index-cache" \ 108 " is currently enabled." \ 109 "index-cache is now enabled" 110 111 # Test the "set/show index-cache directory" commands. 112 gdb_test "set index-cache directory" "Argument required.*" "set index-cache directory without arg" 113 gdb_test_no_output "set index-cache directory /tmp" "change the index cache directory" 114 gdb_test \ 115 "show index-cache directory" \ 116 "The directory of the index cache is \"/tmp\"." \ 117 "show index cache directory" 118} 119 120# Test loading a binary with the cache disabled. No file should be created. 121 122proc_with_prefix test_cache_disabled { cache_dir test_prefix } { 123 with_test_prefix $test_prefix { 124 lassign [ls_host $cache_dir] ret files_before 125 126 run_test_with_flags $cache_dir off { 127 lassign [ls_host $cache_dir] ret files_after 128 129 set nfiles_created [expr [llength $files_after] - [llength $files_before]] 130 gdb_assert "$nfiles_created == 0" "no files were created" 131 132 check_cache_stats 0 0 133 } 134 } 135} 136 137# Test a cache miss. We expect to have at least one file in the cache if the 138# index cache is going to be used (see expecting_index_cache_use) and a cache 139# miss in the stats. If the cache is not going to be used, we expect to have 140# no files and no cache hits nor misses. 141 142proc_with_prefix test_cache_enabled_miss { cache_dir } { 143 global testfile expecting_index_cache_use 144 145 lassign [ls_host $cache_dir] ret files_before 146 147 run_test_with_flags $cache_dir on { 148 149 lassign [ls_host $cache_dir] ret files_after 150 set nfiles_created [expr [llength $files_after] - [llength $files_before]] 151 if { $expecting_index_cache_use } { 152 gdb_assert "$nfiles_created > 0" "at least one file was created" 153 } else { 154 gdb_assert "$nfiles_created == 0" "no file was created" 155 } 156 157 set build_id [get_build_id [standard_output_file ${testfile}]] 158 if { $build_id == "" } { 159 fail "couldn't get executable build id" 160 return 161 } 162 163 set expected_created_file [list "${build_id}.gdb-index"] 164 set found_idx [lsearch -exact $files_after $expected_created_file] 165 if { $expecting_index_cache_use } { 166 gdb_assert "$found_idx >= 0" "expected file is there" 167 } else { 168 gdb_assert "$found_idx == -1" "no index cache file generated" 169 } 170 171 remote_exec host rm "-f $cache_dir/$expected_created_file" 172 173 if { $expecting_index_cache_use } { 174 check_cache_stats 0 1 175 } else { 176 check_cache_stats 0 0 177 } 178 } 179} 180 181 182# Test a cache hit. We should have at least one file in the cache if the index 183# cache is going to be used (see expecting_index_cache_use) and a cache hit in 184# the stats. If the cache is not going to be used, we expect to have no files 185# and no cache hits nor misses. 186 187proc_with_prefix test_cache_enabled_hit { cache_dir } { 188 global expecting_index_cache_use 189 190 # Just to populate the cache. 191 run_test_with_flags $cache_dir on {} 192 193 lassign [ls_host $cache_dir] ret files_before 194 195 run_test_with_flags $cache_dir on { 196 lassign [ls_host $cache_dir] ret files_after 197 set nfiles_created [expr [llength $files_after] - [llength $files_before]] 198 gdb_assert "$nfiles_created == 0" "no files were created" 199 200 if { $expecting_index_cache_use } { 201 check_cache_stats 1 0 202 } else { 203 check_cache_stats 0 0 204 } 205 } 206} 207 208test_basic_stuff 209 210# The cache dir should be on the host (possibly remote), so we can't use the 211# standard output directory for that (it's on the build machine). 212lassign [remote_exec host mktemp -d] ret cache_dir 213 214if { $ret != 0 } { 215 fail "couldn't create temporary cache dir" 216 return 217} 218 219# The ouput of mktemp contains an end of line, remove it. 220set cache_dir [string trimright $cache_dir \r\n] 221 222test_cache_disabled $cache_dir "before populate" 223test_cache_enabled_miss $cache_dir 224test_cache_enabled_hit $cache_dir 225 226# Test again with the cache disabled, now that it is populated. 227test_cache_disabled $cache_dir "after populate" 228 229