blob: 8c51675429b6a19494f050f0307502177ed7b789 [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 Moolenaarb7f4fa52020-08-08 14:41:52 +02007CheckRunVimInTerminal
8
9func CheckCWD()
10 " Check that the longer lines don't wrap due to the length of the script name
11 " in cwd
12 let script_len = len( getcwd() .. '/Xtest1.vim' )
13 let longest_line = len( 'Breakpoint in "" line 1' )
14 if script_len > ( 75 - longest_line )
15 throw 'Skipped: Your CWD has too many characters'
16 endif
17endfunc
18command! -nargs=0 -bar CheckCWD call CheckCWD()
19
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +020020func CheckDbgOutput(buf, lines, options = {})
21 " Verify the expected output
22 let lnum = 20 - len(a:lines)
23 for l in a:lines
24 if get(a:options, 'match', 'equal') ==# 'pattern'
25 call WaitForAssert({-> assert_match(l, term_getline(a:buf, lnum))}, 200)
26 else
27 call WaitForAssert({-> assert_equal(l, term_getline(a:buf, lnum))}, 200)
28 endif
29 let lnum += 1
30 endfor
31endfunc
32
Bram Moolenaar113bf062019-04-17 16:54:05 +020033" Run a Vim debugger command
34" If the expected output argument is supplied, then check for it.
35func RunDbgCmd(buf, cmd, ...)
36 call term_sendkeys(a:buf, a:cmd . "\r")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +020037 call TermWait(a:buf)
Bram Moolenaar113bf062019-04-17 16:54:05 +020038
39 if a:0 != 0
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +020040 let options = #{match: 'equal'}
41 if a:0 > 1
42 call extend(options, a:2)
43 endif
44 call CheckDbgOutput(a:buf, a:1, options)
Bram Moolenaar113bf062019-04-17 16:54:05 +020045 endif
46endfunc
47
48" Debugger tests
49func Test_Debugger()
Bram Moolenaar113bf062019-04-17 16:54:05 +020050 " Create a Vim script with some functions
Bram Moolenaare7eb9272019-06-24 00:58:07 +020051 let lines =<< trim END
52 func Foo()
53 let var1 = 1
54 let var2 = Bar(var1) + 9
55 return var2
56 endfunc
57 func Bar(var)
58 let var1 = 2 + a:var
59 let var2 = Bazz(var1) + 4
60 return var2
61 endfunc
62 func Bazz(var)
63 try
64 let var1 = 3 + a:var
65 let var3 = "another var"
66 let var3 = "value2"
67 catch
68 let var4 = "exception"
69 endtry
70 return var1
71 endfunc
72 END
73 call writefile(lines, 'Xtest.vim')
Bram Moolenaar113bf062019-04-17 16:54:05 +020074
75 " Start Vim in a terminal
76 let buf = RunVimInTerminal('-S Xtest.vim', {})
77
78 " Start the Vim debugger
Bram Moolenaarddd33082019-06-03 23:07:25 +020079 call RunDbgCmd(buf, ':debug echo Foo()', ['cmd: echo Foo()'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020080
81 " Create a few stack frames by stepping through functions
Bram Moolenaarddd33082019-06-03 23:07:25 +020082 call RunDbgCmd(buf, 'step', ['line 1: let var1 = 1'])
83 call RunDbgCmd(buf, 'step', ['line 2: let var2 = Bar(var1) + 9'])
84 call RunDbgCmd(buf, 'step', ['line 1: let var1 = 2 + a:var'])
85 call RunDbgCmd(buf, 'step', ['line 2: let var2 = Bazz(var1) + 4'])
86 call RunDbgCmd(buf, 'step', ['line 1: try'])
87 call RunDbgCmd(buf, 'step', ['line 2: let var1 = 3 + a:var'])
88 call RunDbgCmd(buf, 'step', ['line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020089
90 " check backtrace
91 call RunDbgCmd(buf, 'backtrace', [
92 \ ' 2 function Foo[2]',
93 \ ' 1 Bar[2]',
94 \ '->0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +020095 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020096
97 " Check variables in different stack frames
98 call RunDbgCmd(buf, 'echo var1', ['6'])
99
100 call RunDbgCmd(buf, 'up')
101 call RunDbgCmd(buf, 'back', [
102 \ ' 2 function Foo[2]',
103 \ '->1 Bar[2]',
104 \ ' 0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200105 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200106 call RunDbgCmd(buf, 'echo var1', ['3'])
107
108 call RunDbgCmd(buf, 'u')
109 call RunDbgCmd(buf, 'bt', [
110 \ '->2 function Foo[2]',
111 \ ' 1 Bar[2]',
112 \ ' 0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200113 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200114 call RunDbgCmd(buf, 'echo var1', ['1'])
115
116 " Undefined variables
117 call RunDbgCmd(buf, 'step')
118 call RunDbgCmd(buf, 'frame 2')
119 call RunDbgCmd(buf, 'echo var3', [
120 \ 'Error detected while processing function Foo[2]..Bar[2]..Bazz:',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200121 \ 'line 4:',
Bram Moolenaar113bf062019-04-17 16:54:05 +0200122 \ 'E121: Undefined variable: var3'])
123
124 " var3 is defined in this level with some other value
125 call RunDbgCmd(buf, 'fr 0')
126 call RunDbgCmd(buf, 'echo var3', ['another var'])
127
128 call RunDbgCmd(buf, 'step')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200129 call RunDbgCmd(buf, '')
130 call RunDbgCmd(buf, '')
131 call RunDbgCmd(buf, '')
132 call RunDbgCmd(buf, '')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200133 call RunDbgCmd(buf, 'step', [
134 \ 'function Foo[2]..Bar',
135 \ 'line 3: End of function'])
136 call RunDbgCmd(buf, 'up')
137
138 " Undefined var2
139 call RunDbgCmd(buf, 'echo var2', [
140 \ 'Error detected while processing function Foo[2]..Bar:',
141 \ 'line 3:',
142 \ 'E121: Undefined variable: var2'])
143
144 " Var2 is defined with 10
145 call RunDbgCmd(buf, 'down')
146 call RunDbgCmd(buf, 'echo var2', ['10'])
147
148 " Backtrace movements
149 call RunDbgCmd(buf, 'b', [
150 \ ' 1 function Foo[2]',
151 \ '->0 Bar',
152 \ 'line 3: End of function'])
153
154 " next command cannot go down, we are on bottom
155 call RunDbgCmd(buf, 'down', ['frame is zero'])
156 call RunDbgCmd(buf, 'up')
157
158 " next command cannot go up, we are on top
159 call RunDbgCmd(buf, 'up', ['frame at highest level: 1'])
160 call RunDbgCmd(buf, 'where', [
161 \ '->1 function Foo[2]',
162 \ ' 0 Bar',
163 \ 'line 3: End of function'])
164
165 " fil is not frame or finish, it is file
166 call RunDbgCmd(buf, 'fil', ['"[No Name]" --No lines in buffer--'])
167
168 " relative backtrace movement
169 call RunDbgCmd(buf, 'fr -1')
170 call RunDbgCmd(buf, 'frame', [
171 \ ' 1 function Foo[2]',
172 \ '->0 Bar',
173 \ 'line 3: End of function'])
174
175 call RunDbgCmd(buf, 'fr +1')
176 call RunDbgCmd(buf, 'fram', [
177 \ '->1 function Foo[2]',
178 \ ' 0 Bar',
179 \ 'line 3: End of function'])
180
181 " go beyond limits does not crash
182 call RunDbgCmd(buf, 'fr 100', ['frame at highest level: 1'])
183 call RunDbgCmd(buf, 'fra', [
184 \ '->1 function Foo[2]',
185 \ ' 0 Bar',
186 \ 'line 3: End of function'])
187
188 call RunDbgCmd(buf, 'frame -40', ['frame is zero'])
189 call RunDbgCmd(buf, 'fram', [
190 \ ' 1 function Foo[2]',
191 \ '->0 Bar',
192 \ 'line 3: End of function'])
193
194 " final result 19
195 call RunDbgCmd(buf, 'cont', ['19'])
196
197 " breakpoints tests
198
199 " Start a debug session, so that reading the last line from the terminal
200 " works properly.
201 call RunDbgCmd(buf, ':debug echo Foo()')
202
203 " No breakpoints
204 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
205
206 " Place some breakpoints
207 call RunDbgCmd(buf, 'breaka func Bar')
208 call RunDbgCmd(buf, 'breaklis', [' 1 func Bar line 1'])
209 call RunDbgCmd(buf, 'breakadd func 3 Bazz')
210 call RunDbgCmd(buf, 'breaklist', [' 1 func Bar line 1',
211 \ ' 2 func Bazz line 3'])
212
213 " Check whether the breakpoints are hit
214 call RunDbgCmd(buf, 'cont', [
215 \ 'Breakpoint in "Bar" line 1',
216 \ 'function Foo[2]..Bar',
217 \ 'line 1: let var1 = 2 + a:var'])
218 call RunDbgCmd(buf, 'cont', [
219 \ 'Breakpoint in "Bazz" line 3',
220 \ 'function Foo[2]..Bar[2]..Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200221 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200222
223 " Delete the breakpoints
224 call RunDbgCmd(buf, 'breakd 1')
225 call RunDbgCmd(buf, 'breakli', [' 2 func Bazz line 3'])
226 call RunDbgCmd(buf, 'breakdel func 3 Bazz')
227 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
228
229 call RunDbgCmd(buf, 'cont')
230
231 " Make sure the breakpoints are removed
232 call RunDbgCmd(buf, ':echo Foo()', ['19'])
233
234 " Delete a non-existing breakpoint
235 call RunDbgCmd(buf, ':breakdel 2', ['E161: Breakpoint not found: 2'])
236
237 " Expression breakpoint
238 call RunDbgCmd(buf, ':breakadd func 2 Bazz')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200239 call RunDbgCmd(buf, ':echo Bazz(1)', [
240 \ 'Entering Debug mode. Type "cont" to continue.',
241 \ 'function Bazz',
242 \ 'line 2: let var1 = 3 + a:var'])
243 call RunDbgCmd(buf, 'step')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200244 call RunDbgCmd(buf, 'step')
245 call RunDbgCmd(buf, 'breaka expr var3')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200246 call RunDbgCmd(buf, 'breakl', [' 3 func Bazz line 2',
247 \ ' 4 expr var3'])
248 call RunDbgCmd(buf, 'cont', ['Breakpoint in "Bazz" line 5',
Bram Moolenaar113bf062019-04-17 16:54:05 +0200249 \ 'Oldval = "''another var''"',
250 \ 'Newval = "''value2''"',
251 \ 'function Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200252 \ 'line 5: catch'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200253
254 call RunDbgCmd(buf, 'breakdel *')
255 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
256
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200257 " Check for error cases
258 call RunDbgCmd(buf, 'breakadd abcd', [
259 \ 'Error detected while processing function Bazz:',
260 \ 'line 5:',
261 \ 'E475: Invalid argument: abcd'])
262 call RunDbgCmd(buf, 'breakadd func', ['E475: Invalid argument: func'])
263 call RunDbgCmd(buf, 'breakadd func 2', ['E475: Invalid argument: func 2'])
264 call RunDbgCmd(buf, 'breaka func a()', ['E475: Invalid argument: func a()'])
265 call RunDbgCmd(buf, 'breakd abcd', ['E475: Invalid argument: abcd'])
266 call RunDbgCmd(buf, 'breakd func', ['E475: Invalid argument: func'])
267 call RunDbgCmd(buf, 'breakd func a()', ['E475: Invalid argument: func a()'])
268 call RunDbgCmd(buf, 'breakd func a', ['E161: Breakpoint not found: func a'])
269 call RunDbgCmd(buf, 'breakd expr', ['E475: Invalid argument: expr'])
270 call RunDbgCmd(buf, 'breakd expr x', [
271 \ 'E121: Undefined variable: x',
272 \ 'E161: Breakpoint not found: expr x'])
273
Bram Moolenaar113bf062019-04-17 16:54:05 +0200274 " finish the current function
275 call RunDbgCmd(buf, 'finish', [
276 \ 'function Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200277 \ 'line 8: End of function'])
278 call RunDbgCmd(buf, 'cont')
279
280 " Test for :next
281 call RunDbgCmd(buf, ':debug echo Bar(1)')
282 call RunDbgCmd(buf, 'step')
283 call RunDbgCmd(buf, 'next')
284 call RunDbgCmd(buf, '', [
285 \ 'function Bar',
286 \ 'line 3: return var2'])
287 call RunDbgCmd(buf, 'c')
288
289 " Test for :interrupt
290 call RunDbgCmd(buf, ':debug echo Bazz(1)')
291 call RunDbgCmd(buf, 'step')
292 call RunDbgCmd(buf, 'step')
293 call RunDbgCmd(buf, 'interrupt', [
294 \ 'Exception thrown: Vim:Interrupt',
295 \ 'function Bazz',
296 \ 'line 5: catch'])
297 call RunDbgCmd(buf, 'c')
298
299 " Test for :quit
300 call RunDbgCmd(buf, ':debug echo Foo()')
301 call RunDbgCmd(buf, 'breakdel *')
302 call RunDbgCmd(buf, 'breakadd func 3 Foo')
303 call RunDbgCmd(buf, 'breakadd func 3 Bazz')
304 call RunDbgCmd(buf, 'cont', [
305 \ 'Breakpoint in "Bazz" line 3',
306 \ 'function Foo[2]..Bar[2]..Bazz',
307 \ 'line 3: let var3 = "another var"'])
308 call RunDbgCmd(buf, 'quit', [
309 \ 'Breakpoint in "Foo" line 3',
310 \ 'function Foo',
311 \ 'line 3: return var2'])
312 call RunDbgCmd(buf, 'breakdel *')
313 call RunDbgCmd(buf, 'quit')
314 call RunDbgCmd(buf, 'enew! | only!')
315
316 call StopVimInTerminal(buf)
317
318 " Tests for :breakadd file and :breakadd here
319 " Breakpoints should be set before sourcing the file
320
Bram Moolenaare7eb9272019-06-24 00:58:07 +0200321 let lines =<< trim END
322 let var1 = 10
323 let var2 = 20
324 let var3 = 30
325 let var4 = 40
326 END
327 call writefile(lines, 'Xtest.vim')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200328
329 " Start Vim in a terminal
330 let buf = RunVimInTerminal('Xtest.vim', {})
331 call RunDbgCmd(buf, ':breakadd file 2 Xtest.vim')
332 call RunDbgCmd(buf, ':4 | breakadd here')
333 call RunDbgCmd(buf, ':source Xtest.vim', ['line 2: let var2 = 20'])
334 call RunDbgCmd(buf, 'cont', ['line 4: let var4 = 40'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200335 call RunDbgCmd(buf, 'cont')
336
337 call StopVimInTerminal(buf)
338
339 call delete('Xtest.vim')
Bram Moolenaar16c62322020-08-13 19:20:04 +0200340 %bw!
341 call assert_fails('breakadd here', 'E32:')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200342endfunc
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200343
344func Test_Backtrace_Through_Source()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200345 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200346 let file1 =<< trim END
347 func SourceAnotherFile()
348 source Xtest2.vim
349 endfunc
350
351 func CallAFunction()
352 call SourceAnotherFile()
353 call File2Function()
354 endfunc
355
356 func GlobalFunction()
357 call CallAFunction()
358 endfunc
359 END
360 call writefile(file1, 'Xtest1.vim')
361
362 let file2 =<< trim END
363 func DoAThing()
364 echo "DoAThing"
365 endfunc
366
367 func File2Function()
368 call DoAThing()
369 endfunc
370
371 call File2Function()
372 END
373 call writefile(file2, 'Xtest2.vim')
374
375 let buf = RunVimInTerminal('-S Xtest1.vim', {})
376
377 call RunDbgCmd(buf,
378 \ ':debug call GlobalFunction()',
379 \ ['cmd: call GlobalFunction()'])
380 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
381
382 call RunDbgCmd(buf, 'backtrace', ['>backtrace',
383 \ '->0 function GlobalFunction',
384 \ 'line 1: call CallAFunction()'])
385
386 call RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()'])
387 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
388
389 call RunDbgCmd(buf, 'backtrace', ['>backtrace',
390 \ ' 2 function GlobalFunction[1]',
391 \ ' 1 CallAFunction[1]',
392 \ '->0 SourceAnotherFile',
393 \ 'line 1: source Xtest2.vim'])
394
395 " Step into the 'source' command. Note that we print the full trace all the
396 " way though the source command.
397 call RunDbgCmd(buf, 'step', ['line 1: func DoAThing()'])
398 call RunDbgCmd(buf, 'backtrace', [
399 \ '>backtrace',
400 \ ' 3 function GlobalFunction[1]',
401 \ ' 2 CallAFunction[1]',
402 \ ' 1 SourceAnotherFile[1]',
403 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
404 \ 'line 1: func DoAThing()'])
405
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200406 call RunDbgCmd( buf, 'up' )
407 call RunDbgCmd( buf, 'backtrace', [
408 \ '>backtrace',
409 \ ' 3 function GlobalFunction[1]',
410 \ ' 2 CallAFunction[1]',
411 \ '->1 SourceAnotherFile[1]',
412 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
413 \ 'line 1: func DoAThing()' ] )
414
415 call RunDbgCmd( buf, 'up' )
416 call RunDbgCmd( buf, 'backtrace', [
417 \ '>backtrace',
418 \ ' 3 function GlobalFunction[1]',
419 \ '->2 CallAFunction[1]',
420 \ ' 1 SourceAnotherFile[1]',
421 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
422 \ 'line 1: func DoAThing()' ] )
423
424 call RunDbgCmd( buf, 'up' )
425 call RunDbgCmd( buf, 'backtrace', [
426 \ '>backtrace',
427 \ '->3 function GlobalFunction[1]',
428 \ ' 2 CallAFunction[1]',
429 \ ' 1 SourceAnotherFile[1]',
430 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
431 \ 'line 1: func DoAThing()' ] )
432
433 call RunDbgCmd( buf, 'up', [ 'frame at highest level: 3' ] )
434 call RunDbgCmd( buf, 'backtrace', [
435 \ '>backtrace',
436 \ '->3 function GlobalFunction[1]',
437 \ ' 2 CallAFunction[1]',
438 \ ' 1 SourceAnotherFile[1]',
439 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
440 \ 'line 1: func DoAThing()' ] )
441
442 call RunDbgCmd( buf, 'down' )
443 call RunDbgCmd( buf, 'backtrace', [
444 \ '>backtrace',
445 \ ' 3 function GlobalFunction[1]',
446 \ '->2 CallAFunction[1]',
447 \ ' 1 SourceAnotherFile[1]',
448 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
449 \ 'line 1: func DoAThing()' ] )
450
451 call RunDbgCmd( buf, 'down' )
452 call RunDbgCmd( buf, 'backtrace', [
453 \ '>backtrace',
454 \ ' 3 function GlobalFunction[1]',
455 \ ' 2 CallAFunction[1]',
456 \ '->1 SourceAnotherFile[1]',
457 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
458 \ 'line 1: func DoAThing()' ] )
459
460 call RunDbgCmd( buf, 'down' )
461 call RunDbgCmd( buf, 'backtrace', [
462 \ '>backtrace',
463 \ ' 3 function GlobalFunction[1]',
464 \ ' 2 CallAFunction[1]',
465 \ ' 1 SourceAnotherFile[1]',
466 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
467 \ 'line 1: func DoAThing()' ] )
468
469 call RunDbgCmd( buf, 'down', [ 'frame is zero' ] )
470
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200471 " step until we have another meaninfgul trace
472 call RunDbgCmd(buf, 'step', ['line 5: func File2Function()'])
473 call RunDbgCmd(buf, 'step', ['line 9: call File2Function()'])
474 call RunDbgCmd(buf, 'backtrace', [
475 \ '>backtrace',
476 \ ' 3 function GlobalFunction[1]',
477 \ ' 2 CallAFunction[1]',
478 \ ' 1 SourceAnotherFile[1]',
479 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
480 \ 'line 9: call File2Function()'])
481
482 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
483 call RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"'])
484 call RunDbgCmd(buf, 'backtrace', [
485 \ '>backtrace',
486 \ ' 5 function GlobalFunction[1]',
487 \ ' 4 CallAFunction[1]',
488 \ ' 3 SourceAnotherFile[1]',
489 \ ' 2 script ' .. getcwd() .. '/Xtest2.vim[9]',
490 \ ' 1 function File2Function[1]',
491 \ '->0 DoAThing',
492 \ 'line 1: echo "DoAThing"'])
493
494 " Now, step (back to Xfile1.vim), and call the function _in_ Xfile2.vim
495 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
496 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
497 call RunDbgCmd(buf, 'step', ['line 10: End of sourced file'])
498 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
499 call RunDbgCmd(buf, 'step', ['line 2: call File2Function()'])
500 call RunDbgCmd(buf, 'backtrace', [
501 \ '>backtrace',
502 \ ' 1 function GlobalFunction[1]',
503 \ '->0 CallAFunction',
504 \ 'line 2: call File2Function()'])
505
506 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
507 call RunDbgCmd(buf, 'backtrace', [
508 \ '>backtrace',
509 \ ' 2 function GlobalFunction[1]',
510 \ ' 1 CallAFunction[2]',
511 \ '->0 File2Function',
512 \ 'line 1: call DoAThing()'])
513
514 call StopVimInTerminal(buf)
515 call delete('Xtest1.vim')
516 call delete('Xtest2.vim')
517endfunc
518
519func Test_Backtrace_Autocmd()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200520 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200521 let file1 =<< trim END
522 func SourceAnotherFile()
523 source Xtest2.vim
524 endfunc
525
526 func CallAFunction()
527 call SourceAnotherFile()
528 call File2Function()
529 endfunc
530
531 func GlobalFunction()
532 call CallAFunction()
533 endfunc
534
535 au User TestGlobalFunction :call GlobalFunction() | echo "Done"
536 END
537 call writefile(file1, 'Xtest1.vim')
538
539 let file2 =<< trim END
540 func DoAThing()
541 echo "DoAThing"
542 endfunc
543
544 func File2Function()
545 call DoAThing()
546 endfunc
547
548 call File2Function()
549 END
550 call writefile(file2, 'Xtest2.vim')
551
552 let buf = RunVimInTerminal('-S Xtest1.vim', {})
553
554 call RunDbgCmd(buf,
555 \ ':debug doautocmd User TestGlobalFunction',
556 \ ['cmd: doautocmd User TestGlobalFunction'])
557 call RunDbgCmd(buf, 'step', ['cmd: call GlobalFunction() | echo "Done"'])
558
559 " At this point the ontly thing in the stack is the autocommand
560 call RunDbgCmd(buf, 'backtrace', [
561 \ '>backtrace',
562 \ '->0 User Autocommands for "TestGlobalFunction"',
563 \ 'cmd: call GlobalFunction() | echo "Done"'])
564
565 " And now we're back into the call stack
566 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
567 call RunDbgCmd(buf, 'backtrace', [
568 \ '>backtrace',
569 \ ' 1 User Autocommands for "TestGlobalFunction"',
570 \ '->0 function GlobalFunction',
571 \ 'line 1: call CallAFunction()'])
572
573 call RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()'])
574 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
575
576 call RunDbgCmd(buf, 'backtrace', [
577 \ '>backtrace',
578 \ ' 3 User Autocommands for "TestGlobalFunction"',
579 \ ' 2 function GlobalFunction[1]',
580 \ ' 1 CallAFunction[1]',
581 \ '->0 SourceAnotherFile',
582 \ 'line 1: source Xtest2.vim'])
583
584 " Step into the 'source' command. Note that we print the full trace all the
585 " way though the source command.
586 call RunDbgCmd(buf, 'step', ['line 1: func DoAThing()'])
587 call RunDbgCmd(buf, 'backtrace', [
588 \ '>backtrace',
589 \ ' 4 User Autocommands for "TestGlobalFunction"',
590 \ ' 3 function GlobalFunction[1]',
591 \ ' 2 CallAFunction[1]',
592 \ ' 1 SourceAnotherFile[1]',
593 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
594 \ 'line 1: func DoAThing()'])
595
Bram Moolenaarc63b72b2020-08-22 16:04:52 +0200596 call RunDbgCmd( buf, 'up' )
597 call RunDbgCmd( buf, 'backtrace', [
598 \ '>backtrace',
599 \ ' 4 User Autocommands for "TestGlobalFunction"',
600 \ ' 3 function GlobalFunction[1]',
601 \ ' 2 CallAFunction[1]',
602 \ '->1 SourceAnotherFile[1]',
603 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
604 \ 'line 1: func DoAThing()' ] )
605
606 call RunDbgCmd( buf, 'up' )
607 call RunDbgCmd( buf, 'backtrace', [
608 \ '>backtrace',
609 \ ' 4 User Autocommands for "TestGlobalFunction"',
610 \ ' 3 function GlobalFunction[1]',
611 \ '->2 CallAFunction[1]',
612 \ ' 1 SourceAnotherFile[1]',
613 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
614 \ 'line 1: func DoAThing()' ] )
615
616 call RunDbgCmd( buf, 'up' )
617 call RunDbgCmd( buf, 'backtrace', [
618 \ '>backtrace',
619 \ ' 4 User Autocommands for "TestGlobalFunction"',
620 \ '->3 function GlobalFunction[1]',
621 \ ' 2 CallAFunction[1]',
622 \ ' 1 SourceAnotherFile[1]',
623 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
624 \ 'line 1: func DoAThing()' ] )
625
626 call RunDbgCmd( buf, 'up' )
627 call RunDbgCmd( buf, 'backtrace', [
628 \ '>backtrace',
629 \ '->4 User Autocommands for "TestGlobalFunction"',
630 \ ' 3 function GlobalFunction[1]',
631 \ ' 2 CallAFunction[1]',
632 \ ' 1 SourceAnotherFile[1]',
633 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
634 \ 'line 1: func DoAThing()' ] )
635
636 call RunDbgCmd( buf, 'up', [ 'frame at highest level: 4' ] )
637 call RunDbgCmd( buf, 'backtrace', [
638 \ '>backtrace',
639 \ '->4 User Autocommands for "TestGlobalFunction"',
640 \ ' 3 function GlobalFunction[1]',
641 \ ' 2 CallAFunction[1]',
642 \ ' 1 SourceAnotherFile[1]',
643 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
644 \ 'line 1: func DoAThing()' ] )
645
646 call RunDbgCmd( buf, 'down' )
647 call RunDbgCmd( buf, 'backtrace', [
648 \ '>backtrace',
649 \ ' 4 User Autocommands for "TestGlobalFunction"',
650 \ '->3 function GlobalFunction[1]',
651 \ ' 2 CallAFunction[1]',
652 \ ' 1 SourceAnotherFile[1]',
653 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
654 \ 'line 1: func DoAThing()' ] )
655
656
657 call RunDbgCmd( buf, 'down' )
658 call RunDbgCmd( buf, 'backtrace', [
659 \ '>backtrace',
660 \ ' 4 User Autocommands for "TestGlobalFunction"',
661 \ ' 3 function GlobalFunction[1]',
662 \ '->2 CallAFunction[1]',
663 \ ' 1 SourceAnotherFile[1]',
664 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
665 \ 'line 1: func DoAThing()' ] )
666
667 call RunDbgCmd( buf, 'down' )
668 call RunDbgCmd( buf, 'backtrace', [
669 \ '>backtrace',
670 \ ' 4 User Autocommands for "TestGlobalFunction"',
671 \ ' 3 function GlobalFunction[1]',
672 \ ' 2 CallAFunction[1]',
673 \ '->1 SourceAnotherFile[1]',
674 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
675 \ 'line 1: func DoAThing()' ] )
676
677 call RunDbgCmd( buf, 'down' )
678 call RunDbgCmd( buf, 'backtrace', [
679 \ '>backtrace',
680 \ ' 4 User Autocommands for "TestGlobalFunction"',
681 \ ' 3 function GlobalFunction[1]',
682 \ ' 2 CallAFunction[1]',
683 \ ' 1 SourceAnotherFile[1]',
684 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
685 \ 'line 1: func DoAThing()' ] )
686
687 call RunDbgCmd( buf, 'down', [ 'frame is zero' ] )
688
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200689 " step until we have another meaninfgul trace
690 call RunDbgCmd(buf, 'step', ['line 5: func File2Function()'])
691 call RunDbgCmd(buf, 'step', ['line 9: call File2Function()'])
692 call RunDbgCmd(buf, 'backtrace', [
693 \ '>backtrace',
694 \ ' 4 User Autocommands for "TestGlobalFunction"',
695 \ ' 3 function GlobalFunction[1]',
696 \ ' 2 CallAFunction[1]',
697 \ ' 1 SourceAnotherFile[1]',
698 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
699 \ 'line 9: call File2Function()'])
700
701 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
702 call RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"'])
703 call RunDbgCmd(buf, 'backtrace', [
704 \ '>backtrace',
705 \ ' 6 User Autocommands for "TestGlobalFunction"',
706 \ ' 5 function GlobalFunction[1]',
707 \ ' 4 CallAFunction[1]',
708 \ ' 3 SourceAnotherFile[1]',
709 \ ' 2 script ' .. getcwd() .. '/Xtest2.vim[9]',
710 \ ' 1 function File2Function[1]',
711 \ '->0 DoAThing',
712 \ 'line 1: echo "DoAThing"'])
713
714 " Now, step (back to Xfile1.vim), and call the function _in_ Xfile2.vim
715 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
716 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
717 call RunDbgCmd(buf, 'step', ['line 10: End of sourced file'])
718 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
719 call RunDbgCmd(buf, 'step', ['line 2: call File2Function()'])
720 call RunDbgCmd(buf, 'backtrace', [
721 \ '>backtrace',
722 \ ' 2 User Autocommands for "TestGlobalFunction"',
723 \ ' 1 function GlobalFunction[1]',
724 \ '->0 CallAFunction',
725 \ 'line 2: call File2Function()'])
726
727 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
728 call RunDbgCmd(buf, 'backtrace', [
729 \ '>backtrace',
730 \ ' 3 User Autocommands for "TestGlobalFunction"',
731 \ ' 2 function GlobalFunction[1]',
732 \ ' 1 CallAFunction[2]',
733 \ '->0 File2Function',
734 \ 'line 1: call DoAThing()'])
735
736
737 " Now unwind so that we get back to the original autocommand (and the second
738 " cmd echo "Done")
739 call RunDbgCmd(buf, 'finish', ['line 1: End of function'])
740 call RunDbgCmd(buf, 'backtrace', [
741 \ '>backtrace',
742 \ ' 3 User Autocommands for "TestGlobalFunction"',
743 \ ' 2 function GlobalFunction[1]',
744 \ ' 1 CallAFunction[2]',
745 \ '->0 File2Function',
746 \ 'line 1: End of function'])
747
748 call RunDbgCmd(buf, 'finish', ['line 2: End of function'])
749 call RunDbgCmd(buf, 'backtrace', [
750 \ '>backtrace',
751 \ ' 2 User Autocommands for "TestGlobalFunction"',
752 \ ' 1 function GlobalFunction[1]',
753 \ '->0 CallAFunction',
754 \ 'line 2: End of function'])
755
756 call RunDbgCmd(buf, 'finish', ['line 1: End of function'])
757 call RunDbgCmd(buf, 'backtrace', [
758 \ '>backtrace',
759 \ ' 1 User Autocommands for "TestGlobalFunction"',
760 \ '->0 function GlobalFunction',
761 \ 'line 1: End of function'])
762
763 call RunDbgCmd(buf, 'step', ['cmd: echo "Done"'])
764 call RunDbgCmd(buf, 'backtrace', [
765 \ '>backtrace',
766 \ '->0 User Autocommands for "TestGlobalFunction"',
767 \ 'cmd: echo "Done"'])
768
769 call StopVimInTerminal(buf)
770 call delete('Xtest1.vim')
771 call delete('Xtest2.vim')
772endfunc
773
774func Test_Backtrace_CmdLine()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200775 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200776 let file1 =<< trim END
777 func SourceAnotherFile()
778 source Xtest2.vim
779 endfunc
780
781 func CallAFunction()
782 call SourceAnotherFile()
783 call File2Function()
784 endfunc
785
786 func GlobalFunction()
787 call CallAFunction()
788 endfunc
789
790 au User TestGlobalFunction :call GlobalFunction() | echo "Done"
791 END
792 call writefile(file1, 'Xtest1.vim')
793
794 let file2 =<< trim END
795 func DoAThing()
796 echo "DoAThing"
797 endfunc
798
799 func File2Function()
800 call DoAThing()
801 endfunc
802
803 call File2Function()
804 END
805 call writefile(file2, 'Xtest2.vim')
806
807 let buf = RunVimInTerminal(
808 \ '-S Xtest1.vim -c "debug call GlobalFunction()"',
809 \ {'wait_for_ruler': 0})
810
811 " Need to wait for the vim-in-terminal to be ready
812 call CheckDbgOutput(buf, ['command line',
813 \ 'cmd: call GlobalFunction()'])
814
815 " At this point the ontly thing in the stack is the cmdline
816 call RunDbgCmd(buf, 'backtrace', [
817 \ '>backtrace',
818 \ '->0 command line',
819 \ 'cmd: call GlobalFunction()'])
820
821 " And now we're back into the call stack
822 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
823 call RunDbgCmd(buf, 'backtrace', [
824 \ '>backtrace',
825 \ ' 1 command line',
826 \ '->0 function GlobalFunction',
827 \ 'line 1: call CallAFunction()'])
828
829 call StopVimInTerminal(buf)
830 call delete('Xtest1.vim')
831 call delete('Xtest2.vim')
832endfunc
833
834func Test_Backtrace_DefFunction()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200835 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200836 let file1 =<< trim END
837 vim9script
838 import File2Function from './Xtest2.vim'
839
840 def SourceAnotherFile()
841 source Xtest2.vim
842 enddef
843
844 def CallAFunction()
845 SourceAnotherFile()
846 File2Function()
847 enddef
848
849 def g:GlobalFunction()
850 CallAFunction()
851 enddef
852
853 defcompile
854 END
855 call writefile(file1, 'Xtest1.vim')
856
857 let file2 =<< trim END
858 vim9script
859
860 def DoAThing(): number
861 let a = 100 * 2
862 a += 3
863 return a
864 enddef
865
866 export def File2Function()
867 DoAThing()
868 enddef
869
870 defcompile
871 File2Function()
872 END
873 call writefile(file2, 'Xtest2.vim')
874
875 let buf = RunVimInTerminal('-S Xtest1.vim', {})
876
877 call RunDbgCmd(buf,
878 \ ':debug call GlobalFunction()',
879 \ ['cmd: call GlobalFunction()'])
880
881 " FIXME: Vim9 lines are not debugged!
882 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
883
884 " But they do appear in the backtrace
885 call RunDbgCmd(buf, 'backtrace', [
886 \ '\V>backtrace',
887 \ '\V 2 function GlobalFunction[1]',
888 \ '\V 1 <SNR>\.\*_CallAFunction[1]',
889 \ '\V->0 <SNR>\.\*_SourceAnotherFile',
890 \ '\Vline 1: source Xtest2.vim'],
891 \ #{match: 'pattern'})
892
893
894 call RunDbgCmd(buf, 'step', ['line 1: vim9script'])
895 call RunDbgCmd(buf, 'step', ['line 3: def DoAThing(): number'])
896 call RunDbgCmd(buf, 'step', ['line 9: export def File2Function()'])
897 call RunDbgCmd(buf, 'step', ['line 9: def File2Function()'])
898 call RunDbgCmd(buf, 'step', ['line 13: defcompile'])
899 call RunDbgCmd(buf, 'step', ['line 14: File2Function()'])
900 call RunDbgCmd(buf, 'backtrace', [
901 \ '\V>backtrace',
902 \ '\V 3 function GlobalFunction[1]',
903 \ '\V 2 <SNR>\.\*_CallAFunction[1]',
904 \ '\V 1 <SNR>\.\*_SourceAnotherFile[1]',
905 \ '\V->0 script ' .. getcwd() .. '/Xtest2.vim',
906 \ '\Vline 14: File2Function()'],
907 \ #{match: 'pattern'})
908
909 " Don't step into compiled functions...
910 call RunDbgCmd(buf, 'step', ['line 15: End of sourced file'])
911 call RunDbgCmd(buf, 'backtrace', [
912 \ '\V>backtrace',
913 \ '\V 3 function GlobalFunction[1]',
914 \ '\V 2 <SNR>\.\*_CallAFunction[1]',
915 \ '\V 1 <SNR>\.\*_SourceAnotherFile[1]',
916 \ '\V->0 script ' .. getcwd() .. '/Xtest2.vim',
917 \ '\Vline 15: End of sourced file'],
918 \ #{match: 'pattern'})
919
920
921 call StopVimInTerminal(buf)
922 call delete('Xtest1.vim')
923 call delete('Xtest2.vim')
924endfunc
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200925
926func Test_debug_backtrace_level()
927 CheckCWD
928 let lines =<< trim END
929 let s:file1_var = 'file1'
930 let g:global_var = 'global'
931
932 func s:File1Func( arg )
933 let s:file1_var .= a:arg
934 let local_var = s:file1_var .. ' test1'
935 let g:global_var .= local_var
936 source Xtest2.vim
937 endfunc
938
939 call s:File1Func( 'arg1' )
940 END
941 call writefile(lines, 'Xtest1.vim')
942
943 let lines =<< trim END
944 let s:file2_var = 'file2'
945
946 func s:File2Func( arg )
947 let s:file2_var .= a:arg
948 let local_var = s:file2_var .. ' test2'
949 let g:global_var .= local_var
950 endfunc
951
952 call s:File2Func( 'arg2' )
953 END
954 call writefile(lines, 'Xtest2.vim')
955
956 let file1 = getcwd() .. '/Xtest1.vim'
957 let file2 = getcwd() .. '/Xtest2.vim'
958
959 " set a breakpoint and source file1.vim
960 let buf = RunVimInTerminal(
961 \ '-c "breakadd file 1 Xtest1.vim" -S Xtest1.vim',
962 \ #{ wait_for_ruler: 0 } )
963
964 call CheckDbgOutput(buf, [
965 \ 'Breakpoint in "' .. file1 .. '" line 1',
966 \ 'Entering Debug mode. Type "cont" to continue.',
967 \ 'command line..script ' .. file1,
968 \ 'line 1: let s:file1_var = ''file1'''
969 \ ])
970
971 " step throught the initial declarations
972 call RunDbgCmd(buf, 'step', [ 'line 2: let g:global_var = ''global''' ] )
973 call RunDbgCmd(buf, 'step', [ 'line 4: func s:File1Func( arg )' ] )
974 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
975 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
976 call RunDbgCmd(buf, 'echo global_var', [ 'global' ] )
977
978 " step in to the first function
979 call RunDbgCmd(buf, 'step', [ 'line 11: call s:File1Func( ''arg1'' )' ] )
980 call RunDbgCmd(buf, 'step', [ 'line 1: let s:file1_var .= a:arg' ] )
981 call RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] )
982 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
983 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
984 call RunDbgCmd(buf,
985 \'echo global_var',
986 \[ 'E121: Undefined variable: global_var' ] )
987 call RunDbgCmd(buf,
988 \'echo local_var',
989 \[ 'E121: Undefined variable: local_var' ] )
990 call RunDbgCmd(buf,
991 \'echo l:local_var',
992 \[ 'E121: Undefined variable: l:local_var' ] )
993
994 " backtrace up
995 call RunDbgCmd(buf, 'backtrace', [
996 \ '\V>backtrace',
997 \ '\V 2 command line',
998 \ '\V 1 script ' .. file1 .. '[11]',
999 \ '\V->0 function <SNR>\.\*_File1Func',
1000 \ '\Vline 1: let s:file1_var .= a:arg',
1001 \ ],
1002 \ #{ match: 'pattern' } )
1003 call RunDbgCmd(buf, 'up', [ '>up' ] )
1004
1005 call RunDbgCmd(buf, 'backtrace', [
1006 \ '\V>backtrace',
1007 \ '\V 2 command line',
1008 \ '\V->1 script ' .. file1 .. '[11]',
1009 \ '\V 0 function <SNR>\.\*_File1Func',
1010 \ '\Vline 1: let s:file1_var .= a:arg',
1011 \ ],
1012 \ #{ match: 'pattern' } )
1013
1014 " Expression evaluation in the script frame (not the function frame)
1015 " FIXME: Unexpected in this scope (a: should not be visibnle)
1016 call RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] )
1017 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1018 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1019 " FIXME: Unexpected in this scope (global should be found)
1020 call RunDbgCmd(buf,
1021 \'echo global_var',
1022 \[ 'E121: Undefined variable: global_var' ] )
1023 call RunDbgCmd(buf,
1024 \'echo local_var',
1025 \[ 'E121: Undefined variable: local_var' ] )
1026 call RunDbgCmd(buf,
1027 \'echo l:local_var',
1028 \[ 'E121: Undefined variable: l:local_var' ] )
1029
1030
1031 " step while backtraced jumps to the latest frame
1032 call RunDbgCmd(buf, 'step', [
1033 \ 'line 2: let local_var = s:file1_var .. '' test1''' ] )
1034 call RunDbgCmd(buf, 'backtrace', [
1035 \ '\V>backtrace',
1036 \ '\V 2 command line',
1037 \ '\V 1 script ' .. file1 .. '[11]',
1038 \ '\V->0 function <SNR>\.\*_File1Func',
1039 \ '\Vline 2: let local_var = s:file1_var .. '' test1''',
1040 \ ],
1041 \ #{ match: 'pattern' } )
1042
1043 call RunDbgCmd(buf, 'step', [ 'line 3: let g:global_var .= local_var' ] )
1044 call RunDbgCmd(buf, 'echo local_var', [ 'file1arg1 test1' ] )
1045 call RunDbgCmd(buf, 'echo l:local_var', [ 'file1arg1 test1' ] )
1046
1047 call RunDbgCmd(buf, 'step', [ 'line 4: source Xtest2.vim' ] )
1048 call RunDbgCmd(buf, 'step', [ 'line 1: let s:file2_var = ''file2''' ] )
1049 call RunDbgCmd(buf, 'backtrace', [
1050 \ '\V>backtrace',
1051 \ '\V 3 command line',
1052 \ '\V 2 script ' .. file1 .. '[11]',
1053 \ '\V 1 function <SNR>\.\*_File1Func[4]',
1054 \ '\V->0 script ' .. file2,
1055 \ '\Vline 1: let s:file2_var = ''file2''',
1056 \ ],
1057 \ #{ match: 'pattern' } )
1058
1059 " Expression evaluation in the script frame file2 (not the function frame)
1060 call RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] )
1061 call RunDbgCmd(buf,
1062 \ 'echo s:file1_var',
1063 \ [ 'E121: Undefined variable: s:file1_var' ] )
1064 call RunDbgCmd(buf, 'echo g:global_var', [ 'globalfile1arg1 test1' ] )
1065 call RunDbgCmd(buf, 'echo global_var', [ 'globalfile1arg1 test1' ] )
1066 call RunDbgCmd(buf,
1067 \'echo local_var',
1068 \[ 'E121: Undefined variable: local_var' ] )
1069 call RunDbgCmd(buf,
1070 \'echo l:local_var',
1071 \[ 'E121: Undefined variable: l:local_var' ] )
1072 call RunDbgCmd(buf,
1073 \ 'echo s:file2_var',
1074 \ [ 'E121: Undefined variable: s:file2_var' ] )
1075
1076 call RunDbgCmd(buf, 'step', [ 'line 3: func s:File2Func( arg )' ] )
1077 call RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] )
1078
1079 " Up the stack to the other script context
1080 call RunDbgCmd(buf, 'up')
1081 call RunDbgCmd(buf, 'backtrace', [
1082 \ '\V>backtrace',
1083 \ '\V 3 command line',
1084 \ '\V 2 script ' .. file1 .. '[11]',
1085 \ '\V->1 function <SNR>\.\*_File1Func[4]',
1086 \ '\V 0 script ' .. file2,
1087 \ '\Vline 3: func s:File2Func( arg )',
1088 \ ],
1089 \ #{ match: 'pattern' } )
1090 " FIXME: Unexpected. Should see the a: and l: dicts from File1Func
1091 call RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] )
1092 call RunDbgCmd(buf,
1093 \ 'echo l:local_var',
1094 \ [ 'E121: Undefined variable: l:local_var' ] )
1095
1096 call RunDbgCmd(buf, 'up')
1097 call RunDbgCmd(buf, 'backtrace', [
1098 \ '\V>backtrace',
1099 \ '\V 3 command line',
1100 \ '\V->2 script ' .. file1 .. '[11]',
1101 \ '\V 1 function <SNR>\.\*_File1Func[4]',
1102 \ '\V 0 script ' .. file2,
1103 \ '\Vline 3: func s:File2Func( arg )',
1104 \ ],
1105 \ #{ match: 'pattern' } )
1106
1107 " FIXME: Unexpected (wrong script vars are used)
1108 call RunDbgCmd(buf,
1109 \ 'echo s:file1_var',
1110 \ [ 'E121: Undefined variable: s:file1_var' ] )
1111 call RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] )
1112
1113 call StopVimInTerminal(buf)
1114 call delete('Xtest1.vim')
1115 call delete('Xtest2.vim')
1116endfunc
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001117
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001118" Test for setting a breakpoint on a :endif where the :if condition is false
1119" and then quit the script. This should generate an interrupt.
1120func Test_breakpt_endif_intr()
1121 func F()
1122 let g:Xpath ..= 'a'
1123 if v:false
1124 let g:Xpath ..= 'b'
1125 endif
1126 invalid_command
1127 endfunc
1128
1129 let g:Xpath = ''
1130 breakadd func 4 F
1131 try
1132 let caught_intr = 0
1133 debuggreedy
1134 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001135 catch /^Vim:Interrupt$/
1136 call assert_match('\.F, line 4', v:throwpoint)
1137 let caught_intr = 1
1138 endtry
1139 0debuggreedy
1140 call assert_equal(1, caught_intr)
1141 call assert_equal('a', g:Xpath)
1142 breakdel *
1143 delfunc F
1144endfunc
1145
1146" Test for setting a breakpoint on a :else where the :if condition is false
1147" and then quit the script. This should generate an interrupt.
1148func Test_breakpt_else_intr()
1149 func F()
1150 let g:Xpath ..= 'a'
1151 if v:false
1152 let g:Xpath ..= 'b'
1153 else
1154 invalid_command
1155 endif
1156 invalid_command
1157 endfunc
1158
1159 let g:Xpath = ''
1160 breakadd func 4 F
1161 try
1162 let caught_intr = 0
1163 debuggreedy
1164 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001165 catch /^Vim:Interrupt$/
1166 call assert_match('\.F, line 4', v:throwpoint)
1167 let caught_intr = 1
1168 endtry
1169 0debuggreedy
1170 call assert_equal(1, caught_intr)
1171 call assert_equal('a', g:Xpath)
1172 breakdel *
1173 delfunc F
1174endfunc
1175
1176" Test for setting a breakpoint on a :endwhile where the :while condition is
1177" false and then quit the script. This should generate an interrupt.
1178func Test_breakpt_endwhile_intr()
1179 func F()
1180 let g:Xpath ..= 'a'
1181 while v:false
1182 let g:Xpath ..= 'b'
1183 endwhile
1184 invalid_command
1185 endfunc
1186
1187 let g:Xpath = ''
1188 breakadd func 4 F
1189 try
1190 let caught_intr = 0
1191 debuggreedy
1192 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001193 catch /^Vim:Interrupt$/
1194 call assert_match('\.F, line 4', v:throwpoint)
1195 let caught_intr = 1
1196 endtry
1197 0debuggreedy
1198 call assert_equal(1, caught_intr)
1199 call assert_equal('a', g:Xpath)
1200 breakdel *
1201 delfunc F
1202endfunc
1203
Bram Moolenaar16c62322020-08-13 19:20:04 +02001204" Test for setting a breakpoint on a script local function
1205func Test_breakpt_scriptlocal_func()
1206 let g:Xpath = ''
1207 func s:G()
1208 let g:Xpath ..= 'a'
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001209 endfunc
1210
Bram Moolenaar16c62322020-08-13 19:20:04 +02001211 let funcname = expand("<SID>") .. "G"
1212 exe "breakadd func 1 " .. funcname
1213 debuggreedy
1214 redir => output
1215 call feedkeys(":call " .. funcname .. "()\<CR>c\<CR>", "xt")
1216 redir END
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001217 0debuggreedy
Bram Moolenaar16c62322020-08-13 19:20:04 +02001218 call assert_match('Breakpoint in "' .. funcname .. '" line 1', output)
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001219 call assert_equal('a', g:Xpath)
1220 breakdel *
Bram Moolenaar16c62322020-08-13 19:20:04 +02001221 exe "delfunc " .. funcname
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001222endfunc
1223
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001224" vim: shiftwidth=2 sts=2 expandtab