blob: e019617e685d570b25adcc7b45459573f0320b77 [file] [log] [blame]
Bram Moolenaar113bf062019-04-17 16:54:05 +02001" Tests for the Vim script debug commands
2
3source shared.vim
4source screendump.vim
Bram Moolenaar8c5a2782019-08-07 23:07:07 +02005source check.vim
Bram Moolenaar113bf062019-04-17 16:54:05 +02006
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +02007func CheckDbgOutput(buf, lines, options = {})
8 " Verify the expected output
9 let lnum = 20 - len(a:lines)
10 for l in a:lines
11 if get(a:options, 'match', 'equal') ==# 'pattern'
12 call WaitForAssert({-> assert_match(l, term_getline(a:buf, lnum))}, 200)
13 else
14 call WaitForAssert({-> assert_equal(l, term_getline(a:buf, lnum))}, 200)
15 endif
16 let lnum += 1
17 endfor
18endfunc
19
Bram Moolenaar113bf062019-04-17 16:54:05 +020020" Run a Vim debugger command
21" If the expected output argument is supplied, then check for it.
22func RunDbgCmd(buf, cmd, ...)
23 call term_sendkeys(a:buf, a:cmd . "\r")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +020024 call TermWait(a:buf)
Bram Moolenaar113bf062019-04-17 16:54:05 +020025
26 if a:0 != 0
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +020027 let options = #{match: 'equal'}
28 if a:0 > 1
29 call extend(options, a:2)
30 endif
31 call CheckDbgOutput(a:buf, a:1, options)
Bram Moolenaar113bf062019-04-17 16:54:05 +020032 endif
33endfunc
34
35" Debugger tests
36func Test_Debugger()
Bram Moolenaar8c5a2782019-08-07 23:07:07 +020037 CheckRunVimInTerminal
Bram Moolenaar113bf062019-04-17 16:54:05 +020038
39 " Create a Vim script with some functions
Bram Moolenaare7eb9272019-06-24 00:58:07 +020040 let lines =<< trim END
41 func Foo()
42 let var1 = 1
43 let var2 = Bar(var1) + 9
44 return var2
45 endfunc
46 func Bar(var)
47 let var1 = 2 + a:var
48 let var2 = Bazz(var1) + 4
49 return var2
50 endfunc
51 func Bazz(var)
52 try
53 let var1 = 3 + a:var
54 let var3 = "another var"
55 let var3 = "value2"
56 catch
57 let var4 = "exception"
58 endtry
59 return var1
60 endfunc
61 END
62 call writefile(lines, 'Xtest.vim')
Bram Moolenaar113bf062019-04-17 16:54:05 +020063
64 " Start Vim in a terminal
65 let buf = RunVimInTerminal('-S Xtest.vim', {})
66
67 " Start the Vim debugger
Bram Moolenaarddd33082019-06-03 23:07:25 +020068 call RunDbgCmd(buf, ':debug echo Foo()', ['cmd: echo Foo()'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020069
70 " Create a few stack frames by stepping through functions
Bram Moolenaarddd33082019-06-03 23:07:25 +020071 call RunDbgCmd(buf, 'step', ['line 1: let var1 = 1'])
72 call RunDbgCmd(buf, 'step', ['line 2: let var2 = Bar(var1) + 9'])
73 call RunDbgCmd(buf, 'step', ['line 1: let var1 = 2 + a:var'])
74 call RunDbgCmd(buf, 'step', ['line 2: let var2 = Bazz(var1) + 4'])
75 call RunDbgCmd(buf, 'step', ['line 1: try'])
76 call RunDbgCmd(buf, 'step', ['line 2: let var1 = 3 + a:var'])
77 call RunDbgCmd(buf, 'step', ['line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020078
79 " check backtrace
80 call RunDbgCmd(buf, 'backtrace', [
81 \ ' 2 function Foo[2]',
82 \ ' 1 Bar[2]',
83 \ '->0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +020084 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020085
86 " Check variables in different stack frames
87 call RunDbgCmd(buf, 'echo var1', ['6'])
88
89 call RunDbgCmd(buf, 'up')
90 call RunDbgCmd(buf, 'back', [
91 \ ' 2 function Foo[2]',
92 \ '->1 Bar[2]',
93 \ ' 0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +020094 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020095 call RunDbgCmd(buf, 'echo var1', ['3'])
96
97 call RunDbgCmd(buf, 'u')
98 call RunDbgCmd(buf, 'bt', [
99 \ '->2 function Foo[2]',
100 \ ' 1 Bar[2]',
101 \ ' 0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200102 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200103 call RunDbgCmd(buf, 'echo var1', ['1'])
104
105 " Undefined variables
106 call RunDbgCmd(buf, 'step')
107 call RunDbgCmd(buf, 'frame 2')
108 call RunDbgCmd(buf, 'echo var3', [
109 \ 'Error detected while processing function Foo[2]..Bar[2]..Bazz:',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200110 \ 'line 4:',
Bram Moolenaar113bf062019-04-17 16:54:05 +0200111 \ 'E121: Undefined variable: var3'])
112
113 " var3 is defined in this level with some other value
114 call RunDbgCmd(buf, 'fr 0')
115 call RunDbgCmd(buf, 'echo var3', ['another var'])
116
117 call RunDbgCmd(buf, 'step')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200118 call RunDbgCmd(buf, '')
119 call RunDbgCmd(buf, '')
120 call RunDbgCmd(buf, '')
121 call RunDbgCmd(buf, '')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200122 call RunDbgCmd(buf, 'step', [
123 \ 'function Foo[2]..Bar',
124 \ 'line 3: End of function'])
125 call RunDbgCmd(buf, 'up')
126
127 " Undefined var2
128 call RunDbgCmd(buf, 'echo var2', [
129 \ 'Error detected while processing function Foo[2]..Bar:',
130 \ 'line 3:',
131 \ 'E121: Undefined variable: var2'])
132
133 " Var2 is defined with 10
134 call RunDbgCmd(buf, 'down')
135 call RunDbgCmd(buf, 'echo var2', ['10'])
136
137 " Backtrace movements
138 call RunDbgCmd(buf, 'b', [
139 \ ' 1 function Foo[2]',
140 \ '->0 Bar',
141 \ 'line 3: End of function'])
142
143 " next command cannot go down, we are on bottom
144 call RunDbgCmd(buf, 'down', ['frame is zero'])
145 call RunDbgCmd(buf, 'up')
146
147 " next command cannot go up, we are on top
148 call RunDbgCmd(buf, 'up', ['frame at highest level: 1'])
149 call RunDbgCmd(buf, 'where', [
150 \ '->1 function Foo[2]',
151 \ ' 0 Bar',
152 \ 'line 3: End of function'])
153
154 " fil is not frame or finish, it is file
155 call RunDbgCmd(buf, 'fil', ['"[No Name]" --No lines in buffer--'])
156
157 " relative backtrace movement
158 call RunDbgCmd(buf, 'fr -1')
159 call RunDbgCmd(buf, 'frame', [
160 \ ' 1 function Foo[2]',
161 \ '->0 Bar',
162 \ 'line 3: End of function'])
163
164 call RunDbgCmd(buf, 'fr +1')
165 call RunDbgCmd(buf, 'fram', [
166 \ '->1 function Foo[2]',
167 \ ' 0 Bar',
168 \ 'line 3: End of function'])
169
170 " go beyond limits does not crash
171 call RunDbgCmd(buf, 'fr 100', ['frame at highest level: 1'])
172 call RunDbgCmd(buf, 'fra', [
173 \ '->1 function Foo[2]',
174 \ ' 0 Bar',
175 \ 'line 3: End of function'])
176
177 call RunDbgCmd(buf, 'frame -40', ['frame is zero'])
178 call RunDbgCmd(buf, 'fram', [
179 \ ' 1 function Foo[2]',
180 \ '->0 Bar',
181 \ 'line 3: End of function'])
182
183 " final result 19
184 call RunDbgCmd(buf, 'cont', ['19'])
185
186 " breakpoints tests
187
188 " Start a debug session, so that reading the last line from the terminal
189 " works properly.
190 call RunDbgCmd(buf, ':debug echo Foo()')
191
192 " No breakpoints
193 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
194
195 " Place some breakpoints
196 call RunDbgCmd(buf, 'breaka func Bar')
197 call RunDbgCmd(buf, 'breaklis', [' 1 func Bar line 1'])
198 call RunDbgCmd(buf, 'breakadd func 3 Bazz')
199 call RunDbgCmd(buf, 'breaklist', [' 1 func Bar line 1',
200 \ ' 2 func Bazz line 3'])
201
202 " Check whether the breakpoints are hit
203 call RunDbgCmd(buf, 'cont', [
204 \ 'Breakpoint in "Bar" line 1',
205 \ 'function Foo[2]..Bar',
206 \ 'line 1: let var1 = 2 + a:var'])
207 call RunDbgCmd(buf, 'cont', [
208 \ 'Breakpoint in "Bazz" line 3',
209 \ 'function Foo[2]..Bar[2]..Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200210 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200211
212 " Delete the breakpoints
213 call RunDbgCmd(buf, 'breakd 1')
214 call RunDbgCmd(buf, 'breakli', [' 2 func Bazz line 3'])
215 call RunDbgCmd(buf, 'breakdel func 3 Bazz')
216 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
217
218 call RunDbgCmd(buf, 'cont')
219
220 " Make sure the breakpoints are removed
221 call RunDbgCmd(buf, ':echo Foo()', ['19'])
222
223 " Delete a non-existing breakpoint
224 call RunDbgCmd(buf, ':breakdel 2', ['E161: Breakpoint not found: 2'])
225
226 " Expression breakpoint
227 call RunDbgCmd(buf, ':breakadd func 2 Bazz')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200228 call RunDbgCmd(buf, ':echo Bazz(1)', [
229 \ 'Entering Debug mode. Type "cont" to continue.',
230 \ 'function Bazz',
231 \ 'line 2: let var1 = 3 + a:var'])
232 call RunDbgCmd(buf, 'step')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200233 call RunDbgCmd(buf, 'step')
234 call RunDbgCmd(buf, 'breaka expr var3')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200235 call RunDbgCmd(buf, 'breakl', [' 3 func Bazz line 2',
236 \ ' 4 expr var3'])
237 call RunDbgCmd(buf, 'cont', ['Breakpoint in "Bazz" line 5',
Bram Moolenaar113bf062019-04-17 16:54:05 +0200238 \ 'Oldval = "''another var''"',
239 \ 'Newval = "''value2''"',
240 \ 'function Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200241 \ 'line 5: catch'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200242
243 call RunDbgCmd(buf, 'breakdel *')
244 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
245
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200246 " Check for error cases
247 call RunDbgCmd(buf, 'breakadd abcd', [
248 \ 'Error detected while processing function Bazz:',
249 \ 'line 5:',
250 \ 'E475: Invalid argument: abcd'])
251 call RunDbgCmd(buf, 'breakadd func', ['E475: Invalid argument: func'])
252 call RunDbgCmd(buf, 'breakadd func 2', ['E475: Invalid argument: func 2'])
253 call RunDbgCmd(buf, 'breaka func a()', ['E475: Invalid argument: func a()'])
254 call RunDbgCmd(buf, 'breakd abcd', ['E475: Invalid argument: abcd'])
255 call RunDbgCmd(buf, 'breakd func', ['E475: Invalid argument: func'])
256 call RunDbgCmd(buf, 'breakd func a()', ['E475: Invalid argument: func a()'])
257 call RunDbgCmd(buf, 'breakd func a', ['E161: Breakpoint not found: func a'])
258 call RunDbgCmd(buf, 'breakd expr', ['E475: Invalid argument: expr'])
259 call RunDbgCmd(buf, 'breakd expr x', [
260 \ 'E121: Undefined variable: x',
261 \ 'E161: Breakpoint not found: expr x'])
262
Bram Moolenaar113bf062019-04-17 16:54:05 +0200263 " finish the current function
264 call RunDbgCmd(buf, 'finish', [
265 \ 'function Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200266 \ 'line 8: End of function'])
267 call RunDbgCmd(buf, 'cont')
268
269 " Test for :next
270 call RunDbgCmd(buf, ':debug echo Bar(1)')
271 call RunDbgCmd(buf, 'step')
272 call RunDbgCmd(buf, 'next')
273 call RunDbgCmd(buf, '', [
274 \ 'function Bar',
275 \ 'line 3: return var2'])
276 call RunDbgCmd(buf, 'c')
277
278 " Test for :interrupt
279 call RunDbgCmd(buf, ':debug echo Bazz(1)')
280 call RunDbgCmd(buf, 'step')
281 call RunDbgCmd(buf, 'step')
282 call RunDbgCmd(buf, 'interrupt', [
283 \ 'Exception thrown: Vim:Interrupt',
284 \ 'function Bazz',
285 \ 'line 5: catch'])
286 call RunDbgCmd(buf, 'c')
287
288 " Test for :quit
289 call RunDbgCmd(buf, ':debug echo Foo()')
290 call RunDbgCmd(buf, 'breakdel *')
291 call RunDbgCmd(buf, 'breakadd func 3 Foo')
292 call RunDbgCmd(buf, 'breakadd func 3 Bazz')
293 call RunDbgCmd(buf, 'cont', [
294 \ 'Breakpoint in "Bazz" line 3',
295 \ 'function Foo[2]..Bar[2]..Bazz',
296 \ 'line 3: let var3 = "another var"'])
297 call RunDbgCmd(buf, 'quit', [
298 \ 'Breakpoint in "Foo" line 3',
299 \ 'function Foo',
300 \ 'line 3: return var2'])
301 call RunDbgCmd(buf, 'breakdel *')
302 call RunDbgCmd(buf, 'quit')
303 call RunDbgCmd(buf, 'enew! | only!')
304
305 call StopVimInTerminal(buf)
306
307 " Tests for :breakadd file and :breakadd here
308 " Breakpoints should be set before sourcing the file
309
Bram Moolenaare7eb9272019-06-24 00:58:07 +0200310 let lines =<< trim END
311 let var1 = 10
312 let var2 = 20
313 let var3 = 30
314 let var4 = 40
315 END
316 call writefile(lines, 'Xtest.vim')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200317
318 " Start Vim in a terminal
319 let buf = RunVimInTerminal('Xtest.vim', {})
320 call RunDbgCmd(buf, ':breakadd file 2 Xtest.vim')
321 call RunDbgCmd(buf, ':4 | breakadd here')
322 call RunDbgCmd(buf, ':source Xtest.vim', ['line 2: let var2 = 20'])
323 call RunDbgCmd(buf, 'cont', ['line 4: let var4 = 40'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200324 call RunDbgCmd(buf, 'cont')
325
326 call StopVimInTerminal(buf)
327
328 call delete('Xtest.vim')
329endfunc
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200330
331func Test_Backtrace_Through_Source()
332 CheckRunVimInTerminal
333
334 let file1 =<< trim END
335 func SourceAnotherFile()
336 source Xtest2.vim
337 endfunc
338
339 func CallAFunction()
340 call SourceAnotherFile()
341 call File2Function()
342 endfunc
343
344 func GlobalFunction()
345 call CallAFunction()
346 endfunc
347 END
348 call writefile(file1, 'Xtest1.vim')
349
350 let file2 =<< trim END
351 func DoAThing()
352 echo "DoAThing"
353 endfunc
354
355 func File2Function()
356 call DoAThing()
357 endfunc
358
359 call File2Function()
360 END
361 call writefile(file2, 'Xtest2.vim')
362
363 let buf = RunVimInTerminal('-S Xtest1.vim', {})
364
365 call RunDbgCmd(buf,
366 \ ':debug call GlobalFunction()',
367 \ ['cmd: call GlobalFunction()'])
368 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
369
370 call RunDbgCmd(buf, 'backtrace', ['>backtrace',
371 \ '->0 function GlobalFunction',
372 \ 'line 1: call CallAFunction()'])
373
374 call RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()'])
375 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
376
377 call RunDbgCmd(buf, 'backtrace', ['>backtrace',
378 \ ' 2 function GlobalFunction[1]',
379 \ ' 1 CallAFunction[1]',
380 \ '->0 SourceAnotherFile',
381 \ 'line 1: source Xtest2.vim'])
382
383 " Step into the 'source' command. Note that we print the full trace all the
384 " way though the source command.
385 call RunDbgCmd(buf, 'step', ['line 1: func DoAThing()'])
386 call RunDbgCmd(buf, 'backtrace', [
387 \ '>backtrace',
388 \ ' 3 function GlobalFunction[1]',
389 \ ' 2 CallAFunction[1]',
390 \ ' 1 SourceAnotherFile[1]',
391 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
392 \ 'line 1: func DoAThing()'])
393
394 " step until we have another meaninfgul trace
395 call RunDbgCmd(buf, 'step', ['line 5: func File2Function()'])
396 call RunDbgCmd(buf, 'step', ['line 9: call File2Function()'])
397 call RunDbgCmd(buf, 'backtrace', [
398 \ '>backtrace',
399 \ ' 3 function GlobalFunction[1]',
400 \ ' 2 CallAFunction[1]',
401 \ ' 1 SourceAnotherFile[1]',
402 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
403 \ 'line 9: call File2Function()'])
404
405 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
406 call RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"'])
407 call RunDbgCmd(buf, 'backtrace', [
408 \ '>backtrace',
409 \ ' 5 function GlobalFunction[1]',
410 \ ' 4 CallAFunction[1]',
411 \ ' 3 SourceAnotherFile[1]',
412 \ ' 2 script ' .. getcwd() .. '/Xtest2.vim[9]',
413 \ ' 1 function File2Function[1]',
414 \ '->0 DoAThing',
415 \ 'line 1: echo "DoAThing"'])
416
417 " Now, step (back to Xfile1.vim), and call the function _in_ Xfile2.vim
418 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
419 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
420 call RunDbgCmd(buf, 'step', ['line 10: End of sourced file'])
421 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
422 call RunDbgCmd(buf, 'step', ['line 2: call File2Function()'])
423 call RunDbgCmd(buf, 'backtrace', [
424 \ '>backtrace',
425 \ ' 1 function GlobalFunction[1]',
426 \ '->0 CallAFunction',
427 \ 'line 2: call File2Function()'])
428
429 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
430 call RunDbgCmd(buf, 'backtrace', [
431 \ '>backtrace',
432 \ ' 2 function GlobalFunction[1]',
433 \ ' 1 CallAFunction[2]',
434 \ '->0 File2Function',
435 \ 'line 1: call DoAThing()'])
436
437 call StopVimInTerminal(buf)
438 call delete('Xtest1.vim')
439 call delete('Xtest2.vim')
440endfunc
441
442func Test_Backtrace_Autocmd()
443 CheckRunVimInTerminal
444
445 let file1 =<< trim END
446 func SourceAnotherFile()
447 source Xtest2.vim
448 endfunc
449
450 func CallAFunction()
451 call SourceAnotherFile()
452 call File2Function()
453 endfunc
454
455 func GlobalFunction()
456 call CallAFunction()
457 endfunc
458
459 au User TestGlobalFunction :call GlobalFunction() | echo "Done"
460 END
461 call writefile(file1, 'Xtest1.vim')
462
463 let file2 =<< trim END
464 func DoAThing()
465 echo "DoAThing"
466 endfunc
467
468 func File2Function()
469 call DoAThing()
470 endfunc
471
472 call File2Function()
473 END
474 call writefile(file2, 'Xtest2.vim')
475
476 let buf = RunVimInTerminal('-S Xtest1.vim', {})
477
478 call RunDbgCmd(buf,
479 \ ':debug doautocmd User TestGlobalFunction',
480 \ ['cmd: doautocmd User TestGlobalFunction'])
481 call RunDbgCmd(buf, 'step', ['cmd: call GlobalFunction() | echo "Done"'])
482
483 " At this point the ontly thing in the stack is the autocommand
484 call RunDbgCmd(buf, 'backtrace', [
485 \ '>backtrace',
486 \ '->0 User Autocommands for "TestGlobalFunction"',
487 \ 'cmd: call GlobalFunction() | echo "Done"'])
488
489 " And now we're back into the call stack
490 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
491 call RunDbgCmd(buf, 'backtrace', [
492 \ '>backtrace',
493 \ ' 1 User Autocommands for "TestGlobalFunction"',
494 \ '->0 function GlobalFunction',
495 \ 'line 1: call CallAFunction()'])
496
497 call RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()'])
498 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
499
500 call RunDbgCmd(buf, 'backtrace', [
501 \ '>backtrace',
502 \ ' 3 User Autocommands for "TestGlobalFunction"',
503 \ ' 2 function GlobalFunction[1]',
504 \ ' 1 CallAFunction[1]',
505 \ '->0 SourceAnotherFile',
506 \ 'line 1: source Xtest2.vim'])
507
508 " Step into the 'source' command. Note that we print the full trace all the
509 " way though the source command.
510 call RunDbgCmd(buf, 'step', ['line 1: func DoAThing()'])
511 call RunDbgCmd(buf, 'backtrace', [
512 \ '>backtrace',
513 \ ' 4 User Autocommands for "TestGlobalFunction"',
514 \ ' 3 function GlobalFunction[1]',
515 \ ' 2 CallAFunction[1]',
516 \ ' 1 SourceAnotherFile[1]',
517 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
518 \ 'line 1: func DoAThing()'])
519
520 " step until we have another meaninfgul trace
521 call RunDbgCmd(buf, 'step', ['line 5: func File2Function()'])
522 call RunDbgCmd(buf, 'step', ['line 9: call File2Function()'])
523 call RunDbgCmd(buf, 'backtrace', [
524 \ '>backtrace',
525 \ ' 4 User Autocommands for "TestGlobalFunction"',
526 \ ' 3 function GlobalFunction[1]',
527 \ ' 2 CallAFunction[1]',
528 \ ' 1 SourceAnotherFile[1]',
529 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
530 \ 'line 9: call File2Function()'])
531
532 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
533 call RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"'])
534 call RunDbgCmd(buf, 'backtrace', [
535 \ '>backtrace',
536 \ ' 6 User Autocommands for "TestGlobalFunction"',
537 \ ' 5 function GlobalFunction[1]',
538 \ ' 4 CallAFunction[1]',
539 \ ' 3 SourceAnotherFile[1]',
540 \ ' 2 script ' .. getcwd() .. '/Xtest2.vim[9]',
541 \ ' 1 function File2Function[1]',
542 \ '->0 DoAThing',
543 \ 'line 1: echo "DoAThing"'])
544
545 " Now, step (back to Xfile1.vim), and call the function _in_ Xfile2.vim
546 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
547 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
548 call RunDbgCmd(buf, 'step', ['line 10: End of sourced file'])
549 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
550 call RunDbgCmd(buf, 'step', ['line 2: call File2Function()'])
551 call RunDbgCmd(buf, 'backtrace', [
552 \ '>backtrace',
553 \ ' 2 User Autocommands for "TestGlobalFunction"',
554 \ ' 1 function GlobalFunction[1]',
555 \ '->0 CallAFunction',
556 \ 'line 2: call File2Function()'])
557
558 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
559 call RunDbgCmd(buf, 'backtrace', [
560 \ '>backtrace',
561 \ ' 3 User Autocommands for "TestGlobalFunction"',
562 \ ' 2 function GlobalFunction[1]',
563 \ ' 1 CallAFunction[2]',
564 \ '->0 File2Function',
565 \ 'line 1: call DoAThing()'])
566
567
568 " Now unwind so that we get back to the original autocommand (and the second
569 " cmd echo "Done")
570 call RunDbgCmd(buf, 'finish', ['line 1: End of function'])
571 call RunDbgCmd(buf, 'backtrace', [
572 \ '>backtrace',
573 \ ' 3 User Autocommands for "TestGlobalFunction"',
574 \ ' 2 function GlobalFunction[1]',
575 \ ' 1 CallAFunction[2]',
576 \ '->0 File2Function',
577 \ 'line 1: End of function'])
578
579 call RunDbgCmd(buf, 'finish', ['line 2: End of function'])
580 call RunDbgCmd(buf, 'backtrace', [
581 \ '>backtrace',
582 \ ' 2 User Autocommands for "TestGlobalFunction"',
583 \ ' 1 function GlobalFunction[1]',
584 \ '->0 CallAFunction',
585 \ 'line 2: End of function'])
586
587 call RunDbgCmd(buf, 'finish', ['line 1: End of function'])
588 call RunDbgCmd(buf, 'backtrace', [
589 \ '>backtrace',
590 \ ' 1 User Autocommands for "TestGlobalFunction"',
591 \ '->0 function GlobalFunction',
592 \ 'line 1: End of function'])
593
594 call RunDbgCmd(buf, 'step', ['cmd: echo "Done"'])
595 call RunDbgCmd(buf, 'backtrace', [
596 \ '>backtrace',
597 \ '->0 User Autocommands for "TestGlobalFunction"',
598 \ 'cmd: echo "Done"'])
599
600 call StopVimInTerminal(buf)
601 call delete('Xtest1.vim')
602 call delete('Xtest2.vim')
603endfunc
604
605func Test_Backtrace_CmdLine()
606 CheckRunVimInTerminal
607
608 let file1 =<< trim END
609 func SourceAnotherFile()
610 source Xtest2.vim
611 endfunc
612
613 func CallAFunction()
614 call SourceAnotherFile()
615 call File2Function()
616 endfunc
617
618 func GlobalFunction()
619 call CallAFunction()
620 endfunc
621
622 au User TestGlobalFunction :call GlobalFunction() | echo "Done"
623 END
624 call writefile(file1, 'Xtest1.vim')
625
626 let file2 =<< trim END
627 func DoAThing()
628 echo "DoAThing"
629 endfunc
630
631 func File2Function()
632 call DoAThing()
633 endfunc
634
635 call File2Function()
636 END
637 call writefile(file2, 'Xtest2.vim')
638
639 let buf = RunVimInTerminal(
640 \ '-S Xtest1.vim -c "debug call GlobalFunction()"',
641 \ {'wait_for_ruler': 0})
642
643 " Need to wait for the vim-in-terminal to be ready
644 call CheckDbgOutput(buf, ['command line',
645 \ 'cmd: call GlobalFunction()'])
646
647 " At this point the ontly thing in the stack is the cmdline
648 call RunDbgCmd(buf, 'backtrace', [
649 \ '>backtrace',
650 \ '->0 command line',
651 \ 'cmd: call GlobalFunction()'])
652
653 " And now we're back into the call stack
654 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
655 call RunDbgCmd(buf, 'backtrace', [
656 \ '>backtrace',
657 \ ' 1 command line',
658 \ '->0 function GlobalFunction',
659 \ 'line 1: call CallAFunction()'])
660
661 call StopVimInTerminal(buf)
662 call delete('Xtest1.vim')
663 call delete('Xtest2.vim')
664endfunc
665
666func Test_Backtrace_DefFunction()
667 CheckRunVimInTerminal
668
669 let file1 =<< trim END
670 vim9script
671 import File2Function from './Xtest2.vim'
672
673 def SourceAnotherFile()
674 source Xtest2.vim
675 enddef
676
677 def CallAFunction()
678 SourceAnotherFile()
679 File2Function()
680 enddef
681
682 def g:GlobalFunction()
683 CallAFunction()
684 enddef
685
686 defcompile
687 END
688 call writefile(file1, 'Xtest1.vim')
689
690 let file2 =<< trim END
691 vim9script
692
693 def DoAThing(): number
694 let a = 100 * 2
695 a += 3
696 return a
697 enddef
698
699 export def File2Function()
700 DoAThing()
701 enddef
702
703 defcompile
704 File2Function()
705 END
706 call writefile(file2, 'Xtest2.vim')
707
708 let buf = RunVimInTerminal('-S Xtest1.vim', {})
709
710 call RunDbgCmd(buf,
711 \ ':debug call GlobalFunction()',
712 \ ['cmd: call GlobalFunction()'])
713
714 " FIXME: Vim9 lines are not debugged!
715 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
716
717 " But they do appear in the backtrace
718 call RunDbgCmd(buf, 'backtrace', [
719 \ '\V>backtrace',
720 \ '\V 2 function GlobalFunction[1]',
721 \ '\V 1 <SNR>\.\*_CallAFunction[1]',
722 \ '\V->0 <SNR>\.\*_SourceAnotherFile',
723 \ '\Vline 1: source Xtest2.vim'],
724 \ #{match: 'pattern'})
725
726
727 call RunDbgCmd(buf, 'step', ['line 1: vim9script'])
728 call RunDbgCmd(buf, 'step', ['line 3: def DoAThing(): number'])
729 call RunDbgCmd(buf, 'step', ['line 9: export def File2Function()'])
730 call RunDbgCmd(buf, 'step', ['line 9: def File2Function()'])
731 call RunDbgCmd(buf, 'step', ['line 13: defcompile'])
732 call RunDbgCmd(buf, 'step', ['line 14: File2Function()'])
733 call RunDbgCmd(buf, 'backtrace', [
734 \ '\V>backtrace',
735 \ '\V 3 function GlobalFunction[1]',
736 \ '\V 2 <SNR>\.\*_CallAFunction[1]',
737 \ '\V 1 <SNR>\.\*_SourceAnotherFile[1]',
738 \ '\V->0 script ' .. getcwd() .. '/Xtest2.vim',
739 \ '\Vline 14: File2Function()'],
740 \ #{match: 'pattern'})
741
742 " Don't step into compiled functions...
743 call RunDbgCmd(buf, 'step', ['line 15: End of sourced file'])
744 call RunDbgCmd(buf, 'backtrace', [
745 \ '\V>backtrace',
746 \ '\V 3 function GlobalFunction[1]',
747 \ '\V 2 <SNR>\.\*_CallAFunction[1]',
748 \ '\V 1 <SNR>\.\*_SourceAnotherFile[1]',
749 \ '\V->0 script ' .. getcwd() .. '/Xtest2.vim',
750 \ '\Vline 15: End of sourced file'],
751 \ #{match: 'pattern'})
752
753
754 call StopVimInTerminal(buf)
755 call delete('Xtest1.vim')
756 call delete('Xtest2.vim')
757endfunc