| 1 | # Copyright 2019-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 | # Test -symbol-info-functions, -symbol-info-variables, and |
| 17 | # -symbol-info-types. |
| 18 | # |
| 19 | # These tests can generate large amounts of output, which can cause gdb to be |
| 20 | # slow in two different ways: |
| 21 | # - it takes long before the command starts producing output |
| 22 | # - it takes long to print all the output |
| 23 | # We can prevent timeouts due to the latter using exp_continue, but for |
| 24 | # the former that doesn't work. There we use with_timeout_factor instead. |
| 25 | |
| 26 | load_lib mi-support.exp |
| 27 | set MIFLAGS "-i=mi" |
| 28 | |
| 29 | standard_testfile mi-sym-info-1.c mi-sym-info-2.c |
| 30 | |
| 31 | if {[prepare_for_testing "failed to prepare" ${testfile} \ |
| 32 | [list $srcfile $srcfile2] {debug}]} { |
| 33 | return -1 |
| 34 | } |
| 35 | |
| 36 | gdb_exit |
| 37 | if {[mi_gdb_start]} { |
| 38 | continue |
| 39 | } |
| 40 | |
| 41 | mi_run_to_main |
| 42 | |
| 43 | set qstr "\"\[^\"\]+\"" |
| 44 | set fun_re "\{line=\"$decimal\",name=${qstr},type=${qstr},description=${qstr}\}" |
| 45 | set type_re "\{(?:line=\"$decimal\",)*name=${qstr}\}" |
| 46 | set sym_list "\\\[${fun_re}(?:,$fun_re)*\\\]" |
| 47 | set type_sym_list "\\\[${type_re}(?:,$type_re)*\\\]" |
| 48 | set symtab_re \ |
| 49 | "\{filename=${qstr},fullname=${qstr},symbols=${sym_list}\}" |
| 50 | set symtab_type_re \ |
| 51 | "\{filename=${qstr},fullname=${qstr},symbols=${type_sym_list}\}" |
| 52 | set debug_only_syms \ |
| 53 | "symbols=\{debug=\\\[${symtab_re}(?:,${symtab_re})*\\\]\}" |
| 54 | set all_syms \ |
| 55 | "symbols=\{debug=\\\[${symtab_re}(?:,${symtab_re})*\\\],nondebug=\\\[.*\\\]\}" |
| 56 | set type_syms \ |
| 57 | "symbols=\{debug=\\\[${symtab_type_re}(?:,${symtab_type_re})*\\\]\}" |
| 58 | |
| 59 | # Fetch all functions, variables and types without any non-debug |
| 60 | # symbols. |
| 61 | set testname "List all functions from debug information only" |
| 62 | set cmd "111-symbol-info-functions" |
| 63 | set state 0 |
| 64 | gdb_test_multiple $cmd $testname -prompt "${mi_gdb_prompt}$" { |
| 65 | -re "111\\^done,symbols=\{debug=\\\[${symtab_re}" { |
| 66 | if { $state == 0 } { incr state } |
| 67 | exp_continue |
| 68 | } |
| 69 | -re ",${symtab_re}" { |
| 70 | exp_continue |
| 71 | } |
| 72 | -re "\\\]\}\r\n${mi_gdb_prompt}$" { |
| 73 | if { $state == 1 } { |
| 74 | pass $gdb_test_name |
| 75 | } else { |
| 76 | fail $gdb_test_name |
| 77 | } |
| 78 | } |
| 79 | } |
| 80 | |
| 81 | set testname "List all variables from debug information only" |
| 82 | set cmd "112-symbol-info-variables" |
| 83 | set state 0 |
| 84 | gdb_test_multiple $cmd $testname -prompt "${mi_gdb_prompt}$" { |
| 85 | -re "112\\^done,symbols=\{debug=\\\[${symtab_re}" { |
| 86 | if { $state == 0 } { incr state } |
| 87 | exp_continue |
| 88 | } |
| 89 | -re ",${symtab_re}" { |
| 90 | exp_continue |
| 91 | } |
| 92 | -re "\\\]\}\r\n${mi_gdb_prompt}$" { |
| 93 | if { $state == 1 } { |
| 94 | pass $gdb_test_name |
| 95 | } else { |
| 96 | fail $gdb_test_name |
| 97 | } |
| 98 | } |
| 99 | } |
| 100 | |
| 101 | set testname "List all types" |
| 102 | set cmd "113-symbol-info-types" |
| 103 | set state 0 |
| 104 | gdb_test_multiple $cmd $testname -prompt "${mi_gdb_prompt}$" { |
| 105 | -re "113\\^done,symbols=\{debug=\\\[${symtab_type_re}" { |
| 106 | if { $state == 0 } { incr state } |
| 107 | exp_continue |
| 108 | } |
| 109 | -re ",${symtab_type_re}" { |
| 110 | exp_continue |
| 111 | } |
| 112 | -re "\\\]\}\r\n${mi_gdb_prompt}$" { |
| 113 | if { $state == 1 } { |
| 114 | pass $gdb_test_name |
| 115 | } else { |
| 116 | fail $gdb_test_name |
| 117 | } |
| 118 | } |
| 119 | } |
| 120 | |
| 121 | # Fetch functions and variables but also grab the non-debug symbols |
| 122 | # (from the symbol table). There's often so much output output from |
| 123 | # this command that we overflow expect's buffers, avoid this by |
| 124 | # fetching the output piece by piece. |
| 125 | set testname "List all functions" |
| 126 | set cmd "114-symbol-info-functions --include-nondebug" |
| 127 | set state 0 |
| 128 | gdb_test_multiple $cmd ${testname} -prompt "${mi_gdb_prompt}$" { |
| 129 | -re "114\\^done,symbols=\{" { |
| 130 | if { $state == 0 } { set state 1 } |
| 131 | exp_continue |
| 132 | } |
| 133 | -re "debug=\\\[${symtab_re}" { |
| 134 | if { $state == 1 } { set state 2 } |
| 135 | exp_continue |
| 136 | } |
| 137 | -re ",${symtab_re}" { |
| 138 | exp_continue |
| 139 | } |
| 140 | -re "\\\],nondebug=\\\[" { |
| 141 | if { $state == 2 } { set state 3 } |
| 142 | exp_continue |
| 143 | } |
| 144 | -re "\{address=${qstr},name=${qstr}\}," { |
| 145 | exp_continue |
| 146 | } |
| 147 | -re "\{address=${qstr},name=${qstr}\}\\\]\}\r\n${mi_gdb_prompt}$" { |
| 148 | if { $state == 3 } { |
| 149 | pass $gdb_test_name |
| 150 | } else { |
| 151 | fail $gdb_test_name |
| 152 | } |
| 153 | } |
| 154 | } |
| 155 | |
| 156 | with_timeout_factor 2 { |
| 157 | set testname "List all variables" |
| 158 | set cmd "115-symbol-info-variables --include-nondebug" |
| 159 | set state 0 |
| 160 | gdb_test_multiple $cmd ${testname} -prompt "${mi_gdb_prompt}$" { |
| 161 | -re "115\\^done,symbols=\{" { |
| 162 | if { $state == 0 } { set state 1 } |
| 163 | exp_continue |
| 164 | } |
| 165 | -re "debug=\\\[${symtab_re}" { |
| 166 | if { $state == 1 } { set state 2 } |
| 167 | exp_continue |
| 168 | } |
| 169 | -re ",${symtab_re}" { |
| 170 | exp_continue |
| 171 | } |
| 172 | -re "\\\],nondebug=\\\[" { |
| 173 | if { $state == 2 } { set state 3 } |
| 174 | exp_continue |
| 175 | } |
| 176 | -re "\{address=${qstr},name=${qstr}\}," { |
| 177 | exp_continue |
| 178 | } |
| 179 | -re "\{address=${qstr},name=${qstr}\}\\\]\}\r\n${mi_gdb_prompt}$" { |
| 180 | if { $state == 3 } { |
| 181 | pass $gdb_test_name |
| 182 | } else { |
| 183 | fail $gdb_test_name |
| 184 | } |
| 185 | } |
| 186 | } |
| 187 | } |
| 188 | |
| 189 | with_timeout_factor 2 { |
| 190 | set testname "List all variables" |
| 191 | set cmd "115-symbol-info-variables --include-nondebug" |
| 192 | set state 0 |
| 193 | gdb_test_multiple $cmd ${testname} -prompt "${mi_gdb_prompt}$" { |
| 194 | -re "115\\^done,symbols=\{" { |
| 195 | if { $state == 0 } { incr state } |
| 196 | exp_continue |
| 197 | } |
| 198 | -re "debug=\\\[${symtab_re}" { |
| 199 | if { $state == 1 } { incr state } |
| 200 | exp_continue |
| 201 | } |
| 202 | -re ",${symtab_re}" { |
| 203 | exp_continue |
| 204 | } |
| 205 | -re "\\\],nondebug=\\\[" { |
| 206 | if { $state == 2 } { incr state } |
| 207 | exp_continue |
| 208 | } |
| 209 | -re "\{address=${qstr},name=${qstr}\}," { |
| 210 | exp_continue |
| 211 | } |
| 212 | -re "\{address=${qstr},name=${qstr}\}\\\]\}\r\n${mi_gdb_prompt}$" { |
| 213 | if { $state == 3 } { |
| 214 | pass $gdb_test_name |
| 215 | } else { |
| 216 | fail $gdb_test_name |
| 217 | } |
| 218 | } |
| 219 | } |
| 220 | } |
| 221 | |
| 222 | # Filter functions by name and type. |
| 223 | set lineno [gdb_get_line_number "f3 (another_int_t arg)" ${srcfile2}] |
| 224 | mi_gdb_test "116-symbol-info-functions --name ^f3$" \ |
| 225 | "116\\^done,symbols=\{debug=\\\[\{filename=\"\[^\"\]*$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[\{line=\"39\",name=\"f3\",type=\"int \\(another_int_t\\)\",description=\"int f3\\(another_int_t\\);\"\}\\\]\}\\\]\}" \ |
| 226 | "List all functions matching pattern f3" |
| 227 | |
| 228 | set lineno [gdb_get_line_number "f4 (int *arg)" ${srcfile}] |
| 229 | mi_gdb_test "117-symbol-info-functions --type void --name ^f4$" \ |
| 230 | "117\\^done,symbols=\{debug=\\\[\{filename=\"\[^\"\]*$srcfile\",fullname=\"\[^\"\]+$srcfile\",symbols=\\\[\{line=\"36\",name=\"f4\",type=\"void \\(int \\*\\)\",description=\"void f4\\(int \\*\\);\"\}\\\]\}\\\]\}" \ |
| 231 | "List all functions matching type void" |
| 232 | |
| 233 | # Filter variables by name and type. |
| 234 | set lineno [gdb_get_line_number "int global_f2;" ${srcfile2}] |
| 235 | mi_gdb_test "118-symbol-info-variables --name global_f2" \ |
| 236 | "118\\^done,symbols=\{debug=\\\[\{filename=\"\[^\"\]*$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[\{line=\"21\",name=\"global_f2\",type=\"int\",description=\"int global_f2;\"\}\\\]\}\\\]\}" \ |
| 237 | "List all variables matching pattern global_f2" |
| 238 | |
| 239 | set lineno1 [gdb_get_line_number "static float global_f1;" ${srcfile}] |
| 240 | set lineno2 [gdb_get_line_number "static float global_f1;" ${srcfile2}] |
| 241 | mi_gdb_test "119-symbol-info-variables --type float --name ^global_" \ |
| 242 | "119\\^done,symbols=\{debug=\\\[\{filename=\"\[^\"\]*$srcfile\",fullname=\"\[^\"\]+$srcfile\",symbols=\\\[\{line=\"25\",name=\"global_f1\",type=\"float\",description=\"static float global_f1;\"\}\\\]\},\{filename=\"\[^\"\]*$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[\{line=\"19\",name=\"global_f1\",type=\"float\",description=\"static float global_f1;\"\}\\\]\}\\\]\}" \ |
| 243 | "List all variables matching type float" |
| 244 | |
| 245 | # Fetch types, filtering by name. |
| 246 | set lineno1 [gdb_get_line_number "typedef int my_int_t;" ${srcfile}] |
| 247 | set lineno2 [gdb_get_line_number "typedef int another_int_t;" ${srcfile2}] |
| 248 | mi_gdb_test "120-symbol-info-types --name _int_" \ |
| 249 | "120\\^done,symbols=\{debug=\\\[\{filename=\"\[^\"\]*$srcfile\",fullname=\"\[^\"\]+$srcfile\",symbols=\\\[\{line=\"27\",name=\"my_int_t\"\}\\\]\},\{filename=\"\[^\"\]*$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[\{line=\"23\",name=\"another_int_t\"\}\\\]\}\\\]\}" \ |
| 250 | "List all types matching _int_" |
| 251 | |
| 252 | # Test the --max-results parameter. |
| 253 | mi_gdb_test "121-symbol-info-functions --max-results 0" \ |
| 254 | "121\\^done,symbols=\{\}" \ |
| 255 | "-symbol-info-functions --max-results 0" |
| 256 | |
| 257 | mi_gdb_test "122-symbol-info-functions --max-results 1 --name ^\[^_\]" \ |
| 258 | "122\\^done,symbols=\{debug=\\\[\{filename=\"\[^\"\]*$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[\{line=\"39\",name=\"f3\",type=\"int \\(another_int_t\\)\",description=\"int f3\\(another_int_t\\);\"\}\\\]\}\\\]\}" \ |
| 259 | "-symbol-info-functions --max-results 1" |
| 260 | |
| 261 | mi_gdb_test "123-symbol-info-functions --max-results 2 --name ^\[^_\]" \ |
| 262 | "123\\^done,symbols=\{debug=\\\[\{filename=\"\[^\"\]*$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[\{line=\"33\",name=\"f2\",type=\"float \\(another_float_t\\)\",description=\"float f2\\(another_float_t\\);\"\},\{line=\"39\",name=\"f3\",type=\"int \\(another_int_t\\)\",description=\"int f3\\(another_int_t\\);\"\}\\\]\}\\\]\}" \ |
| 263 | "-symbol-info-functions --max-results 2" |
| 264 | |
| 265 | mi_gdb_test "124-symbol-info-variables --max-results 3 --name ^\[^_\]" \ |
| 266 | "124\\^done,symbols=\{debug=\\\[\{filename=\"\[^\"\]*$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[\{line=\"21\",name=\"global_f2\",type=\"int\",description=\"int global_f2;\"\},\{line=\"20\",name=\"global_i2\",type=\"int\",description=\"int global_i2;\"\},\{line=\"19\",name=\"global_f1\",type=\"float\",description=\"static float global_f1;\"\}\\\]\}\\\]\}" \ |
| 267 | |
| 268 | set s1 "\{line=\"44\",name=\"another_char_t\"\}" |
| 269 | set s2 "\{line=\"24\",name=\"another_float_t\"\}" |
| 270 | set s3 "\{line=\"23\",name=\"another_int_t\"\}" |
| 271 | set s4 "\{line=\"45\",name=\"another_short_t\"\}" |
| 272 | mi_gdb_test "125-symbol-info-types --max-results 4 --name another_" \ |
| 273 | "125\\^done,symbols=\{debug=\\\[\{filename=\"\[^\"\]*$srcfile2\",fullname=\"\[^\"\]+$srcfile2\",symbols=\\\[$s1,$s2,$s3,$s4\\\]\}\\\]\}" \ |
| 274 | "-symbol-info-types --max-results 4" |