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