Automatic date update in version.in
[binutils-gdb.git] / gdb / testsuite / gdb.btrace / ptwrite.exp
blob7f1adad26d28759ce60185a26bbd17ed13526435
1 # This testcase is part of GDB, the GNU debugger.
3 # Copyright 2024 Free Software Foundation, Inc.
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 load_lib gdb-python.exp
20 require allow_btrace_ptw_tests allow_python_tests
22 set opts {}
24 if [info exists COMPILE] {
25     # make check RUNTESTFLAGS="gdb.btrace/ptwrite.exp COMPILE=1"
26     standard_testfile ptwrite.c
27     lappend opts debug additional_flags=-mptwrite
28 } elseif {[istarget "i?86-*-*"] || [istarget "x86_64-*-*"]} {
29     if {[is_amd64_regs_target]} {
30         standard_testfile x86_64-ptwrite.S
31     } else {
32         standard_testfile i386-ptwrite.S
33     }
34 } else {
35     unsupported "target architecture not supported"
36     return -1
39 if [prepare_for_testing "failed to prepare" $testfile $srcfile $opts] {
40     return -1
43 if { ![runto_main] } {
44     untested "failed to run to main"
45     return -1
48 ### 1. Default testrun
50 # Setup recording
51 gdb_test_no_output "set record instruction-history-size unlimited"
52 gdb_test_no_output "record btrace pt"
53 gdb_test "next 2" ".*"
55 with_test_prefix "Default" {
56     # Test record instruction-history
57     gdb_test "record instruction-history 1" [multi_line \
58         ".*\[0-9\]+\t   $hex <ptwrite1\\+\[0-9\]+>:\tptwrite %\[a-z\]+" \
59         "\[0-9\]+\t     \\\[0x42\\\]" \
60         ".*\[0-9\]+\t   $hex <ptwrite2\\+\[0-9\]+>:\tptwrite %\[a-z\]+" \
61         "\[0-9\]+\t     \\\[0x43\\\].*" \
62         ]
64     gdb_test "record instruction-history /a 1" [multi_line \
65         ".*\[0-9\]+\t   $hex <ptwrite1\\+\[0-9\]+>:\tptwrite %\[a-z\]+" \
66         ".*\[0-9\]+\t   $hex <ptwrite2\\+\[0-9\]+>:\tptwrite %\[a-z\]+.*" \
67         ]
69     # Test function call history
70     gdb_test "record function-call-history 1,4" [multi_line \
71         "1\tmain" \
72         "2\tptwrite1" \
73         "\t  \\\[0x42\\\]" \
74         "3\tmain" \
75         "4\tptwrite2" \
76         "\t  \\\[0x43\\\]" \
77         ]
79     gdb_test "record function-call-history /a 1,4" [multi_line \
80         "1\tmain" \
81         "2\tptwrite1" \
82         "3\tmain" \
83         "4\tptwrite2" \
84         ]
87 # Test payload printing during stepping
88 with_test_prefix "Stepping" {
89     gdb_test "record goto 10" "Can't go to an auxiliary instruction\."
90     gdb_test "record goto 9" ".*ptwrite.* at .*"
91     gdb_test "stepi" ".*\\\[0x42\\\].*"
92     gdb_test "reverse-stepi" ".*\\\[0x42\\\].*"
93     gdb_test "continue" [multi_line \
94             ".*\\\[0x42\\\]" \
95             "\\\[0x43\\\].*" \
96             ]
97     gdb_test "reverse-continue" [multi_line \
98             ".*\\\[0x43\\\]" \
99             "\\\[0x42\\\].*" \
100             ]
103 # Test auxiliary type in python
104 gdb_test_multiline "auxiliary type in python" \
105     "python" "" \
106     "h = gdb.current_recording().instruction_history" "" \
107     "for insn in h:" "" \
108     "    if hasattr(insn, 'decoded'):" "" \
109     "        print(insn.decoded.decode())" "" \
110     "    elif hasattr(insn, 'data'):" "" \
111     "        print(insn.data)" "" \
112     "end" \
113     [multi_line \
114         ".*mov    -0x4\\\(%(e|r)bp\\\),%(e|r)ax" \
115         "ptwrite %eax" \
116         "0x42" \
117         "nop.*" \
118         "mov    -0x4\\\(%(e|r)bp\\\),%(e|r)ax" \
119         "ptwrite %eax" \
120         "0x43" \
121         "nop.*"
122     ]
125 ### 2. Test filter registration
126 ### 2.1 Custom filter
127 with_test_prefix "Custom" {
128     gdb_test_multiline "register filter in python" \
129         "python" "" \
130         "def my_filter(payload, ip):" "" \
131         "    if  payload == 66:" "" \
132         "        return \"payload: {0}, ip: {1:#x}\".format(payload, ip)" "" \
133         "    else:" "" \
134         "        return None" "" \
135         "def factory(thread): return my_filter" "" \
136         "import gdb.ptwrite" "" \
137         "gdb.ptwrite.register_filter_factory(factory)" "" \
138         "end" ""
140     gdb_test "record instruction-history 1" [multi_line \
141         ".*\[0-9\]+\t   $hex <ptwrite1\\+\[0-9\]+>:\tptwrite %\[a-z\]+" \
142         "\[0-9\]+\t     \\\[payload: 66, ip: $hex\\\]" \
143         ".*\[0-9\]+\t   $hex <ptwrite2\\+\[0-9\]+>:\tptwrite %\[a-z\]+" \
144         "\[0-9\]+\t   $hex <ptwrite2\\+\[0-9\]+>:.*" \
145         ]
148 ### 2.2 None as filter. This resets the default behavior.
149 with_test_prefix "None" {
150     gdb_test_multiline "register filter in python" \
151         "python" "" \
152         "import gdb.ptwrite" "" \
153         "gdb.ptwrite.register_filter_factory(None)" "" \
154         "end" ""
156     gdb_test "record instruction-history 1" [multi_line \
157         ".*\[0-9\]+\t   $hex <ptwrite1\\+\[0-9\]+>:\tptwrite %\[a-z\]+" \
158         "\[0-9\]+\t     \\\[0x42\\\]" \
159         ".*\[0-9\]+\t   $hex <ptwrite2\\+\[0-9\]+>:\tptwrite %\[a-z\]+" \
160         "\[0-9\]+\t     \\\[0x43\\\].*" \
161         ]
164 ### 2.3 Lambdas as filter
165 with_test_prefix "Lambdas" {
166     gdb_test_multiline "register filter in python" \
167         "python" "" \
168         "import gdb.ptwrite" "" \
169         "lambda_filter = lambda payload, ip: \"{}\".format(payload + 2)" "" \
170         "gdb.ptwrite.register_filter_factory(lambda thread : lambda_filter)" "" \
171         "end" ""
173     gdb_test "record instruction-history 1" [multi_line \
174         ".*\[0-9\]+\t   $hex <ptwrite1\\+\[0-9\]+>:\tptwrite %\[a-z\]+" \
175         "\[0-9\]+\t     \\\[68\\\]" \
176         ".*\[0-9\]+\t   $hex <ptwrite2\\+\[0-9\]+>:\tptwrite %\[a-z\]+" \
177         "\[0-9\]+\t     \\\[69\\\].*" \
178         ] "Lambdas: record instruction-history 1"
181 ### 2.4 Functors as filter
182 with_test_prefix "Functors" {
183     gdb_test_multiline "register filter in python" \
184         "python" "" \
185         "import gdb.ptwrite" "" \
186         "class foobar(object):" "" \
187         "    def __init__(self):" "" \
188         "        self.variable = 0" "" \
189         "    def __call__(self, payload, ip):" "" \
190         "        self.variable += 1" "" \
191         "        return \"{}, {}\".format(self.variable, payload)" "" \
192         "gdb.ptwrite.register_filter_factory(lambda thread : foobar())" "" \
193         "end" ""
195     gdb_test "record instruction-history 1" [multi_line \
196         ".*\[0-9\]+\t   $hex <ptwrite1\\+\[0-9\]+>:\tptwrite %\[a-z\]+" \
197         "\[0-9\]+\t     \\\[1, 66\\\]" \
198         ".*\[0-9\]+\t   $hex <ptwrite2\\+\[0-9\]+>:\tptwrite %\[a-z\]+" \
199         "\[0-9\]+\t     \\\[2, 67\\\].*" \
200         ] "Functors: record instruction-history 1"