]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/testsuite/gdb.python/py-mi-cmd.exp
Automatic date update in version.in
[thirdparty/binutils-gdb.git] / gdb / testsuite / gdb.python / py-mi-cmd.exp
1 # Copyright (C) 2019-2024 Free Software Foundation, Inc.
2 # This program is free software; you can redistribute it and/or modify
3 # it under the terms of the GNU General Public License as published by
4 # the Free Software Foundation; either version 3 of the License, or
5 # (at your option) any later version.
6 #
7 # This program is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # GNU General Public License for more details.
11 #
12 # You should have received a copy of the GNU General Public License
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14
15 # Test custom MI commands implemented in Python.
16
17 load_lib gdb-python.exp
18 load_lib mi-support.exp
19 set MIFLAGS "-i=mi"
20
21 gdb_exit
22 if {[mi_gdb_start]} {
23 return
24 }
25
26 if {[lsearch -exact [mi_get_features] python] < 0} {
27 unsupported "python support is disabled"
28 return -1
29 }
30
31 standard_testfile
32
33 mi_gdb_test "set python print-stack full" \
34 ".*\\^done" \
35 "set python print-stack full"
36
37 mi_gdb_test "source ${srcdir}/${subdir}/${testfile}.py" \
38 ".*\\^done" \
39 "load python file"
40
41 mi_gdb_test "python pycmd1('-pycmd')" \
42 ".*\\^done" \
43 "define -pycmd MI command"
44
45 mi_gdb_test "-pycmd int" \
46 "\\^done,result=\"42\"" \
47 "-pycmd int"
48
49 mi_gdb_test "-pycmd str" \
50 "\\^done,result=\"Hello world!\"" \
51 "-pycmd str"
52
53 mi_gdb_test "-pycmd ary" \
54 "\\^done,result=\\\[\"Hello\",\"42\"\\\]" \
55 "-pycmd ary"
56
57 set re_order1 "\\^done,result={hello=\"world\",times=\"42\"}"
58 set re_order2 "\\^done,result={times=\"42\",hello=\"world\"}"
59 mi_gdb_test "-pycmd dct" \
60 "($re_order1|$re_order2)" \
61 "-pycmd dct"
62
63 mi_gdb_test "-pycmd bk1" \
64 "\\^error,msg=\"Error occurred in Python: non-string object used as key: Bad Key\"" \
65 "-pycmd bk1"
66
67 mi_gdb_test "-pycmd bk2" \
68 "\\^error,msg=\"Error occurred in Python: non-string object used as key: 1\"" \
69 "-pycmd bk2"
70
71 mi_gdb_test "-pycmd bk3" \
72 [multi_line \
73 "&\"TypeError.*: __repr__ returned non-string \\(type BadKey\\)..\"" \
74 "\\^error,msg=\"Error occurred in Python: __repr__ returned non-string \\(type BadKey\\)\""] \
75 "-pycmd bk3"
76
77 mi_gdb_test "-pycmd tpl" \
78 "\\^done,result=\\\[\"42\",\"Hello\"\\\]" \
79 "-pycmd tpl"
80
81 mi_gdb_test "-pycmd itr" \
82 "\\^done,result=\\\[\"1\",\"2\",\"3\"\\\]" \
83 "-pycmd itr"
84
85 mi_gdb_test "-pycmd nn1" \
86 "\\^done" \
87 "-pycmd nn1"
88
89 mi_gdb_test "-pycmd nn2" \
90 "\\^done,result=\\\[\"None\"\\\]" \
91 "-pycmd nn2"
92
93 mi_gdb_test "-pycmd bogus" \
94 "\\^error,msg=\"Invalid parameter: bogus\"" \
95 "-pycmd bogus"
96
97 # Check that the top-level result from 'invoke' must be a dictionary.
98 foreach test_name { nd1 nd2 nd3 } {
99 mi_gdb_test "-pycmd ${test_name}" \
100 "\\^error,msg=\"Error occurred in Python: Result from invoke must be a dictionary\""
101 }
102
103 # Check for invalid strings in the result.
104 foreach test_desc { {ik1 "xxx yyy"} {ik2 "xxx yyy"} {ik3 "xxx\\+yyy"} \
105 {ik4 "xxx\\.yyy"} {ik5 "123xxxyyy"} } {
106 lassign $test_desc name pattern
107
108 mi_gdb_test "-pycmd ${name}" \
109 "\\^error,msg=\"Error occurred in Python: Invalid key in MI result: ${pattern}\""
110 }
111
112 mi_gdb_test "-pycmd empty_key" \
113 "\\^error,msg=\"Error occurred in Python: Invalid empty key in MI result\""
114
115 # Check that a dash ('-') can be used in a key name.
116 mi_gdb_test "-pycmd dash-key" \
117 "\\^done,the-key=\"123\""
118
119 # With this argument the command raises a gdb.GdbError with no message
120 # string. GDB considers this a bug in the user program, so prints a
121 # backtrace, and a generic error message.
122 mi_gdb_test "-pycmd exp" \
123 [multi_line ".*&\"Traceback \\(most recent call last\\):..\"" \
124 "&\"\[^\r\n\]+${testfile}.py\[^\r\n\]+\"" \
125 "&\"\[^\r\n\]+raise gdb.GdbError\\(\\)..\"" \
126 "&\"gdb.GdbError..\"" \
127 "\\^error,msg=\"Error occurred in Python\\.\""] \
128 "-pycmd exp"
129
130 mi_gdb_test "python pycmd2('-pycmd')" \
131 ".*\\^done" \
132 "redefine -pycmd MI command from CLI command"
133
134 mi_gdb_test "-pycmd str" \
135 "\\^done,result=\"Ciao!\"" \
136 "-pycmd str - redefined from CLI"
137
138 mi_gdb_test "-pycmd int" \
139 "\\^error,msg=\"Invalid parameter: int\"" \
140 "-pycmd int - redefined from CLI"
141
142 mi_gdb_test "-pycmd new" \
143 "\\^done" \
144 "Define new command -pycmd-new MI command from Python MI command"
145
146 mi_gdb_test "-pycmd red" \
147 "\\^error,msg=\"Command redefined but we failing anyway\"" \
148 "redefine -pycmd MI command from Python MI command"
149
150 mi_gdb_test "-pycmd int" \
151 "\\^done,result=\"42\"" \
152 "-pycmd int - redefined from MI"
153
154 mi_gdb_test "-pycmd-new int" \
155 "\\^done,result=\"42\"" \
156 "-pycmd-new int - defined from MI"
157
158 mi_gdb_test "python pycmd1('')" \
159 ".*&\"ValueError.*: MI command name is empty\\...\".*\\^error,msg=\"Error occurred in Python.*\"" \
160 "empty MI command name"
161
162 mi_gdb_test "python pycmd1('-')" \
163 [multi_line \
164 ".*" \
165 "&\"ValueError.*: MI command name does not start with '-' followed by at least one letter or digit\\...\"" \
166 "&\"Error occurred in Python.*..\"" \
167 "\\^error,msg=\"Error occurred in Python.*\""] \
168 "invalid MI command name"
169
170 mi_gdb_test "python pycmd1('-bad-character-@')" \
171 [multi_line \
172 ".*" \
173 "&\"ValueError.*: MI command name contains invalid character: @\\...\"" \
174 "&\"Error occurred in Python.*..\"" \
175 "\\^error,msg=\"Error occurred in Python.*\""] \
176 "invalid character in MI command name"
177
178 mi_gdb_test "python cmd=pycmd1('-abc')" \
179 ".*\\^done" \
180 "create command -abc, stored in a python variable"
181
182 mi_gdb_test "python print(cmd.name)" \
183 ".*\r\n~\"-abc\\\\n\"\r\n\\^done" \
184 "print the name of the stored mi command"
185
186 mi_gdb_test "python print(cmd.installed)" \
187 ".*\r\n~\"True\\\\n\"\r\n\\^done" \
188 "print the installed status of the stored mi command"
189
190 mi_gdb_test "-abc str" \
191 "\\^done,result=\"Hello world!\"" \
192 "-abc str"
193
194 mi_gdb_test "python cmd.installed = False" \
195 ".*\\^done" \
196 "uninstall the mi command"
197
198 mi_gdb_test "-abc str" \
199 "\\^error,msg=\"Undefined MI command: abc\",code=\"undefined-command\"" \
200 "-abc str, but now the command is gone"
201
202 mi_gdb_test "python cmd.installed = True" \
203 ".*\\^done" \
204 "re-install the mi command"
205
206 mi_gdb_test "-abc str" \
207 "\\^done,result=\"Hello world!\"" \
208 "-abc str, the command is back again"
209
210 mi_gdb_test "python other=pycmd2('-abc')" \
211 ".*\\^done" \
212 "create another command called -abc, stored in a separate python variable"
213
214 mi_gdb_test "python print(other.installed)" \
215 ".*\r\n~\"True\\\\n\"\r\n\\^done" \
216 "print the installed status of the other stored mi command"
217
218 mi_gdb_test "python print(cmd.installed)" \
219 ".*\r\n~\"False\\\\n\"\r\n\\^done" \
220 "print the installed status of the original stored mi command"
221
222 mi_gdb_test "-abc str" \
223 "\\^done,result=\"Ciao!\"" \
224 "-abc str, when the other command is in place"
225
226 mi_gdb_test "python cmd.installed = True" \
227 ".*\\^done" \
228 "re-install the original mi command"
229
230 mi_gdb_test "-abc str" \
231 "\\^done,result=\"Hello world!\"" \
232 "-abc str, the original command is back again"
233
234 mi_gdb_test "python print(other.installed)" \
235 ".*\r\n~\"False\\\\n\"\r\n\\^done" \
236 "the other command is now not installed"
237
238 mi_gdb_test "python print(cmd.installed)" \
239 ".*\r\n~\"True\\\\n\"\r\n\\^done" \
240 "the original command is now installed"
241
242 mi_gdb_test "python aa = pycmd3('-aa', 'message one', 'xxx')" \
243 ".*\\^done" \
244 "created a new -aa command"
245
246 mi_gdb_test "-aa" \
247 ".*\\^done,xxx={msg=\"message one\"}" \
248 "call the -aa command"
249
250 mi_gdb_test "python aa.__init__('-aa', 'message two', 'yyy')" \
251 ".*\\^done" \
252 "reinitialise -aa command with a new message"
253
254 mi_gdb_test "-aa" \
255 ".*\\^done,yyy={msg=\"message two\"}" \
256 "call the -aa command, get the new message"
257
258 mi_gdb_test "python aa.__init__('-bb', 'message three', 'zzz')" \
259 [multi_line \
260 ".*" \
261 "&\"ValueError.*: can't reinitialize object with a different command name..\"" \
262 "&\"Error occurred in Python.*..\"" \
263 "\\^error,msg=\"Error occurred in Python.*\""] \
264 "attempt to reinitialise aa variable to a new command name"
265
266 mi_gdb_test "-aa" \
267 ".*\\^done,yyy={msg=\"message two\"}" \
268 "check the aa object has not changed after failed initialization"
269
270 mi_gdb_test "python aa.installed = False" \
271 ".*\\^done" \
272 "uninstall the -aa command"
273
274 mi_gdb_test "python aa.__init__('-bb', 'message three', 'zzz')" \
275 [multi_line \
276 ".*" \
277 "&\"ValueError.*: can't reinitialize object with a different command name..\"" \
278 "&\"Error occurred in Python.*..\"" \
279 "\\^error,msg=\"Error occurred in Python.*\""] \
280 "attempt to reinitialise aa variable to a new command name while uninstalled"
281
282 mi_gdb_test "python aa.__init__('-aa', 'message three', 'zzz')" \
283 ".*\\^done" \
284 "reinitialise -aa command with a new message while uninstalled"
285
286 mi_gdb_test "python aa.installed = True" \
287 ".*\\^done" \
288 "install the -aa command"
289
290 mi_gdb_test "-aa" \
291 ".*\\^done,zzz={msg=\"message three\"}" \
292 "call the -aa command looking for message three"
293
294 # Try to register a command object that is missing an invoke method.
295 # This is accepted, but will give an error when the user tries to run
296 # the command.
297 mi_gdb_test "python no_invoke('-no-invoke')" ".*\\^done" \
298 "attempt to register command with no invoke method"
299 mi_gdb_test "-no-invoke" \
300 [multi_line \
301 ".*" \
302 "&\"AttributeError.*: 'no_invoke' object has no attribute 'invoke'..\"" \
303 "\\^error,msg=\"Error occurred in Python: 'no_invoke' object has no attribute 'invoke'\""] \
304 "execute -no-invoke command, which is missing the invoke method"
305
306 # Register a command, then delete its invoke method. What is the user thinking!!
307 mi_gdb_test "python setattr(no_invoke, 'invoke', free_invoke)" ".*\\^done"
308 mi_gdb_test "python cmd = no_invoke('-hello')" ".*\\^done"
309 mi_gdb_test "-hello" ".*\\^done,result=\\\[\\\]" \
310 "execute no_invoke command, while it still has an invoke attribute"
311 mi_gdb_test "python delattr(no_invoke, 'invoke')" ".*\\^done"
312 mi_gdb_test "-hello" \
313 [multi_line \
314 ".*" \
315 "&\"AttributeError.*: 'no_invoke' object has no attribute 'invoke'..\"" \
316 "\\^error,msg=\"Error occurred in Python: 'no_invoke' object has no attribute 'invoke'\""] \
317 "execute -hello command, that had its invoke method removed"
318 mi_gdb_test "python cmd.invoke = 'string'" ".*\\^done"
319 mi_gdb_test "-hello" \
320 [multi_line \
321 ".*" \
322 "&\"TypeError.*: 'str' object is not callable..\"" \
323 "\\^error,msg=\"Error occurred in Python: 'str' object is not callable\""] \
324 "execute command with invoke set to a string"
325
326 # Try to create a new MI command that uses the name of a builtin MI command.
327 mi_gdb_test "python cmd = pycmd2('-data-disassemble')" \
328 [multi_line \
329 ".*" \
330 "&\"RuntimeError.*: unable to add command, name is already in use..\"" \
331 "&\"Error occurred in Python.*..\"" \
332 "\\^error,msg=\"Error occurred in Python.*\""] \
333 "try to register a command that replaces -data-disassemble"
334
335
336
337 mi_gdb_test "python run_exception_tests()" \
338 [multi_line \
339 ".*" \
340 "~\"PASS..\"" \
341 "\\^done"]