1 1.1 christos # Copyright 2021-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 # Test that string values are correctly allocated inside GDB when doing 17 1.1 christos # various operations that yield strings. 18 1.1 christos # 19 1.1 christos # The issue that lead to this test was a missing NULL terminator in the 20 1.1 christos # C-string values. We verify that we can print the null terminator of these 21 1.1 christos # strings. 22 1.1 christos 23 1.1 christos load_lib "trace-support.exp" 24 1.1 christos load_lib "gdb-guile.exp" 25 1.1 christos 26 1.1 christos standard_testfile 27 1.1 christos 28 1.1 christos if {[build_executable "failed to prepare" $testfile $srcfile ]} { 29 1.1 christos return 30 1.1 christos } 31 1.1 christos 32 1.1 christos set user_conv_funcs {$_gdb_setting $_gdb_setting_str} 33 1.1 christos set maint_conv_funcs {$_gdb_maint_setting $_gdb_maint_setting_str} 34 1.1 christos 35 1.1 christos # Add language (LANG) appropriate quotation marks around string STR. 36 1.1 christos proc quote_for_lang {lang str} { 37 1.1 christos if {$lang == "fortran"} { 38 1.1 christos return "'$str'" 39 1.1 christos } else { 40 1.1 christos return "\"$str\"" 41 1.1 christos } 42 1.1 christos } 43 1.1 christos 44 1.1 christos # Check that the string contained in the convenienced variable $v is 45 1.1 christos # EXPECTED_STR. 46 1.1 christos # 47 1.1 christos # In particular, check that the null terminator is there and that we can't 48 1.1 christos # access a character past the end of the string. 49 1.1 christos 50 1.1 christos proc check_v_string { expected_str } { 51 1.1 christos set len [string length $expected_str] 52 1.1 christos 53 1.1 christos for { set i 0 } { $i < $len } { incr i } { 54 1.1 christos set c [string index $expected_str $i] 55 1.1 christos gdb_test "print \$v\[$i\]" "= $::decimal '$c'" 56 1.1 christos } 57 1.1 christos 58 1.1 christos # Check that the string ends with a null terminator. 59 1.1 christos gdb_test "print \$v\[$i\]" {= 0 '\\000'} 60 1.1 christos 61 1.1 christos # Check that we can't access a character after the end of the string. 62 1.1 christos incr i 63 1.1 christos gdb_test "print \$v\[$i\]" "no such vector element" 64 1.1 christos } 65 1.1 christos 66 1.1 christos # Test with string values made by $_gdb_setting & co. 67 1.1 christos 68 1.1 christos proc_with_prefix test_setting { } { 69 1.1 christos clean_restart 70 1.1 christos 71 1.1 christos # This is an internal GDB implementation detail, but the variable backing 72 1.1 christos # a string setting starts as nullptr (unless explicitly initialized at 73 1.1 christos # startup). When assigning an empty value, the variable then points to an 74 1.1 christos # empty string. Test both cases, as it triggers different code paths (in 75 1.1 christos # addition to a non-empty value). 76 1.1 christos # 77 1.1 christos # Use "set trace-user" and "maintenance set test-settings string" as they 78 1.1 christos # are both not initialized at startup. 79 1.1 christos with_test_prefix "user setting" { 80 1.1 christos with_test_prefix "not set" { 81 1.1 christos foreach_with_prefix conv_func $::user_conv_funcs { 82 1.1 christos gdb_test_no_output "set \$v = ${conv_func}(\"trace-user\")" 83 1.1 christos check_v_string "" 84 1.1 christos } 85 1.1 christos } 86 1.1 christos 87 1.1 christos with_test_prefix "set to empty" { 88 1.1 christos gdb_test "set trace-user" 89 1.1 christos foreach_with_prefix conv_func $::user_conv_funcs { 90 1.1 christos gdb_test_no_output "set \$v = ${conv_func}(\"trace-user\")" 91 1.1 christos check_v_string "" 92 1.1 christos } 93 1.1 christos } 94 1.1 christos 95 1.1 christos with_test_prefix "set" { 96 1.1 christos gdb_test "set trace-user poulet" 97 1.1 christos foreach_with_prefix conv_func $::user_conv_funcs { 98 1.1 christos gdb_test_no_output {set $v = $_gdb_setting("trace-user")} 99 1.1 christos check_v_string "poulet" 100 1.1 christos } 101 1.1 christos } 102 1.1 christos } 103 1.1 christos 104 1.1 christos with_test_prefix "maintenance setting" { 105 1.1 christos with_test_prefix "not set" { 106 1.1 christos foreach_with_prefix conv_func $::maint_conv_funcs { 107 1.1 christos gdb_test_no_output \ 108 1.1 christos "set \$v = ${conv_func}(\"test-settings string\")" 109 1.1 christos check_v_string "" 110 1.1 christos } 111 1.1 christos } 112 1.1 christos 113 1.1 christos with_test_prefix "set to empty" { 114 1.1 christos gdb_test "maintenance set test-settings string" 115 1.1 christos foreach_with_prefix conv_func $::maint_conv_funcs { 116 1.1 christos gdb_test_no_output \ 117 1.1 christos "set \$v = ${conv_func}(\"test-settings string\")" 118 1.1 christos check_v_string "" 119 1.1 christos } 120 1.1 christos } 121 1.1 christos 122 1.1 christos with_test_prefix "set" { 123 1.1 christos gdb_test "maintenance set test-settings string perchaude" 124 1.1 christos foreach_with_prefix conv_func $::maint_conv_funcs { 125 1.1 christos gdb_test_no_output \ 126 1.1 christos "set \$v = ${conv_func}(\"test-settings string\")" 127 1.1 christos check_v_string "perchaude" 128 1.1 christos } 129 1.1 christos } 130 1.1 christos } 131 1.1 christos 132 1.1 christos # Test with a non-string setting, this tests yet another code path. 133 1.1 christos with_test_prefix "integer setting" { 134 1.1 christos gdb_test_no_output {set $v = $_gdb_setting_str("remotetimeout")} 135 1.1 christos check_v_string "2" 136 1.1 christos } 137 1.1 christos 138 1.1 christos # Test string values made by $_gdb_setting & co. in all languages. 139 1.1 christos with_test_prefix "all langs" { 140 1.1 christos # Get list of supported languages. 141 1.1 christos set langs [gdb_supported_languages] 142 1.1 christos 143 1.1 christos gdb_test "maintenance set test-settings string foo" 144 1.1 christos foreach_with_prefix lang $langs { 145 1.1 christos gdb_test_no_output "set language $lang" 146 1.1 christos 147 1.1 christos if {$lang == "modula-2"} { 148 1.1 christos # The Modula-2 parser doesn't know how to build a 149 1.1 christos # suitable string expression. 150 1.1 christos gdb_test "print \"foo\"" "strings are not implemented" 151 1.1 christos continue 152 1.1 christos } 153 1.1 christos 154 1.1 christos if {$lang == "rust"} { 155 1.1 christos # Rust strings are actually structs, without a running 156 1.1 christos # inferior into which the string data can be pushed 157 1.1 christos # GDB can't print anything. 158 1.1 christos gdb_test "print \"foo\"" \ 159 1.1 christos "evaluation of this expression requires the target program to be active" 160 1.1 christos gdb_test "print \$_gdb_maint_setting(\"test-settings string\")" \ 161 1.1 christos "evaluation of this expression requires the target program to be active" 162 1.1 christos continue 163 1.1 christos } 164 1.1 christos 165 1.1 christos if {$lang == "unknown"} { 166 1.1 christos # Skipped because expression parsing is not supported 167 1.1 christos # for the "unknown" language. See gdb/28093 for more 168 1.1 christos # details. 169 1.1 christos continue 170 1.1 christos } 171 1.1 christos 172 1.1 christos set print_output "" 173 1.1 christos set ptype_output "" 174 1.1 christos 175 1.1 christos set foo_str [quote_for_lang $lang foo] 176 1.1 christos gdb_test_multiple "print $foo_str" "" { 177 1.1 christos -wrap -re " = (.*)" { 178 1.1 christos set print_output $expect_out(1,string) 179 1.1 christos pass $gdb_test_name 180 1.1 christos } 181 1.1 christos } 182 1.1 christos 183 1.1 christos gdb_test_multiple "ptype $foo_str" "" { 184 1.1 christos -wrap -re " = (.*)" { 185 1.1 christos set ptype_output $expect_out(1,string) 186 1.1 christos pass $gdb_test_name 187 1.1 christos } 188 1.1 christos } 189 1.1 christos 190 1.1 christos set cmd_str [quote_for_lang $lang "test-settings string"] 191 1.1 christos set ptype_output_re [string_to_regexp $ptype_output] 192 1.1 christos set print_output_re [string_to_regexp $print_output] 193 1.1 christos 194 1.1 christos foreach_with_prefix conv_func $::maint_conv_funcs { 195 1.1 christos gdb_test "print ${conv_func}($cmd_str)" \ 196 1.1 christos " = $print_output_re" 197 1.1 christos gdb_test "ptype \$" \ 198 1.1 christos " = $ptype_output_re" 199 1.1 christos } 200 1.1 christos } 201 1.1 christos } 202 1.1 christos } 203 1.1 christos 204 1.1 christos # Test with a string value created by gdb.Value in Python. 205 1.1 christos 206 1.1 christos proc_with_prefix test_python_value { } { 207 1.1 christos clean_restart 208 1.1 christos 209 1.1 christos if {![allow_python_tests]} { 210 1.1 christos untested "skipping test_python_value" 211 1.1 christos return 212 1.1 christos } 213 1.1 christos 214 1.1 christos gdb_test_no_output "python gdb.set_convenience_variable(\"v\", \"bar\")" \ 215 1.1 christos "set convenience var" 216 1.1 christos check_v_string "bar" 217 1.1 christos } 218 1.1 christos 219 1.1 christos # Test with a string value created by make-value in Guile. 220 1.1 christos 221 1.1 christos proc_with_prefix test_guile_value { } { 222 1.1 christos clean_restart 223 1.1 christos 224 1.1 christos if {![allow_guile_tests]} { 225 1.1 christos untested "skipping test_guile_value" 226 1.1 christos return 227 1.1 christos } 228 1.1 christos 229 1.1 christos # We can't set a convenience var from Guile, but we can append to history. 230 1.1 christos # Do that, then transfer to a convenience var with a CLI command. 231 1.1 christos gdb_test_no_output "guile (use-modules (gdb))" 232 1.1 christos gdb_test_multiple "guile (history-append! (make-value \"foo\"))" "make value" { 233 1.1 christos -re -wrap "($::decimal)" { 234 1.1 christos set histnum $expect_out(1,string) 235 1.1 christos } 236 1.1 christos } 237 1.1 christos 238 1.1 christos gdb_test_no_output "set \$v = \$$histnum" 239 1.1 christos check_v_string "foo" 240 1.1 christos } 241 1.1 christos 242 1.1 christos # Test with a string value coming from a string internal var. The only internal 243 1.1 christos # vars of this type, at the time of writing, are $trace_func and $trace_file. 244 1.1 christos # They both require inspecting a trace frame. So if the target is capable start 245 1.1 christos # tracing, record one trace frame, and use $trace_func. 246 1.1 christos 247 1.1 christos proc_with_prefix test_internal_var { } { 248 1.1 christos if {![gdb_trace_common_supports_arch]} { 249 1.1 christos unsupported "arch does not support trace" 250 1.1 christos return 251 1.1 christos } 252 1.1 christos 253 1.1 christos clean_restart $::binfile 254 1.1 christos 255 1.1 christos if {![runto_main]} { 256 1.1 christos fail "could not run to main" 257 1.1 christos return 258 1.1 christos } 259 1.1 christos 260 1.1 christos if {![gdb_target_supports_trace]} { 261 1.1 christos unsupported "target does not support trace" 262 1.1 christos return 263 1.1 christos } 264 1.1 christos 265 1.1 christos gdb_breakpoint "end" 266 1.1 christos gdb_test "trace trace_me" "Tracepoint $::decimal at $::hex.*" 267 1.1 christos gdb_test_no_output "tstart" 268 1.1 christos gdb_continue_to_breakpoint "breakpoint at end" 269 1.1 christos gdb_test_no_output "tstop" 270 1.1 christos gdb_test "tfind" "Found trace frame 0, tracepoint $::decimal.*" 271 1.1 christos gdb_test_no_output "set \$v = \$trace_func" 272 1.1 christos gdb_test "tfind none" "No longer looking at any trace frame.*" 273 1.1 christos check_v_string "trace_me" 274 1.1 christos } 275 1.1 christos 276 1.1 christos test_setting 277 1.1 christos test_python_value 278 1.1 christos test_guile_value 279 1.1 christos test_internal_var 280