blob: 1856f8db4a00f94bbdf3695ecc708ac5829bf162 [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 Moolenaar18dc3552020-11-22 14:24:00 +010020" "options" argument can contain:
21" 'msec' - time to wait for a match
22" 'match' - "pattern" to use "lines" as pattern instead of text
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +020023func CheckDbgOutput(buf, lines, options = {})
24 " Verify the expected output
25 let lnum = 20 - len(a:lines)
Bram Moolenaar18dc3552020-11-22 14:24:00 +010026 let msec = get(a:options, 'msec', 1000)
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +020027 for l in a:lines
28 if get(a:options, 'match', 'equal') ==# 'pattern'
Bram Moolenaar18dc3552020-11-22 14:24:00 +010029 call WaitForAssert({-> assert_match(l, term_getline(a:buf, lnum))}, msec)
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +020030 else
Bram Moolenaar18dc3552020-11-22 14:24:00 +010031 call WaitForAssert({-> assert_equal(l, term_getline(a:buf, lnum))}, msec)
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +020032 endif
33 let lnum += 1
34 endfor
35endfunc
36
Bram Moolenaar113bf062019-04-17 16:54:05 +020037" Run a Vim debugger command
38" If the expected output argument is supplied, then check for it.
39func RunDbgCmd(buf, cmd, ...)
40 call term_sendkeys(a:buf, a:cmd . "\r")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +020041 call TermWait(a:buf)
Bram Moolenaar113bf062019-04-17 16:54:05 +020042
43 if a:0 != 0
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +020044 let options = #{match: 'equal'}
45 if a:0 > 1
46 call extend(options, a:2)
47 endif
48 call CheckDbgOutput(a:buf, a:1, options)
Bram Moolenaar113bf062019-04-17 16:54:05 +020049 endif
50endfunc
51
52" Debugger tests
53func Test_Debugger()
Bram Moolenaar113bf062019-04-17 16:54:05 +020054 " Create a Vim script with some functions
Bram Moolenaare7eb9272019-06-24 00:58:07 +020055 let lines =<< trim END
56 func Foo()
57 let var1 = 1
58 let var2 = Bar(var1) + 9
59 return var2
60 endfunc
61 func Bar(var)
62 let var1 = 2 + a:var
63 let var2 = Bazz(var1) + 4
64 return var2
65 endfunc
66 func Bazz(var)
67 try
68 let var1 = 3 + a:var
69 let var3 = "another var"
70 let var3 = "value2"
71 catch
72 let var4 = "exception"
73 endtry
74 return var1
75 endfunc
Bram Moolenaare406ff82022-03-10 20:47:43 +000076 def Vim9Func()
77 for cmd in ['confirm', 'xxxxxxx']
78 for _ in [1, 2]
79 echo cmd
80 endfor
81 endfor
82 enddef
Bram Moolenaare7eb9272019-06-24 00:58:07 +020083 END
84 call writefile(lines, 'Xtest.vim')
Bram Moolenaar113bf062019-04-17 16:54:05 +020085
86 " Start Vim in a terminal
87 let buf = RunVimInTerminal('-S Xtest.vim', {})
88
89 " Start the Vim debugger
Bram Moolenaarddd33082019-06-03 23:07:25 +020090 call RunDbgCmd(buf, ':debug echo Foo()', ['cmd: echo Foo()'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020091
92 " Create a few stack frames by stepping through functions
Bram Moolenaarddd33082019-06-03 23:07:25 +020093 call RunDbgCmd(buf, 'step', ['line 1: let var1 = 1'])
94 call RunDbgCmd(buf, 'step', ['line 2: let var2 = Bar(var1) + 9'])
95 call RunDbgCmd(buf, 'step', ['line 1: let var1 = 2 + a:var'])
96 call RunDbgCmd(buf, 'step', ['line 2: let var2 = Bazz(var1) + 4'])
97 call RunDbgCmd(buf, 'step', ['line 1: try'])
98 call RunDbgCmd(buf, 'step', ['line 2: let var1 = 3 + a:var'])
99 call RunDbgCmd(buf, 'step', ['line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200100
101 " check backtrace
102 call RunDbgCmd(buf, 'backtrace', [
103 \ ' 2 function Foo[2]',
104 \ ' 1 Bar[2]',
105 \ '->0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200106 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200107
108 " Check variables in different stack frames
109 call RunDbgCmd(buf, 'echo var1', ['6'])
110
111 call RunDbgCmd(buf, 'up')
112 call RunDbgCmd(buf, 'back', [
113 \ ' 2 function Foo[2]',
114 \ '->1 Bar[2]',
115 \ ' 0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200116 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200117 call RunDbgCmd(buf, 'echo var1', ['3'])
118
119 call RunDbgCmd(buf, 'u')
120 call RunDbgCmd(buf, 'bt', [
121 \ '->2 function Foo[2]',
122 \ ' 1 Bar[2]',
123 \ ' 0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200124 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200125 call RunDbgCmd(buf, 'echo var1', ['1'])
126
127 " Undefined variables
128 call RunDbgCmd(buf, 'step')
129 call RunDbgCmd(buf, 'frame 2')
130 call RunDbgCmd(buf, 'echo var3', [
131 \ 'Error detected while processing function Foo[2]..Bar[2]..Bazz:',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200132 \ 'line 4:',
Bram Moolenaar113bf062019-04-17 16:54:05 +0200133 \ 'E121: Undefined variable: var3'])
134
135 " var3 is defined in this level with some other value
136 call RunDbgCmd(buf, 'fr 0')
137 call RunDbgCmd(buf, 'echo var3', ['another var'])
138
139 call RunDbgCmd(buf, 'step')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200140 call RunDbgCmd(buf, '')
141 call RunDbgCmd(buf, '')
142 call RunDbgCmd(buf, '')
143 call RunDbgCmd(buf, '')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200144 call RunDbgCmd(buf, 'step', [
145 \ 'function Foo[2]..Bar',
146 \ 'line 3: End of function'])
147 call RunDbgCmd(buf, 'up')
148
149 " Undefined var2
150 call RunDbgCmd(buf, 'echo var2', [
151 \ 'Error detected while processing function Foo[2]..Bar:',
152 \ 'line 3:',
153 \ 'E121: Undefined variable: var2'])
154
155 " Var2 is defined with 10
156 call RunDbgCmd(buf, 'down')
157 call RunDbgCmd(buf, 'echo var2', ['10'])
158
159 " Backtrace movements
160 call RunDbgCmd(buf, 'b', [
161 \ ' 1 function Foo[2]',
162 \ '->0 Bar',
163 \ 'line 3: End of function'])
164
165 " next command cannot go down, we are on bottom
166 call RunDbgCmd(buf, 'down', ['frame is zero'])
167 call RunDbgCmd(buf, 'up')
168
169 " next command cannot go up, we are on top
170 call RunDbgCmd(buf, 'up', ['frame at highest level: 1'])
171 call RunDbgCmd(buf, 'where', [
172 \ '->1 function Foo[2]',
173 \ ' 0 Bar',
174 \ 'line 3: End of function'])
175
176 " fil is not frame or finish, it is file
177 call RunDbgCmd(buf, 'fil', ['"[No Name]" --No lines in buffer--'])
178
179 " relative backtrace movement
180 call RunDbgCmd(buf, 'fr -1')
181 call RunDbgCmd(buf, 'frame', [
182 \ ' 1 function Foo[2]',
183 \ '->0 Bar',
184 \ 'line 3: End of function'])
185
186 call RunDbgCmd(buf, 'fr +1')
187 call RunDbgCmd(buf, 'fram', [
188 \ '->1 function Foo[2]',
189 \ ' 0 Bar',
190 \ 'line 3: End of function'])
191
192 " go beyond limits does not crash
193 call RunDbgCmd(buf, 'fr 100', ['frame at highest level: 1'])
194 call RunDbgCmd(buf, 'fra', [
195 \ '->1 function Foo[2]',
196 \ ' 0 Bar',
197 \ 'line 3: End of function'])
198
199 call RunDbgCmd(buf, 'frame -40', ['frame is zero'])
200 call RunDbgCmd(buf, 'fram', [
201 \ ' 1 function Foo[2]',
202 \ '->0 Bar',
203 \ 'line 3: End of function'])
204
205 " final result 19
206 call RunDbgCmd(buf, 'cont', ['19'])
207
208 " breakpoints tests
209
210 " Start a debug session, so that reading the last line from the terminal
211 " works properly.
Bram Moolenaar18dc3552020-11-22 14:24:00 +0100212 call RunDbgCmd(buf, ':debug echo Foo()', ['cmd: echo Foo()'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200213
214 " No breakpoints
215 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
216
217 " Place some breakpoints
218 call RunDbgCmd(buf, 'breaka func Bar')
219 call RunDbgCmd(buf, 'breaklis', [' 1 func Bar line 1'])
220 call RunDbgCmd(buf, 'breakadd func 3 Bazz')
221 call RunDbgCmd(buf, 'breaklist', [' 1 func Bar line 1',
222 \ ' 2 func Bazz line 3'])
223
224 " Check whether the breakpoints are hit
225 call RunDbgCmd(buf, 'cont', [
226 \ 'Breakpoint in "Bar" line 1',
227 \ 'function Foo[2]..Bar',
228 \ 'line 1: let var1 = 2 + a:var'])
229 call RunDbgCmd(buf, 'cont', [
230 \ 'Breakpoint in "Bazz" line 3',
231 \ 'function Foo[2]..Bar[2]..Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200232 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200233
234 " Delete the breakpoints
235 call RunDbgCmd(buf, 'breakd 1')
236 call RunDbgCmd(buf, 'breakli', [' 2 func Bazz line 3'])
237 call RunDbgCmd(buf, 'breakdel func 3 Bazz')
238 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
239
240 call RunDbgCmd(buf, 'cont')
241
242 " Make sure the breakpoints are removed
243 call RunDbgCmd(buf, ':echo Foo()', ['19'])
244
245 " Delete a non-existing breakpoint
246 call RunDbgCmd(buf, ':breakdel 2', ['E161: Breakpoint not found: 2'])
247
248 " Expression breakpoint
249 call RunDbgCmd(buf, ':breakadd func 2 Bazz')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200250 call RunDbgCmd(buf, ':echo Bazz(1)', [
251 \ 'Entering Debug mode. Type "cont" to continue.',
252 \ 'function Bazz',
253 \ 'line 2: let var1 = 3 + a:var'])
254 call RunDbgCmd(buf, 'step')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200255 call RunDbgCmd(buf, 'step')
256 call RunDbgCmd(buf, 'breaka expr var3')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200257 call RunDbgCmd(buf, 'breakl', [' 3 func Bazz line 2',
258 \ ' 4 expr var3'])
259 call RunDbgCmd(buf, 'cont', ['Breakpoint in "Bazz" line 5',
Bram Moolenaar113bf062019-04-17 16:54:05 +0200260 \ 'Oldval = "''another var''"',
261 \ 'Newval = "''value2''"',
262 \ 'function Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200263 \ 'line 5: catch'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200264
265 call RunDbgCmd(buf, 'breakdel *')
266 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
267
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200268 " Check for error cases
269 call RunDbgCmd(buf, 'breakadd abcd', [
270 \ 'Error detected while processing function Bazz:',
271 \ 'line 5:',
272 \ 'E475: Invalid argument: abcd'])
273 call RunDbgCmd(buf, 'breakadd func', ['E475: Invalid argument: func'])
274 call RunDbgCmd(buf, 'breakadd func 2', ['E475: Invalid argument: func 2'])
275 call RunDbgCmd(buf, 'breaka func a()', ['E475: Invalid argument: func a()'])
276 call RunDbgCmd(buf, 'breakd abcd', ['E475: Invalid argument: abcd'])
277 call RunDbgCmd(buf, 'breakd func', ['E475: Invalid argument: func'])
278 call RunDbgCmd(buf, 'breakd func a()', ['E475: Invalid argument: func a()'])
279 call RunDbgCmd(buf, 'breakd func a', ['E161: Breakpoint not found: func a'])
280 call RunDbgCmd(buf, 'breakd expr', ['E475: Invalid argument: expr'])
Bram Moolenaar0325d392021-09-09 12:34:19 +0200281 call RunDbgCmd(buf, 'breakd expr x', ['E161: Breakpoint not found: expr x'])
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200282
Bram Moolenaar113bf062019-04-17 16:54:05 +0200283 " finish the current function
284 call RunDbgCmd(buf, 'finish', [
285 \ 'function Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200286 \ 'line 8: End of function'])
287 call RunDbgCmd(buf, 'cont')
288
289 " Test for :next
290 call RunDbgCmd(buf, ':debug echo Bar(1)')
291 call RunDbgCmd(buf, 'step')
292 call RunDbgCmd(buf, 'next')
293 call RunDbgCmd(buf, '', [
294 \ 'function Bar',
295 \ 'line 3: return var2'])
296 call RunDbgCmd(buf, 'c')
297
298 " Test for :interrupt
299 call RunDbgCmd(buf, ':debug echo Bazz(1)')
300 call RunDbgCmd(buf, 'step')
301 call RunDbgCmd(buf, 'step')
302 call RunDbgCmd(buf, 'interrupt', [
303 \ 'Exception thrown: Vim:Interrupt',
304 \ 'function Bazz',
305 \ 'line 5: catch'])
306 call RunDbgCmd(buf, 'c')
307
Bram Moolenaare406ff82022-03-10 20:47:43 +0000308 " Test showing local variable in :def function
309 call RunDbgCmd(buf, ':breakadd func 2 Vim9Func')
310 call RunDbgCmd(buf, ':call Vim9Func()', ['line 2: for _ in [1, 2]'])
311 call RunDbgCmd(buf, 'next', ['line 2: for _ in [1, 2]'])
312 call RunDbgCmd(buf, 'echo cmd', ['confirm'])
313 call RunDbgCmd(buf, 'breakdel *')
314 call RunDbgCmd(buf, 'cont')
315
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200316 " Test for :quit
317 call RunDbgCmd(buf, ':debug echo Foo()')
318 call RunDbgCmd(buf, 'breakdel *')
319 call RunDbgCmd(buf, 'breakadd func 3 Foo')
320 call RunDbgCmd(buf, 'breakadd func 3 Bazz')
321 call RunDbgCmd(buf, 'cont', [
322 \ 'Breakpoint in "Bazz" line 3',
323 \ 'function Foo[2]..Bar[2]..Bazz',
324 \ 'line 3: let var3 = "another var"'])
325 call RunDbgCmd(buf, 'quit', [
326 \ 'Breakpoint in "Foo" line 3',
327 \ 'function Foo',
328 \ 'line 3: return var2'])
329 call RunDbgCmd(buf, 'breakdel *')
330 call RunDbgCmd(buf, 'quit')
331 call RunDbgCmd(buf, 'enew! | only!')
332
333 call StopVimInTerminal(buf)
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200334endfunc
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200335
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200336func Test_Debugger_breakadd()
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200337 " Tests for :breakadd file and :breakadd here
338 " Breakpoints should be set before sourcing the file
339
Bram Moolenaare7eb9272019-06-24 00:58:07 +0200340 let lines =<< trim END
341 let var1 = 10
342 let var2 = 20
343 let var3 = 30
344 let var4 = 40
345 END
346 call writefile(lines, 'Xtest.vim')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200347
348 " Start Vim in a terminal
349 let buf = RunVimInTerminal('Xtest.vim', {})
350 call RunDbgCmd(buf, ':breakadd file 2 Xtest.vim')
351 call RunDbgCmd(buf, ':4 | breakadd here')
352 call RunDbgCmd(buf, ':source Xtest.vim', ['line 2: let var2 = 20'])
353 call RunDbgCmd(buf, 'cont', ['line 4: let var4 = 40'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200354 call RunDbgCmd(buf, 'cont')
355
356 call StopVimInTerminal(buf)
357
358 call delete('Xtest.vim')
Bram Moolenaar16c62322020-08-13 19:20:04 +0200359 %bw!
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200360
Bram Moolenaar16c62322020-08-13 19:20:04 +0200361 call assert_fails('breakadd here', 'E32:')
Bram Moolenaar531be472020-09-23 22:38:05 +0200362 call assert_fails('breakadd file Xtest.vim /\)/', 'E55:')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200363endfunc
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200364
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200365def Test_Debugger_breakadd_expr()
366 var lines =<< trim END
367 vim9script
368 func g:EarlyFunc()
369 endfunc
370 breakadd expr DoesNotExist()
371 func g:LaterFunc()
372 endfunc
373 breakdel *
374 END
375 writefile(lines, 'Xtest.vim')
376
377 # Start Vim in a terminal
Bram Moolenaar62aec932022-01-29 21:45:34 +0000378 var buf = g:RunVimInTerminal('-S Xtest.vim', {wait_for_ruler: 0})
379 call g:TermWait(buf)
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200380
381 # Despite the failure the functions are defined
Bram Moolenaar62aec932022-01-29 21:45:34 +0000382 g:RunDbgCmd(buf, ':function g:EarlyFunc',
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200383 ['function EarlyFunc()', 'endfunction'], {match: 'pattern'})
Bram Moolenaar62aec932022-01-29 21:45:34 +0000384 g:RunDbgCmd(buf, ':function g:LaterFunc',
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200385 ['function LaterFunc()', 'endfunction'], {match: 'pattern'})
386
Bram Moolenaar62aec932022-01-29 21:45:34 +0000387 call g:StopVimInTerminal(buf)
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200388 call delete('Xtest.vim')
389enddef
390
Bram Moolenaar112bed02021-11-23 22:16:34 +0000391def Test_Debugger_break_at_return()
392 var lines =<< trim END
393 vim9script
394 def g:GetNum(): number
395 return 1
396 + 2
397 + 3
398 enddef
399 breakadd func GetNum
400 END
401 writefile(lines, 'Xtest.vim')
402
403 # Start Vim in a terminal
Bram Moolenaar62aec932022-01-29 21:45:34 +0000404 var buf = g:RunVimInTerminal('-S Xtest.vim', {wait_for_ruler: 0})
405 call g:TermWait(buf)
Bram Moolenaar112bed02021-11-23 22:16:34 +0000406
Bram Moolenaar62aec932022-01-29 21:45:34 +0000407 g:RunDbgCmd(buf, ':call GetNum()',
Bram Moolenaar112bed02021-11-23 22:16:34 +0000408 ['line 1: return 1 + 2 + 3'], {match: 'pattern'})
409
Bram Moolenaar62aec932022-01-29 21:45:34 +0000410 call g:StopVimInTerminal(buf)
Bram Moolenaar112bed02021-11-23 22:16:34 +0000411 call delete('Xtest.vim')
412enddef
413
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200414func Test_Backtrace_Through_Source()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200415 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200416 let file1 =<< trim END
417 func SourceAnotherFile()
418 source Xtest2.vim
419 endfunc
420
421 func CallAFunction()
422 call SourceAnotherFile()
423 call File2Function()
424 endfunc
425
426 func GlobalFunction()
427 call CallAFunction()
428 endfunc
429 END
430 call writefile(file1, 'Xtest1.vim')
431
432 let file2 =<< trim END
433 func DoAThing()
434 echo "DoAThing"
435 endfunc
436
437 func File2Function()
438 call DoAThing()
439 endfunc
440
441 call File2Function()
442 END
443 call writefile(file2, 'Xtest2.vim')
444
445 let buf = RunVimInTerminal('-S Xtest1.vim', {})
446
447 call RunDbgCmd(buf,
448 \ ':debug call GlobalFunction()',
449 \ ['cmd: call GlobalFunction()'])
450 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
451
452 call RunDbgCmd(buf, 'backtrace', ['>backtrace',
453 \ '->0 function GlobalFunction',
454 \ 'line 1: call CallAFunction()'])
455
456 call RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()'])
457 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
458
459 call RunDbgCmd(buf, 'backtrace', ['>backtrace',
460 \ ' 2 function GlobalFunction[1]',
461 \ ' 1 CallAFunction[1]',
462 \ '->0 SourceAnotherFile',
463 \ 'line 1: source Xtest2.vim'])
464
465 " Step into the 'source' command. Note that we print the full trace all the
466 " way though the source command.
467 call RunDbgCmd(buf, 'step', ['line 1: func DoAThing()'])
468 call RunDbgCmd(buf, 'backtrace', [
469 \ '>backtrace',
470 \ ' 3 function GlobalFunction[1]',
471 \ ' 2 CallAFunction[1]',
472 \ ' 1 SourceAnotherFile[1]',
473 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
474 \ 'line 1: func DoAThing()'])
475
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200476 call RunDbgCmd( buf, 'up' )
477 call RunDbgCmd( buf, 'backtrace', [
478 \ '>backtrace',
479 \ ' 3 function GlobalFunction[1]',
480 \ ' 2 CallAFunction[1]',
481 \ '->1 SourceAnotherFile[1]',
482 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
483 \ 'line 1: func DoAThing()' ] )
484
485 call RunDbgCmd( buf, 'up' )
486 call RunDbgCmd( buf, 'backtrace', [
487 \ '>backtrace',
488 \ ' 3 function GlobalFunction[1]',
489 \ '->2 CallAFunction[1]',
490 \ ' 1 SourceAnotherFile[1]',
491 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
492 \ 'line 1: func DoAThing()' ] )
493
494 call RunDbgCmd( buf, 'up' )
495 call RunDbgCmd( buf, 'backtrace', [
496 \ '>backtrace',
497 \ '->3 function GlobalFunction[1]',
498 \ ' 2 CallAFunction[1]',
499 \ ' 1 SourceAnotherFile[1]',
500 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
501 \ 'line 1: func DoAThing()' ] )
502
503 call RunDbgCmd( buf, 'up', [ 'frame at highest level: 3' ] )
504 call RunDbgCmd( buf, 'backtrace', [
505 \ '>backtrace',
506 \ '->3 function GlobalFunction[1]',
507 \ ' 2 CallAFunction[1]',
508 \ ' 1 SourceAnotherFile[1]',
509 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
510 \ 'line 1: func DoAThing()' ] )
511
512 call RunDbgCmd( buf, 'down' )
513 call RunDbgCmd( buf, 'backtrace', [
514 \ '>backtrace',
515 \ ' 3 function GlobalFunction[1]',
516 \ '->2 CallAFunction[1]',
517 \ ' 1 SourceAnotherFile[1]',
518 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
519 \ 'line 1: func DoAThing()' ] )
520
521 call RunDbgCmd( buf, 'down' )
522 call RunDbgCmd( buf, 'backtrace', [
523 \ '>backtrace',
524 \ ' 3 function GlobalFunction[1]',
525 \ ' 2 CallAFunction[1]',
526 \ '->1 SourceAnotherFile[1]',
527 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
528 \ 'line 1: func DoAThing()' ] )
529
530 call RunDbgCmd( buf, 'down' )
531 call RunDbgCmd( buf, 'backtrace', [
532 \ '>backtrace',
533 \ ' 3 function GlobalFunction[1]',
534 \ ' 2 CallAFunction[1]',
535 \ ' 1 SourceAnotherFile[1]',
536 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
537 \ 'line 1: func DoAThing()' ] )
538
539 call RunDbgCmd( buf, 'down', [ 'frame is zero' ] )
540
Dominique Pelle923dce22021-11-21 11:36:04 +0000541 " step until we have another meaningful trace
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200542 call RunDbgCmd(buf, 'step', ['line 5: func File2Function()'])
543 call RunDbgCmd(buf, 'step', ['line 9: call File2Function()'])
544 call RunDbgCmd(buf, 'backtrace', [
545 \ '>backtrace',
546 \ ' 3 function GlobalFunction[1]',
547 \ ' 2 CallAFunction[1]',
548 \ ' 1 SourceAnotherFile[1]',
549 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
550 \ 'line 9: call File2Function()'])
551
552 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
553 call RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"'])
554 call RunDbgCmd(buf, 'backtrace', [
555 \ '>backtrace',
556 \ ' 5 function GlobalFunction[1]',
557 \ ' 4 CallAFunction[1]',
558 \ ' 3 SourceAnotherFile[1]',
559 \ ' 2 script ' .. getcwd() .. '/Xtest2.vim[9]',
560 \ ' 1 function File2Function[1]',
561 \ '->0 DoAThing',
562 \ 'line 1: echo "DoAThing"'])
563
564 " Now, step (back to Xfile1.vim), and call the function _in_ Xfile2.vim
565 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
566 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
567 call RunDbgCmd(buf, 'step', ['line 10: End of sourced file'])
568 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
569 call RunDbgCmd(buf, 'step', ['line 2: call File2Function()'])
570 call RunDbgCmd(buf, 'backtrace', [
571 \ '>backtrace',
572 \ ' 1 function GlobalFunction[1]',
573 \ '->0 CallAFunction',
574 \ 'line 2: call File2Function()'])
575
576 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
577 call RunDbgCmd(buf, 'backtrace', [
578 \ '>backtrace',
579 \ ' 2 function GlobalFunction[1]',
580 \ ' 1 CallAFunction[2]',
581 \ '->0 File2Function',
582 \ 'line 1: call DoAThing()'])
583
584 call StopVimInTerminal(buf)
585 call delete('Xtest1.vim')
586 call delete('Xtest2.vim')
587endfunc
588
589func Test_Backtrace_Autocmd()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200590 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200591 let file1 =<< trim END
592 func SourceAnotherFile()
593 source Xtest2.vim
594 endfunc
595
596 func CallAFunction()
597 call SourceAnotherFile()
598 call File2Function()
599 endfunc
600
601 func GlobalFunction()
602 call CallAFunction()
603 endfunc
604
605 au User TestGlobalFunction :call GlobalFunction() | echo "Done"
606 END
607 call writefile(file1, 'Xtest1.vim')
608
609 let file2 =<< trim END
610 func DoAThing()
611 echo "DoAThing"
612 endfunc
613
614 func File2Function()
615 call DoAThing()
616 endfunc
617
618 call File2Function()
619 END
620 call writefile(file2, 'Xtest2.vim')
621
622 let buf = RunVimInTerminal('-S Xtest1.vim', {})
623
624 call RunDbgCmd(buf,
625 \ ':debug doautocmd User TestGlobalFunction',
626 \ ['cmd: doautocmd User TestGlobalFunction'])
627 call RunDbgCmd(buf, 'step', ['cmd: call GlobalFunction() | echo "Done"'])
628
Dominique Pelle923dce22021-11-21 11:36:04 +0000629 " At this point the only thing in the stack is the autocommand
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200630 call RunDbgCmd(buf, 'backtrace', [
631 \ '>backtrace',
632 \ '->0 User Autocommands for "TestGlobalFunction"',
633 \ 'cmd: call GlobalFunction() | echo "Done"'])
634
635 " And now we're back into the call stack
636 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
637 call RunDbgCmd(buf, 'backtrace', [
638 \ '>backtrace',
639 \ ' 1 User Autocommands for "TestGlobalFunction"',
640 \ '->0 function GlobalFunction',
641 \ 'line 1: call CallAFunction()'])
642
643 call RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()'])
644 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
645
646 call RunDbgCmd(buf, 'backtrace', [
647 \ '>backtrace',
648 \ ' 3 User Autocommands for "TestGlobalFunction"',
649 \ ' 2 function GlobalFunction[1]',
650 \ ' 1 CallAFunction[1]',
651 \ '->0 SourceAnotherFile',
652 \ 'line 1: source Xtest2.vim'])
653
654 " Step into the 'source' command. Note that we print the full trace all the
655 " way though the source command.
656 call RunDbgCmd(buf, 'step', ['line 1: func DoAThing()'])
657 call RunDbgCmd(buf, 'backtrace', [
658 \ '>backtrace',
659 \ ' 4 User Autocommands for "TestGlobalFunction"',
660 \ ' 3 function GlobalFunction[1]',
661 \ ' 2 CallAFunction[1]',
662 \ ' 1 SourceAnotherFile[1]',
663 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
664 \ 'line 1: func DoAThing()'])
665
Bram Moolenaarc63b72b2020-08-22 16:04:52 +0200666 call RunDbgCmd( buf, 'up' )
667 call RunDbgCmd( buf, 'backtrace', [
668 \ '>backtrace',
669 \ ' 4 User Autocommands for "TestGlobalFunction"',
670 \ ' 3 function GlobalFunction[1]',
671 \ ' 2 CallAFunction[1]',
672 \ '->1 SourceAnotherFile[1]',
673 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
674 \ 'line 1: func DoAThing()' ] )
675
676 call RunDbgCmd( buf, 'up' )
677 call RunDbgCmd( buf, 'backtrace', [
678 \ '>backtrace',
679 \ ' 4 User Autocommands for "TestGlobalFunction"',
680 \ ' 3 function GlobalFunction[1]',
681 \ '->2 CallAFunction[1]',
682 \ ' 1 SourceAnotherFile[1]',
683 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
684 \ 'line 1: func DoAThing()' ] )
685
686 call RunDbgCmd( buf, 'up' )
687 call RunDbgCmd( buf, 'backtrace', [
688 \ '>backtrace',
689 \ ' 4 User Autocommands for "TestGlobalFunction"',
690 \ '->3 function GlobalFunction[1]',
691 \ ' 2 CallAFunction[1]',
692 \ ' 1 SourceAnotherFile[1]',
693 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
694 \ 'line 1: func DoAThing()' ] )
695
696 call RunDbgCmd( buf, 'up' )
697 call RunDbgCmd( buf, 'backtrace', [
698 \ '>backtrace',
699 \ '->4 User Autocommands for "TestGlobalFunction"',
700 \ ' 3 function GlobalFunction[1]',
701 \ ' 2 CallAFunction[1]',
702 \ ' 1 SourceAnotherFile[1]',
703 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
704 \ 'line 1: func DoAThing()' ] )
705
706 call RunDbgCmd( buf, 'up', [ 'frame at highest level: 4' ] )
707 call RunDbgCmd( buf, 'backtrace', [
708 \ '>backtrace',
709 \ '->4 User Autocommands for "TestGlobalFunction"',
710 \ ' 3 function GlobalFunction[1]',
711 \ ' 2 CallAFunction[1]',
712 \ ' 1 SourceAnotherFile[1]',
713 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
714 \ 'line 1: func DoAThing()' ] )
715
716 call RunDbgCmd( buf, 'down' )
717 call RunDbgCmd( buf, 'backtrace', [
718 \ '>backtrace',
719 \ ' 4 User Autocommands for "TestGlobalFunction"',
720 \ '->3 function GlobalFunction[1]',
721 \ ' 2 CallAFunction[1]',
722 \ ' 1 SourceAnotherFile[1]',
723 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
724 \ 'line 1: func DoAThing()' ] )
725
726
727 call RunDbgCmd( buf, 'down' )
728 call RunDbgCmd( buf, 'backtrace', [
729 \ '>backtrace',
730 \ ' 4 User Autocommands for "TestGlobalFunction"',
731 \ ' 3 function GlobalFunction[1]',
732 \ '->2 CallAFunction[1]',
733 \ ' 1 SourceAnotherFile[1]',
734 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
735 \ 'line 1: func DoAThing()' ] )
736
737 call RunDbgCmd( buf, 'down' )
738 call RunDbgCmd( buf, 'backtrace', [
739 \ '>backtrace',
740 \ ' 4 User Autocommands for "TestGlobalFunction"',
741 \ ' 3 function GlobalFunction[1]',
742 \ ' 2 CallAFunction[1]',
743 \ '->1 SourceAnotherFile[1]',
744 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
745 \ 'line 1: func DoAThing()' ] )
746
747 call RunDbgCmd( buf, 'down' )
748 call RunDbgCmd( buf, 'backtrace', [
749 \ '>backtrace',
750 \ ' 4 User Autocommands for "TestGlobalFunction"',
751 \ ' 3 function GlobalFunction[1]',
752 \ ' 2 CallAFunction[1]',
753 \ ' 1 SourceAnotherFile[1]',
754 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
755 \ 'line 1: func DoAThing()' ] )
756
757 call RunDbgCmd( buf, 'down', [ 'frame is zero' ] )
758
Dominique Pelle923dce22021-11-21 11:36:04 +0000759 " step until we have another meaningful trace
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200760 call RunDbgCmd(buf, 'step', ['line 5: func File2Function()'])
761 call RunDbgCmd(buf, 'step', ['line 9: call File2Function()'])
762 call RunDbgCmd(buf, 'backtrace', [
763 \ '>backtrace',
764 \ ' 4 User Autocommands for "TestGlobalFunction"',
765 \ ' 3 function GlobalFunction[1]',
766 \ ' 2 CallAFunction[1]',
767 \ ' 1 SourceAnotherFile[1]',
768 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
769 \ 'line 9: call File2Function()'])
770
771 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
772 call RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"'])
773 call RunDbgCmd(buf, 'backtrace', [
774 \ '>backtrace',
775 \ ' 6 User Autocommands for "TestGlobalFunction"',
776 \ ' 5 function GlobalFunction[1]',
777 \ ' 4 CallAFunction[1]',
778 \ ' 3 SourceAnotherFile[1]',
779 \ ' 2 script ' .. getcwd() .. '/Xtest2.vim[9]',
780 \ ' 1 function File2Function[1]',
781 \ '->0 DoAThing',
782 \ 'line 1: echo "DoAThing"'])
783
784 " Now, step (back to Xfile1.vim), and call the function _in_ Xfile2.vim
785 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
786 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
787 call RunDbgCmd(buf, 'step', ['line 10: End of sourced file'])
788 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
789 call RunDbgCmd(buf, 'step', ['line 2: call File2Function()'])
790 call RunDbgCmd(buf, 'backtrace', [
791 \ '>backtrace',
792 \ ' 2 User Autocommands for "TestGlobalFunction"',
793 \ ' 1 function GlobalFunction[1]',
794 \ '->0 CallAFunction',
795 \ 'line 2: call File2Function()'])
796
797 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
798 call RunDbgCmd(buf, 'backtrace', [
799 \ '>backtrace',
800 \ ' 3 User Autocommands for "TestGlobalFunction"',
801 \ ' 2 function GlobalFunction[1]',
802 \ ' 1 CallAFunction[2]',
803 \ '->0 File2Function',
804 \ 'line 1: call DoAThing()'])
805
806
807 " Now unwind so that we get back to the original autocommand (and the second
808 " cmd echo "Done")
809 call RunDbgCmd(buf, 'finish', ['line 1: End of function'])
810 call RunDbgCmd(buf, 'backtrace', [
811 \ '>backtrace',
812 \ ' 3 User Autocommands for "TestGlobalFunction"',
813 \ ' 2 function GlobalFunction[1]',
814 \ ' 1 CallAFunction[2]',
815 \ '->0 File2Function',
816 \ 'line 1: End of function'])
817
818 call RunDbgCmd(buf, 'finish', ['line 2: End of function'])
819 call RunDbgCmd(buf, 'backtrace', [
820 \ '>backtrace',
821 \ ' 2 User Autocommands for "TestGlobalFunction"',
822 \ ' 1 function GlobalFunction[1]',
823 \ '->0 CallAFunction',
824 \ 'line 2: End of function'])
825
826 call RunDbgCmd(buf, 'finish', ['line 1: End of function'])
827 call RunDbgCmd(buf, 'backtrace', [
828 \ '>backtrace',
829 \ ' 1 User Autocommands for "TestGlobalFunction"',
830 \ '->0 function GlobalFunction',
831 \ 'line 1: End of function'])
832
833 call RunDbgCmd(buf, 'step', ['cmd: echo "Done"'])
834 call RunDbgCmd(buf, 'backtrace', [
835 \ '>backtrace',
836 \ '->0 User Autocommands for "TestGlobalFunction"',
837 \ 'cmd: echo "Done"'])
838
839 call StopVimInTerminal(buf)
840 call delete('Xtest1.vim')
841 call delete('Xtest2.vim')
842endfunc
843
844func Test_Backtrace_CmdLine()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200845 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200846 let file1 =<< trim END
847 func SourceAnotherFile()
848 source Xtest2.vim
849 endfunc
850
851 func CallAFunction()
852 call SourceAnotherFile()
853 call File2Function()
854 endfunc
855
856 func GlobalFunction()
857 call CallAFunction()
858 endfunc
859
860 au User TestGlobalFunction :call GlobalFunction() | echo "Done"
861 END
862 call writefile(file1, 'Xtest1.vim')
863
864 let file2 =<< trim END
865 func DoAThing()
866 echo "DoAThing"
867 endfunc
868
869 func File2Function()
870 call DoAThing()
871 endfunc
872
873 call File2Function()
874 END
875 call writefile(file2, 'Xtest2.vim')
876
877 let buf = RunVimInTerminal(
878 \ '-S Xtest1.vim -c "debug call GlobalFunction()"',
879 \ {'wait_for_ruler': 0})
880
Bram Moolenaar18dc3552020-11-22 14:24:00 +0100881 " Need to wait for the vim-in-terminal to be ready.
882 " With valgrind this can take quite long.
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200883 call CheckDbgOutput(buf, ['command line',
Bram Moolenaar18dc3552020-11-22 14:24:00 +0100884 \ 'cmd: call GlobalFunction()'], #{msec: 5000})
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200885
Dominique Pelle923dce22021-11-21 11:36:04 +0000886 " At this point the only thing in the stack is the cmdline
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200887 call RunDbgCmd(buf, 'backtrace', [
888 \ '>backtrace',
889 \ '->0 command line',
890 \ 'cmd: call GlobalFunction()'])
891
892 " And now we're back into the call stack
893 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
894 call RunDbgCmd(buf, 'backtrace', [
895 \ '>backtrace',
896 \ ' 1 command line',
897 \ '->0 function GlobalFunction',
898 \ 'line 1: call CallAFunction()'])
899
900 call StopVimInTerminal(buf)
901 call delete('Xtest1.vim')
902 call delete('Xtest2.vim')
903endfunc
904
905func Test_Backtrace_DefFunction()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200906 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200907 let file1 =<< trim END
908 vim9script
Bram Moolenaar84c62d52022-01-06 21:31:19 +0000909 import './Xtest2.vim' as imp
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200910
911 def SourceAnotherFile()
912 source Xtest2.vim
913 enddef
914
915 def CallAFunction()
916 SourceAnotherFile()
Bram Moolenaar84c62d52022-01-06 21:31:19 +0000917 imp.File2Function()
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200918 enddef
919
920 def g:GlobalFunction()
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +0200921 var some = "some var"
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200922 CallAFunction()
923 enddef
924
925 defcompile
926 END
927 call writefile(file1, 'Xtest1.vim')
928
929 let file2 =<< trim END
930 vim9script
931
932 def DoAThing(): number
Bram Moolenaar1bdae402020-10-03 14:14:56 +0200933 var a = 100 * 2
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200934 a += 3
935 return a
936 enddef
937
938 export def File2Function()
939 DoAThing()
940 enddef
941
942 defcompile
943 File2Function()
944 END
945 call writefile(file2, 'Xtest2.vim')
946
947 let buf = RunVimInTerminal('-S Xtest1.vim', {})
948
949 call RunDbgCmd(buf,
950 \ ':debug call GlobalFunction()',
951 \ ['cmd: call GlobalFunction()'])
952
Bram Moolenaar4cea5362021-06-16 22:24:40 +0200953 call RunDbgCmd(buf, 'step', ['line 1: var some = "some var"'])
954 call RunDbgCmd(buf, 'step', ['line 2: CallAFunction()'])
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +0200955 call RunDbgCmd(buf, 'echo some', ['some var'])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200956
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200957 call RunDbgCmd(buf, 'backtrace', [
958 \ '\V>backtrace',
Bram Moolenaare99d4222021-06-13 14:01:26 +0200959 \ '\V->0 function GlobalFunction',
Bram Moolenaar4cea5362021-06-16 22:24:40 +0200960 \ '\Vline 2: CallAFunction()',
Bram Moolenaare99d4222021-06-13 14:01:26 +0200961 \ ],
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200962 \ #{match: 'pattern'})
963
Bram Moolenaar4cea5362021-06-16 22:24:40 +0200964 call RunDbgCmd(buf, 'step', ['line 1: SourceAnotherFile()'])
965 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
Dominique Pelleaf4a61a2021-12-27 17:21:41 +0000966 " Repeated line, because we first are in the compiled function before the
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +0200967 " EXEC and then in do_cmdline() before the :source command.
Bram Moolenaare99d4222021-06-13 14:01:26 +0200968 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200969 call RunDbgCmd(buf, 'step', ['line 1: vim9script'])
970 call RunDbgCmd(buf, 'step', ['line 3: def DoAThing(): number'])
971 call RunDbgCmd(buf, 'step', ['line 9: export def File2Function()'])
972 call RunDbgCmd(buf, 'step', ['line 9: def File2Function()'])
973 call RunDbgCmd(buf, 'step', ['line 13: defcompile'])
974 call RunDbgCmd(buf, 'step', ['line 14: File2Function()'])
975 call RunDbgCmd(buf, 'backtrace', [
976 \ '\V>backtrace',
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +0200977 \ '\V 3 function GlobalFunction[2]',
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200978 \ '\V 2 <SNR>\.\*_CallAFunction[1]',
979 \ '\V 1 <SNR>\.\*_SourceAnotherFile[1]',
980 \ '\V->0 script ' .. getcwd() .. '/Xtest2.vim',
981 \ '\Vline 14: File2Function()'],
982 \ #{match: 'pattern'})
983
984 " Don't step into compiled functions...
Bram Moolenaare99d4222021-06-13 14:01:26 +0200985 call RunDbgCmd(buf, 'next', ['line 15: End of sourced file'])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200986 call RunDbgCmd(buf, 'backtrace', [
987 \ '\V>backtrace',
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +0200988 \ '\V 3 function GlobalFunction[2]',
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200989 \ '\V 2 <SNR>\.\*_CallAFunction[1]',
990 \ '\V 1 <SNR>\.\*_SourceAnotherFile[1]',
991 \ '\V->0 script ' .. getcwd() .. '/Xtest2.vim',
992 \ '\Vline 15: End of sourced file'],
993 \ #{match: 'pattern'})
994
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200995 call StopVimInTerminal(buf)
996 call delete('Xtest1.vim')
997 call delete('Xtest2.vim')
998endfunc
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200999
Bram Moolenaar26a44842021-09-02 18:49:06 +02001000func Test_DefFunction_expr()
1001 CheckCWD
1002 let file3 =<< trim END
1003 vim9script
1004 g:someVar = "foo"
1005 def g:ChangeVar()
1006 g:someVar = "bar"
1007 echo "changed"
1008 enddef
1009 defcompile
1010 END
1011 call writefile(file3, 'Xtest3.vim')
1012 let buf = RunVimInTerminal('-S Xtest3.vim', {})
1013
1014 call RunDbgCmd(buf, ':breakadd expr g:someVar')
1015 call RunDbgCmd(buf, ':call g:ChangeVar()', ['Oldval = "''foo''"', 'Newval = "''bar''"', 'function ChangeVar', 'line 2: echo "changed"'])
1016
1017 call StopVimInTerminal(buf)
1018 call delete('Xtest3.vim')
1019endfunc
1020
Bram Moolenaar17d868b2021-06-27 16:29:53 +02001021func Test_debug_def_and_legacy_function()
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001022 CheckCWD
1023 let file =<< trim END
1024 vim9script
1025 def g:SomeFunc()
1026 echo "here"
1027 echo "and"
1028 echo "there"
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001029 breakadd func 2 LocalFunc
1030 LocalFunc()
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001031 enddef
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001032
1033 def LocalFunc()
1034 echo "first"
1035 echo "second"
Bram Moolenaar8cec9272021-06-23 20:20:53 +02001036 breakadd func LegacyFunc
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001037 LegacyFunc()
1038 enddef
1039
1040 func LegacyFunc()
1041 echo "legone"
1042 echo "legtwo"
1043 endfunc
1044
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001045 breakadd func 2 g:SomeFunc
1046 END
1047 call writefile(file, 'XtestDebug.vim')
1048
1049 let buf = RunVimInTerminal('-S XtestDebug.vim', {})
1050
1051 call RunDbgCmd(buf,':call SomeFunc()', ['line 2: echo "and"'])
1052 call RunDbgCmd(buf,'next', ['line 3: echo "there"'])
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001053 call RunDbgCmd(buf,'next', ['line 4: breakadd func 2 LocalFunc'])
1054
1055 " continue, next breakpoint is in LocalFunc()
1056 call RunDbgCmd(buf,'cont', ['line 2: echo "second"'])
1057
1058 " continue, next breakpoint is in LegacyFunc()
1059 call RunDbgCmd(buf,'cont', ['line 1: echo "legone"'])
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001060
1061 call RunDbgCmd(buf, 'cont')
1062
1063 call StopVimInTerminal(buf)
Dominique Pelle6c72fd52021-07-04 12:30:06 +02001064 call delete('XtestDebug.vim')
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001065endfunc
1066
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001067func Test_debug_def_function()
1068 CheckCWD
1069 let file =<< trim END
1070 vim9script
1071 def g:Func()
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001072 var n: number
1073 def Closure(): number
1074 return n + 3
1075 enddef
1076 n += Closure()
1077 echo 'result: ' .. n
1078 enddef
1079
1080 def g:FuncWithArgs(text: string, nr: number, ...items: list<number>)
1081 echo text .. nr
1082 for it in items
1083 echo it
1084 endfor
1085 echo "done"
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001086 enddef
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001087
1088 def g:FuncWithDict()
1089 var d = {
1090 a: 1,
1091 b: 2,
1092 }
Bram Moolenaar59b50c32021-06-17 22:27:48 +02001093 # comment
1094 def Inner()
Bram Moolenaar31e21762021-07-10 20:43:59 +02001095 eval 1 + 2
Bram Moolenaar59b50c32021-06-17 22:27:48 +02001096 enddef
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001097 enddef
Bram Moolenaar303215d2021-07-07 20:10:43 +02001098
Bram Moolenaar8cec9272021-06-23 20:20:53 +02001099 def g:FuncComment()
1100 # comment
1101 echo "first"
1102 .. "one"
1103 # comment
1104 echo "second"
1105 enddef
Bram Moolenaar303215d2021-07-07 20:10:43 +02001106
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001107 def g:FuncForLoop()
Bram Moolenaar31e21762021-07-10 20:43:59 +02001108 eval 1 + 2
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001109 for i in [11, 22, 33]
Bram Moolenaar31e21762021-07-10 20:43:59 +02001110 eval i + 2
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001111 endfor
1112 echo "done"
1113 enddef
Bram Moolenaar303215d2021-07-07 20:10:43 +02001114
1115 def g:FuncWithSplitLine()
Bram Moolenaar31e21762021-07-10 20:43:59 +02001116 eval 1 + 2
1117 | eval 2 + 3
Bram Moolenaar303215d2021-07-07 20:10:43 +02001118 enddef
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001119 END
1120 call writefile(file, 'Xtest.vim')
1121
1122 let buf = RunVimInTerminal('-S Xtest.vim', {})
1123
1124 call RunDbgCmd(buf,
1125 \ ':debug call Func()',
1126 \ ['cmd: call Func()'])
1127 call RunDbgCmd(buf, 'next', ['result: 3'])
1128 call term_sendkeys(buf, "\r")
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001129 call RunDbgCmd(buf, 'cont')
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001130
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001131 call RunDbgCmd(buf,
1132 \ ':debug call FuncWithArgs("asdf", 42, 1, 2, 3)',
1133 \ ['cmd: call FuncWithArgs("asdf", 42, 1, 2, 3)'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001134 call RunDbgCmd(buf, 'step', ['line 1: echo text .. nr'])
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001135 call RunDbgCmd(buf, 'echo text', ['asdf'])
1136 call RunDbgCmd(buf, 'echo nr', ['42'])
1137 call RunDbgCmd(buf, 'echo items', ['[1, 2, 3]'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001138 call RunDbgCmd(buf, 'step', ['asdf42', 'function FuncWithArgs', 'line 2: for it in items'])
1139 call RunDbgCmd(buf, 'step', ['function FuncWithArgs', 'line 2: for it in items'])
1140 call RunDbgCmd(buf, 'echo it', ['0'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001141 call RunDbgCmd(buf, 'step', ['line 3: echo it'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001142 call RunDbgCmd(buf, 'echo it', ['1'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001143 call RunDbgCmd(buf, 'step', ['1', 'function FuncWithArgs', 'line 4: endfor'])
1144 call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001145 call RunDbgCmd(buf, 'echo it', ['1'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001146 call RunDbgCmd(buf, 'step', ['line 3: echo it'])
1147 call RunDbgCmd(buf, 'step', ['2', 'function FuncWithArgs', 'line 4: endfor'])
1148 call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001149 call RunDbgCmd(buf, 'echo it', ['2'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001150 call RunDbgCmd(buf, 'step', ['line 3: echo it'])
1151 call RunDbgCmd(buf, 'step', ['3', 'function FuncWithArgs', 'line 4: endfor'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001152 call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001153 call RunDbgCmd(buf, 'step', ['line 5: echo "done"'])
1154 call RunDbgCmd(buf, 'cont')
1155
1156 call RunDbgCmd(buf,
1157 \ ':debug call FuncWithDict()',
1158 \ ['cmd: call FuncWithDict()'])
1159 call RunDbgCmd(buf, 'step', ['line 1: var d = { a: 1, b: 2, }'])
Bram Moolenaar59b50c32021-06-17 22:27:48 +02001160 call RunDbgCmd(buf, 'step', ['line 6: def Inner()'])
Bram Moolenaar8cec9272021-06-23 20:20:53 +02001161 call RunDbgCmd(buf, 'cont')
1162
1163 call RunDbgCmd(buf, ':breakadd func 1 FuncComment')
1164 call RunDbgCmd(buf, ':call FuncComment()', ['function FuncComment', 'line 2: echo "first" .. "one"'])
1165 call RunDbgCmd(buf, ':breakadd func 3 FuncComment')
1166 call RunDbgCmd(buf, 'cont', ['function FuncComment', 'line 5: echo "second"'])
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001167 call RunDbgCmd(buf, 'cont')
1168
1169 call RunDbgCmd(buf, ':breakadd func 2 FuncForLoop')
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001170 call RunDbgCmd(buf, ':call FuncForLoop()', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]'])
1171 call RunDbgCmd(buf, 'step', ['line 2: for i in [11, 22, 33]'])
Bram Moolenaar31e21762021-07-10 20:43:59 +02001172 call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 3: eval i + 2'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001173 call RunDbgCmd(buf, 'echo i', ['11'])
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001174 call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 4: endfor'])
1175 call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001176 call RunDbgCmd(buf, 'next', ['line 3: eval i + 2'])
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001177 call RunDbgCmd(buf, 'echo i', ['22'])
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001178
Bram Moolenaar303215d2021-07-07 20:10:43 +02001179 call RunDbgCmd(buf, 'breakdel *')
1180 call RunDbgCmd(buf, 'cont')
1181
1182 call RunDbgCmd(buf, ':breakadd func FuncWithSplitLine')
Bram Moolenaar31e21762021-07-10 20:43:59 +02001183 call RunDbgCmd(buf, ':call FuncWithSplitLine()', ['function FuncWithSplitLine', 'line 1: eval 1 + 2 | eval 2 + 3'])
Bram Moolenaar303215d2021-07-07 20:10:43 +02001184
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001185 call RunDbgCmd(buf, 'cont')
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001186 call StopVimInTerminal(buf)
1187 call delete('Xtest.vim')
1188endfunc
1189
Bram Moolenaar17d868b2021-06-27 16:29:53 +02001190func Test_debug_def_function_with_lambda()
1191 CheckCWD
1192 let lines =<< trim END
1193 vim9script
1194 def g:Func()
1195 var s = 'a'
1196 ['b']->map((_, v) => s)
1197 echo "done"
1198 enddef
1199 breakadd func 2 g:Func
1200 END
1201 call writefile(lines, 'XtestLambda.vim')
1202
1203 let buf = RunVimInTerminal('-S XtestLambda.vim', {})
1204
1205 call RunDbgCmd(buf,
1206 \ ':call g:Func()',
1207 \ ['function Func', 'line 2: [''b'']->map((_, v) => s)'])
1208 call RunDbgCmd(buf,
1209 \ 'next',
1210 \ ['function Func', 'line 3: echo "done"'])
1211
1212 call RunDbgCmd(buf, 'cont')
1213 call StopVimInTerminal(buf)
1214 call delete('XtestLambda.vim')
1215endfunc
1216
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001217func Test_debug_backtrace_level()
1218 CheckCWD
1219 let lines =<< trim END
1220 let s:file1_var = 'file1'
1221 let g:global_var = 'global'
1222
1223 func s:File1Func( arg )
1224 let s:file1_var .= a:arg
1225 let local_var = s:file1_var .. ' test1'
1226 let g:global_var .= local_var
1227 source Xtest2.vim
1228 endfunc
1229
1230 call s:File1Func( 'arg1' )
1231 END
1232 call writefile(lines, 'Xtest1.vim')
1233
1234 let lines =<< trim END
1235 let s:file2_var = 'file2'
1236
1237 func s:File2Func( arg )
1238 let s:file2_var .= a:arg
1239 let local_var = s:file2_var .. ' test2'
1240 let g:global_var .= local_var
1241 endfunc
1242
1243 call s:File2Func( 'arg2' )
1244 END
1245 call writefile(lines, 'Xtest2.vim')
1246
1247 let file1 = getcwd() .. '/Xtest1.vim'
1248 let file2 = getcwd() .. '/Xtest2.vim'
1249
1250 " set a breakpoint and source file1.vim
1251 let buf = RunVimInTerminal(
1252 \ '-c "breakadd file 1 Xtest1.vim" -S Xtest1.vim',
Bram Moolenaar18dc3552020-11-22 14:24:00 +01001253 \ #{wait_for_ruler: 0})
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001254
1255 call CheckDbgOutput(buf, [
1256 \ 'Breakpoint in "' .. file1 .. '" line 1',
1257 \ 'Entering Debug mode. Type "cont" to continue.',
1258 \ 'command line..script ' .. file1,
1259 \ 'line 1: let s:file1_var = ''file1'''
Bram Moolenaar18dc3552020-11-22 14:24:00 +01001260 \ ], #{msec: 5000})
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001261
Bram Moolenaar8e7d6222020-12-18 19:49:56 +01001262 " step through the initial declarations
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001263 call RunDbgCmd(buf, 'step', [ 'line 2: let g:global_var = ''global''' ] )
1264 call RunDbgCmd(buf, 'step', [ 'line 4: func s:File1Func( arg )' ] )
1265 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1266 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1267 call RunDbgCmd(buf, 'echo global_var', [ 'global' ] )
1268
1269 " step in to the first function
1270 call RunDbgCmd(buf, 'step', [ 'line 11: call s:File1Func( ''arg1'' )' ] )
1271 call RunDbgCmd(buf, 'step', [ 'line 1: let s:file1_var .= a:arg' ] )
1272 call RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] )
1273 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1274 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1275 call RunDbgCmd(buf,
1276 \'echo global_var',
1277 \[ 'E121: Undefined variable: global_var' ] )
1278 call RunDbgCmd(buf,
1279 \'echo local_var',
1280 \[ 'E121: Undefined variable: local_var' ] )
1281 call RunDbgCmd(buf,
1282 \'echo l:local_var',
1283 \[ 'E121: Undefined variable: l:local_var' ] )
1284
1285 " backtrace up
1286 call RunDbgCmd(buf, 'backtrace', [
1287 \ '\V>backtrace',
1288 \ '\V 2 command line',
1289 \ '\V 1 script ' .. file1 .. '[11]',
1290 \ '\V->0 function <SNR>\.\*_File1Func',
1291 \ '\Vline 1: let s:file1_var .= a:arg',
1292 \ ],
1293 \ #{ match: 'pattern' } )
1294 call RunDbgCmd(buf, 'up', [ '>up' ] )
1295
1296 call RunDbgCmd(buf, 'backtrace', [
1297 \ '\V>backtrace',
1298 \ '\V 2 command line',
1299 \ '\V->1 script ' .. file1 .. '[11]',
1300 \ '\V 0 function <SNR>\.\*_File1Func',
1301 \ '\Vline 1: let s:file1_var .= a:arg',
1302 \ ],
1303 \ #{ match: 'pattern' } )
1304
1305 " Expression evaluation in the script frame (not the function frame)
Dominique Pelle923dce22021-11-21 11:36:04 +00001306 " FIXME: Unexpected in this scope (a: should not be visible)
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001307 call RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] )
1308 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1309 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1310 " FIXME: Unexpected in this scope (global should be found)
1311 call RunDbgCmd(buf,
1312 \'echo global_var',
1313 \[ 'E121: Undefined variable: global_var' ] )
1314 call RunDbgCmd(buf,
1315 \'echo local_var',
1316 \[ 'E121: Undefined variable: local_var' ] )
1317 call RunDbgCmd(buf,
1318 \'echo l:local_var',
1319 \[ 'E121: Undefined variable: l:local_var' ] )
1320
1321
1322 " step while backtraced jumps to the latest frame
1323 call RunDbgCmd(buf, 'step', [
1324 \ 'line 2: let local_var = s:file1_var .. '' test1''' ] )
1325 call RunDbgCmd(buf, 'backtrace', [
1326 \ '\V>backtrace',
1327 \ '\V 2 command line',
1328 \ '\V 1 script ' .. file1 .. '[11]',
1329 \ '\V->0 function <SNR>\.\*_File1Func',
1330 \ '\Vline 2: let local_var = s:file1_var .. '' test1''',
1331 \ ],
1332 \ #{ match: 'pattern' } )
1333
1334 call RunDbgCmd(buf, 'step', [ 'line 3: let g:global_var .= local_var' ] )
1335 call RunDbgCmd(buf, 'echo local_var', [ 'file1arg1 test1' ] )
1336 call RunDbgCmd(buf, 'echo l:local_var', [ 'file1arg1 test1' ] )
1337
1338 call RunDbgCmd(buf, 'step', [ 'line 4: source Xtest2.vim' ] )
1339 call RunDbgCmd(buf, 'step', [ 'line 1: let s:file2_var = ''file2''' ] )
1340 call RunDbgCmd(buf, 'backtrace', [
1341 \ '\V>backtrace',
1342 \ '\V 3 command line',
1343 \ '\V 2 script ' .. file1 .. '[11]',
1344 \ '\V 1 function <SNR>\.\*_File1Func[4]',
1345 \ '\V->0 script ' .. file2,
1346 \ '\Vline 1: let s:file2_var = ''file2''',
1347 \ ],
1348 \ #{ match: 'pattern' } )
1349
1350 " Expression evaluation in the script frame file2 (not the function frame)
1351 call RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] )
1352 call RunDbgCmd(buf,
1353 \ 'echo s:file1_var',
1354 \ [ 'E121: Undefined variable: s:file1_var' ] )
1355 call RunDbgCmd(buf, 'echo g:global_var', [ 'globalfile1arg1 test1' ] )
1356 call RunDbgCmd(buf, 'echo global_var', [ 'globalfile1arg1 test1' ] )
1357 call RunDbgCmd(buf,
1358 \'echo local_var',
1359 \[ 'E121: Undefined variable: local_var' ] )
1360 call RunDbgCmd(buf,
1361 \'echo l:local_var',
1362 \[ 'E121: Undefined variable: l:local_var' ] )
1363 call RunDbgCmd(buf,
1364 \ 'echo s:file2_var',
1365 \ [ 'E121: Undefined variable: s:file2_var' ] )
1366
1367 call RunDbgCmd(buf, 'step', [ 'line 3: func s:File2Func( arg )' ] )
1368 call RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] )
1369
1370 " Up the stack to the other script context
1371 call RunDbgCmd(buf, 'up')
1372 call RunDbgCmd(buf, 'backtrace', [
1373 \ '\V>backtrace',
1374 \ '\V 3 command line',
1375 \ '\V 2 script ' .. file1 .. '[11]',
1376 \ '\V->1 function <SNR>\.\*_File1Func[4]',
1377 \ '\V 0 script ' .. file2,
1378 \ '\Vline 3: func s:File2Func( arg )',
1379 \ ],
1380 \ #{ match: 'pattern' } )
1381 " FIXME: Unexpected. Should see the a: and l: dicts from File1Func
1382 call RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] )
1383 call RunDbgCmd(buf,
1384 \ 'echo l:local_var',
1385 \ [ 'E121: Undefined variable: l:local_var' ] )
1386
1387 call RunDbgCmd(buf, 'up')
1388 call RunDbgCmd(buf, 'backtrace', [
1389 \ '\V>backtrace',
1390 \ '\V 3 command line',
1391 \ '\V->2 script ' .. file1 .. '[11]',
1392 \ '\V 1 function <SNR>\.\*_File1Func[4]',
1393 \ '\V 0 script ' .. file2,
1394 \ '\Vline 3: func s:File2Func( arg )',
1395 \ ],
1396 \ #{ match: 'pattern' } )
1397
1398 " FIXME: Unexpected (wrong script vars are used)
1399 call RunDbgCmd(buf,
1400 \ 'echo s:file1_var',
1401 \ [ 'E121: Undefined variable: s:file1_var' ] )
1402 call RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] )
1403
Bram Moolenaare99d4222021-06-13 14:01:26 +02001404 call RunDbgCmd(buf, 'cont')
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001405 call StopVimInTerminal(buf)
1406 call delete('Xtest1.vim')
1407 call delete('Xtest2.vim')
1408endfunc
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001409
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001410" Test for setting a breakpoint on a :endif where the :if condition is false
1411" and then quit the script. This should generate an interrupt.
1412func Test_breakpt_endif_intr()
1413 func F()
1414 let g:Xpath ..= 'a'
1415 if v:false
1416 let g:Xpath ..= 'b'
1417 endif
1418 invalid_command
1419 endfunc
1420
1421 let g:Xpath = ''
1422 breakadd func 4 F
1423 try
1424 let caught_intr = 0
1425 debuggreedy
1426 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001427 catch /^Vim:Interrupt$/
1428 call assert_match('\.F, line 4', v:throwpoint)
1429 let caught_intr = 1
1430 endtry
1431 0debuggreedy
1432 call assert_equal(1, caught_intr)
1433 call assert_equal('a', g:Xpath)
1434 breakdel *
1435 delfunc F
1436endfunc
1437
1438" Test for setting a breakpoint on a :else where the :if condition is false
1439" and then quit the script. This should generate an interrupt.
1440func Test_breakpt_else_intr()
1441 func F()
1442 let g:Xpath ..= 'a'
1443 if v:false
1444 let g:Xpath ..= 'b'
1445 else
1446 invalid_command
1447 endif
1448 invalid_command
1449 endfunc
1450
1451 let g:Xpath = ''
1452 breakadd func 4 F
1453 try
1454 let caught_intr = 0
1455 debuggreedy
1456 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001457 catch /^Vim:Interrupt$/
1458 call assert_match('\.F, line 4', v:throwpoint)
1459 let caught_intr = 1
1460 endtry
1461 0debuggreedy
1462 call assert_equal(1, caught_intr)
1463 call assert_equal('a', g:Xpath)
1464 breakdel *
1465 delfunc F
1466endfunc
1467
1468" Test for setting a breakpoint on a :endwhile where the :while condition is
1469" false and then quit the script. This should generate an interrupt.
1470func Test_breakpt_endwhile_intr()
1471 func F()
1472 let g:Xpath ..= 'a'
1473 while v:false
1474 let g:Xpath ..= 'b'
1475 endwhile
1476 invalid_command
1477 endfunc
1478
1479 let g:Xpath = ''
1480 breakadd func 4 F
1481 try
1482 let caught_intr = 0
1483 debuggreedy
1484 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001485 catch /^Vim:Interrupt$/
1486 call assert_match('\.F, line 4', v:throwpoint)
1487 let caught_intr = 1
1488 endtry
1489 0debuggreedy
1490 call assert_equal(1, caught_intr)
1491 call assert_equal('a', g:Xpath)
1492 breakdel *
1493 delfunc F
1494endfunc
1495
Bram Moolenaar16c62322020-08-13 19:20:04 +02001496" Test for setting a breakpoint on a script local function
1497func Test_breakpt_scriptlocal_func()
1498 let g:Xpath = ''
1499 func s:G()
1500 let g:Xpath ..= 'a'
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001501 endfunc
1502
Bram Moolenaar16c62322020-08-13 19:20:04 +02001503 let funcname = expand("<SID>") .. "G"
1504 exe "breakadd func 1 " .. funcname
1505 debuggreedy
1506 redir => output
1507 call feedkeys(":call " .. funcname .. "()\<CR>c\<CR>", "xt")
1508 redir END
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001509 0debuggreedy
Bram Moolenaar16c62322020-08-13 19:20:04 +02001510 call assert_match('Breakpoint in "' .. funcname .. '" line 1', output)
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001511 call assert_equal('a', g:Xpath)
1512 breakdel *
Bram Moolenaar16c62322020-08-13 19:20:04 +02001513 exe "delfunc " .. funcname
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001514endfunc
1515
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001516" vim: shiftwidth=2 sts=2 expandtab