Fix C++ template function matching in cooked index
[binutils-gdb.git] / gdb / testsuite / gdb.base / jit-reader.exp
blob2a96207346cc168f71947198ad20d3eeadba18a7
1 # Copyright 2012-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 # Optionally test a Python API here as well.
17 load_lib gdb-python.exp
19 standard_testfile jit-reader-host.c
21 require {is_any_target "i?86-*-*" "x86_64-*-*"} is_lp64_target
23 require allow_shlib_tests isnative
25 # Increase this to see more detail.
26 set test_verbose 0
28 set jit_host_src $srcfile
29 set jit_host_bin $binfile
31 # We inject the complete path to jit-reader.h into the source file
32 # lest we end up (incorrectly) building against a system-installed
33 # version.
34 set jit_reader_header [standard_output_file "../../../../../gdb/jit-reader.h"]
35 set jit_reader_flag "-DJIT_READER_H=\"$jit_reader_header\""
37 if  { [gdb_compile "${srcdir}/${subdir}/${jit_host_src}" "${jit_host_bin}" \
38        executable  [list debug additional_flags=$jit_reader_flag]] != "" } {
39     untested "failed to compile"
40     return -1
43 set jit_reader jit-reader
44 set jit_reader_src ${jit_reader}.c
45 set jit_reader_bin [standard_output_file ${jit_reader}.so]
47 if { [gdb_compile_shlib "${srcdir}/${subdir}/${jit_reader_src}" "${jit_reader_bin}" \
48           [list debug additional_flags=$jit_reader_flag]] != "" } {
49     untested "failed to compile"
50     return -1
53 # Test "info registers" in the current frame, expecting RSP's value to
54 # be SP.
56 proc info_registers_current_frame {sp} {
57     global hex decimal
59     set any "\[^\r\n\]*"
61     set neg_decimal "-?$decimal"
63     set expected \
64         [multi_line \
65              "rax            $hex +$neg_decimal" \
66              "rbx            $hex +$neg_decimal" \
67              "rcx            $hex +$neg_decimal" \
68              "rdx            $hex +$neg_decimal" \
69              "rsi            $hex +$neg_decimal" \
70              "rdi            $hex +$neg_decimal" \
71              "rbp            $hex +$hex" \
72              "rsp            $sp +$sp" \
73              "r8             $hex +$neg_decimal" \
74              "r9             $hex +$neg_decimal" \
75              "r10            $hex +$neg_decimal" \
76              "r11            $hex +$neg_decimal" \
77              "r12            $hex +$neg_decimal" \
78              "r13            $hex +$neg_decimal" \
79              "r14            $hex +$neg_decimal" \
80              "r15            $hex +$neg_decimal" \
81              "rip            $hex +$hex$any" \
82              "eflags         $hex +\\\[$any\\\]" \
83              "cs             $hex +$neg_decimal" \
84              "ss             $hex +$neg_decimal" \
85              "ds             $hex +$neg_decimal" \
86              "es             $hex +$neg_decimal" \
87              "fs             $hex +$neg_decimal" \
88              "gs             $hex +$neg_decimal" \
89             ]
91     # There may be more registers.
92     append expected ".*"
94     gdb_test "info registers" $expected
97 proc jit_reader_test {} {
98     global jit_host_bin
99     global jit_reader_bin
100     global test_verbose
101     global hex decimal
103     set any "\[^\r\n\]*"
105     clean_restart $jit_host_bin
106     gdb_load_shlib $jit_reader_bin
108     if {$test_verbose > 0} {
109         gdb_test_no_output "set debug jit 1"
110     }
112     # Just test that this is installed and prints something.
113     gdb_test "show jit-reader-directory" \
114         "JIT reader directory is .*\\."
116     gdb_test_no_output "jit-reader-load ${jit_reader_bin}" "jit-reader-load"
117     gdb_run_cmd
118     gdb_test "" "Program received signal SIGTRAP, .*" "expect SIGTRAP"
120     # Test the JIT reader unwinder.
121     with_test_prefix "with jit-reader" {
123         with_test_prefix "before mangling" {
124             gdb_test "bt" \
125                 [multi_line \
126                      "#0 ${any} in jit_function_stack_mangle ${any}" \
127                      "#1 ${any} in main ${any}" \
128                     ] \
129                 "bt works"
131             set sp_before_mangling \
132                 [get_hexadecimal_valueof "\$sp" 0 "get sp"]
134             gdb_test "up" "#1  $any in main $any\r\n$any  function_stack_mangle $any" \
135                 "move up to caller"
137             set caller_sp \
138                 [get_hexadecimal_valueof "\$sp" 0 "get caller sp"]
139         }
141         # Step over the instruction that mangles the stack pointer.
142         # While that confuses GDB's built-in unwinder, the JIT
143         # reader's unwinder understands the mangling and should thus
144         # be able to unwind at that location.
145         with_test_prefix "after mangling" {
146             gdb_test "si" "in jit_function_stack_mangle .*" "step over stack mangling"
148             set sp_after_mangling \
149                 [get_hexadecimal_valueof "\$sp" 0 "get sp"]
151             gdb_assert {$sp_before_mangling != $sp_after_mangling} \
152                 "sp is mangled"
154             # Check that the jit unwinder manages to backtrace through
155             # the mangled stack pointer.
156             gdb_test "bt" \
157                 [multi_line \
158                      "#0 ${any} in jit_function_stack_mangle ${any}" \
159                      "#1 ${any} in main ${any}" \
160                     ] \
161                 "bt works"
163             with_test_prefix "current frame" {
164                 info_registers_current_frame $sp_after_mangling
166                 gdb_test "info frame" \
167                     "Stack level 0, frame at $sp_before_mangling.*in jit_function_stack_mangle.*"
168             }
170             with_test_prefix "caller frame" {
171                 gdb_test "up" "#1  $any in main $any\r\n$any  function_stack_mangle $any" \
172                     "up to caller"
174                 # Since the JIT unwinder only provides RIP/RSP/RBP,
175                 # all other registers should show as "<not saved>".
177                 set expected \
178                     [multi_line \
179                          "rax            <not saved>" \
180                          "rbx            <not saved>" \
181                          "rcx            <not saved>" \
182                          "rdx            <not saved>" \
183                          "rsi            <not saved>" \
184                          "rdi            <not saved>" \
185                          "rbp            $hex +$hex" \
186                          "rsp            $caller_sp +$caller_sp" \
187                          "r8             <not saved>" \
188                          "r9             <not saved>" \
189                          "r10            <not saved>" \
190                          "r11            <not saved>" \
191                          "r12            <not saved>" \
192                          "r13            <not saved>" \
193                          "r14            <not saved>" \
194                          "r15            <not saved>" \
195                          "rip            $hex +$hex $any" \
196                          "eflags         <not saved>" \
197                          "cs             <not saved>" \
198                          "ss             <not saved>" \
199                          "ds             <not saved>" \
200                          "es             <not saved>" \
201                          "fs             <not saved>" \
202                          "gs             <not saved>" \
203                         ]
205                 # There may be more registers.
206                 append expected ".*"
208                 gdb_test "info registers" $expected
210                 # Make sure that "info frame" doesn't crash.
211                 gdb_test "info frame" "Stack level 1, .*in main.*"
213                 # ... and that neither does printing a pseudo
214                 # register.
215                 gdb_test "print /x \$ebp" " = $hex" "print pseudo register"
217                 # There's no way for the JIT reader API to support
218                 # modifyiable values.
219                 gdb_test "print \$rbp = -1" \
220                     "Attempt to assign to an unmodifiable value\." \
221                     "cannot assign to register"
222             }
224             if { [allow_python_tests] } {
225                 gdb_test "python print(gdb.objfiles())" \
226                     "$any<gdb.Objfile filename=<< JIT compiled code at $hex >>>$any" \
227                     "python gdb.Objfile.__repr__ ()"
229                 gdb_test "python print(list(map(lambda objf : objf.filename, gdb.objfiles())))" \
230                     "$any'<< JIT compiled code at $hex >>'$any" \
231                     "python gdb.Objfile.filename"
233                 gdb_test "python print( \[o for o in gdb.objfiles() if o.filename.startswith('<< JIT compiled code')\]\[0\].build_id )" \
234                     "None" \
235                     "python gdb.Objfile.build_id"
236             }
237         }
238     }
240     # Now unload the jit reader, and ensure that backtracing really
241     # doesn't work without it.
242     with_test_prefix "without jit-reader" {
243         gdb_test_no_output "jit-reader-unload ${jit_reader_bin}" \
244             "jit-reader-unload"
246         # Check that we're no longer using the JIT unwinder, and that
247         # the built-in unwinder cannot backtrace through the mangled
248         # stack pointer.
249         gdb_test "bt" \
250             "Backtrace stopped: Cannot access memory at address $sp_after_mangling" \
251             "bt shows error"
253         gdb_test "info frame" "Cannot access memory at address.*" \
254             "info frame shows error"
255         info_registers_current_frame $sp_after_mangling
256         gdb_test "up" "Initial frame selected; you cannot go up\\." \
257             "cannot go up"
258     }
260     with_test_prefix "with jit-reader again" {
261         gdb_test_no_output "jit-reader-load ${jit_reader_bin}" "jit-reader-load"
263         # Check that the jit unwinder manages to backtrace through
264         # the mangled stack pointer.
265         gdb_test "bt" \
266             [multi_line \
267                  "#0 ${any} in jit_function_stack_mangle ${any}" \
268                  "#1 ${any} in main ${any}" \
269                 ]
270     }
272     if {[allow_python_tests]} {
273         gdb_test "python print(any(\[not x.is_file for x in gdb.objfiles()\]))" \
274             "True" \
275             "at least one non-file objfile"
276         gdb_test "python print(any(\[x.is_file for x in gdb.objfiles()\]))" \
277             "True" \
278             "at least one file-based objfile"
279     }
281     with_test_prefix "test dwarf unwinder" {
282         # Check that the DWARF unwinder does not crash in presence of
283         # JIT objfiles.
284         gdb_test "up"
285         gdb_breakpoint "*function_add" temporary
286         gdb_test "cont" ".*Temporary breakpoint ${any} in jit_function_add .*"
287         gdb_test "bt" \
288             [multi_line \
289                  "#0 ${any} in jit_function_add ${any}" \
290                  "#1 ${any} in main ${any}" \
291                 ]
292     }
295 jit_reader_test