blob: 17d3616a0e0f3de717e427eaf433539a0cf03d0f [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
Yegappan Lakshmanan885de442022-04-23 10:51:14 +0100365" Test for expression breakpoint set using ":breakadd expr <expr>"
366func Test_Debugger_breakadd_expr()
367 let lines =<< trim END
368 let g:Xtest_var += 1
369 END
370 call writefile(lines, 'Xtest.vim')
371
372 " Start Vim in a terminal
373 let buf = RunVimInTerminal('Xtest.vim', {})
374 call RunDbgCmd(buf, ':let g:Xtest_var = 10')
375 call RunDbgCmd(buf, ':breakadd expr g:Xtest_var')
376 call RunDbgCmd(buf, ':source %')
377 let expected =<< eval trim END
378 Oldval = "10"
379 Newval = "11"
LemonBoy2eaef102022-05-06 13:14:50 +0100380 {fnamemodify('Xtest.vim', ':p')}
Yegappan Lakshmanan885de442022-04-23 10:51:14 +0100381 line 1: let g:Xtest_var += 1
382 END
383 call RunDbgCmd(buf, ':source %', expected)
384 call RunDbgCmd(buf, 'cont')
385 let expected =<< eval trim END
386 Oldval = "11"
387 Newval = "12"
LemonBoy2eaef102022-05-06 13:14:50 +0100388 {fnamemodify('Xtest.vim', ':p')}
Yegappan Lakshmanan885de442022-04-23 10:51:14 +0100389 line 1: let g:Xtest_var += 1
390 END
391 call RunDbgCmd(buf, ':source %', expected)
392
393 call StopVimInTerminal(buf)
394 call delete('Xtest.vim')
395endfunc
396
397def Test_Debugger_breakadd_vim9_expr()
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200398 var lines =<< trim END
399 vim9script
400 func g:EarlyFunc()
401 endfunc
402 breakadd expr DoesNotExist()
403 func g:LaterFunc()
404 endfunc
405 breakdel *
406 END
407 writefile(lines, 'Xtest.vim')
408
409 # Start Vim in a terminal
Bram Moolenaar62aec932022-01-29 21:45:34 +0000410 var buf = g:RunVimInTerminal('-S Xtest.vim', {wait_for_ruler: 0})
411 call g:TermWait(buf)
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200412
413 # Despite the failure the functions are defined
Bram Moolenaar62aec932022-01-29 21:45:34 +0000414 g:RunDbgCmd(buf, ':function g:EarlyFunc',
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200415 ['function EarlyFunc()', 'endfunction'], {match: 'pattern'})
Bram Moolenaar62aec932022-01-29 21:45:34 +0000416 g:RunDbgCmd(buf, ':function g:LaterFunc',
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200417 ['function LaterFunc()', 'endfunction'], {match: 'pattern'})
418
Bram Moolenaar62aec932022-01-29 21:45:34 +0000419 call g:StopVimInTerminal(buf)
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200420 call delete('Xtest.vim')
421enddef
422
Bram Moolenaar112bed02021-11-23 22:16:34 +0000423def Test_Debugger_break_at_return()
424 var lines =<< trim END
425 vim9script
426 def g:GetNum(): number
427 return 1
428 + 2
429 + 3
430 enddef
431 breakadd func GetNum
432 END
433 writefile(lines, 'Xtest.vim')
434
435 # Start Vim in a terminal
Bram Moolenaar62aec932022-01-29 21:45:34 +0000436 var buf = g:RunVimInTerminal('-S Xtest.vim', {wait_for_ruler: 0})
437 call g:TermWait(buf)
Bram Moolenaar112bed02021-11-23 22:16:34 +0000438
Bram Moolenaar62aec932022-01-29 21:45:34 +0000439 g:RunDbgCmd(buf, ':call GetNum()',
Bram Moolenaar112bed02021-11-23 22:16:34 +0000440 ['line 1: return 1 + 2 + 3'], {match: 'pattern'})
441
Bram Moolenaar62aec932022-01-29 21:45:34 +0000442 call g:StopVimInTerminal(buf)
Bram Moolenaar112bed02021-11-23 22:16:34 +0000443 call delete('Xtest.vim')
444enddef
445
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200446func Test_Backtrace_Through_Source()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200447 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200448 let file1 =<< trim END
449 func SourceAnotherFile()
450 source Xtest2.vim
451 endfunc
452
453 func CallAFunction()
454 call SourceAnotherFile()
455 call File2Function()
456 endfunc
457
458 func GlobalFunction()
459 call CallAFunction()
460 endfunc
461 END
462 call writefile(file1, 'Xtest1.vim')
463
464 let file2 =<< trim END
465 func DoAThing()
466 echo "DoAThing"
467 endfunc
468
469 func File2Function()
470 call DoAThing()
471 endfunc
472
473 call File2Function()
474 END
475 call writefile(file2, 'Xtest2.vim')
476
477 let buf = RunVimInTerminal('-S Xtest1.vim', {})
478
479 call RunDbgCmd(buf,
480 \ ':debug call GlobalFunction()',
481 \ ['cmd: call GlobalFunction()'])
482 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
483
484 call RunDbgCmd(buf, 'backtrace', ['>backtrace',
485 \ '->0 function GlobalFunction',
486 \ 'line 1: call CallAFunction()'])
487
488 call RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()'])
489 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
490
491 call RunDbgCmd(buf, 'backtrace', ['>backtrace',
492 \ ' 2 function GlobalFunction[1]',
493 \ ' 1 CallAFunction[1]',
494 \ '->0 SourceAnotherFile',
495 \ 'line 1: source Xtest2.vim'])
496
497 " Step into the 'source' command. Note that we print the full trace all the
498 " way though the source command.
499 call RunDbgCmd(buf, 'step', ['line 1: func DoAThing()'])
500 call RunDbgCmd(buf, 'backtrace', [
501 \ '>backtrace',
502 \ ' 3 function GlobalFunction[1]',
503 \ ' 2 CallAFunction[1]',
504 \ ' 1 SourceAnotherFile[1]',
505 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
506 \ 'line 1: func DoAThing()'])
507
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200508 call RunDbgCmd( buf, 'up' )
509 call RunDbgCmd( buf, 'backtrace', [
510 \ '>backtrace',
511 \ ' 3 function GlobalFunction[1]',
512 \ ' 2 CallAFunction[1]',
513 \ '->1 SourceAnotherFile[1]',
514 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
515 \ 'line 1: func DoAThing()' ] )
516
517 call RunDbgCmd( buf, 'up' )
518 call RunDbgCmd( buf, 'backtrace', [
519 \ '>backtrace',
520 \ ' 3 function GlobalFunction[1]',
521 \ '->2 CallAFunction[1]',
522 \ ' 1 SourceAnotherFile[1]',
523 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
524 \ 'line 1: func DoAThing()' ] )
525
526 call RunDbgCmd( buf, 'up' )
527 call RunDbgCmd( buf, 'backtrace', [
528 \ '>backtrace',
529 \ '->3 function GlobalFunction[1]',
530 \ ' 2 CallAFunction[1]',
531 \ ' 1 SourceAnotherFile[1]',
532 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
533 \ 'line 1: func DoAThing()' ] )
534
535 call RunDbgCmd( buf, 'up', [ 'frame at highest level: 3' ] )
536 call RunDbgCmd( buf, 'backtrace', [
537 \ '>backtrace',
538 \ '->3 function GlobalFunction[1]',
539 \ ' 2 CallAFunction[1]',
540 \ ' 1 SourceAnotherFile[1]',
541 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
542 \ 'line 1: func DoAThing()' ] )
543
544 call RunDbgCmd( buf, 'down' )
545 call RunDbgCmd( buf, 'backtrace', [
546 \ '>backtrace',
547 \ ' 3 function GlobalFunction[1]',
548 \ '->2 CallAFunction[1]',
549 \ ' 1 SourceAnotherFile[1]',
550 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
551 \ 'line 1: func DoAThing()' ] )
552
553 call RunDbgCmd( buf, 'down' )
554 call RunDbgCmd( buf, 'backtrace', [
555 \ '>backtrace',
556 \ ' 3 function GlobalFunction[1]',
557 \ ' 2 CallAFunction[1]',
558 \ '->1 SourceAnotherFile[1]',
559 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
560 \ 'line 1: func DoAThing()' ] )
561
562 call RunDbgCmd( buf, 'down' )
563 call RunDbgCmd( buf, 'backtrace', [
564 \ '>backtrace',
565 \ ' 3 function GlobalFunction[1]',
566 \ ' 2 CallAFunction[1]',
567 \ ' 1 SourceAnotherFile[1]',
568 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
569 \ 'line 1: func DoAThing()' ] )
570
571 call RunDbgCmd( buf, 'down', [ 'frame is zero' ] )
572
Dominique Pelle923dce22021-11-21 11:36:04 +0000573 " step until we have another meaningful trace
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200574 call RunDbgCmd(buf, 'step', ['line 5: func File2Function()'])
575 call RunDbgCmd(buf, 'step', ['line 9: call File2Function()'])
576 call RunDbgCmd(buf, 'backtrace', [
577 \ '>backtrace',
578 \ ' 3 function GlobalFunction[1]',
579 \ ' 2 CallAFunction[1]',
580 \ ' 1 SourceAnotherFile[1]',
581 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
582 \ 'line 9: call File2Function()'])
583
584 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
585 call RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"'])
586 call RunDbgCmd(buf, 'backtrace', [
587 \ '>backtrace',
588 \ ' 5 function GlobalFunction[1]',
589 \ ' 4 CallAFunction[1]',
590 \ ' 3 SourceAnotherFile[1]',
591 \ ' 2 script ' .. getcwd() .. '/Xtest2.vim[9]',
592 \ ' 1 function File2Function[1]',
593 \ '->0 DoAThing',
594 \ 'line 1: echo "DoAThing"'])
595
596 " Now, step (back to Xfile1.vim), and call the function _in_ Xfile2.vim
597 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
598 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
599 call RunDbgCmd(buf, 'step', ['line 10: End of sourced file'])
600 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
601 call RunDbgCmd(buf, 'step', ['line 2: call File2Function()'])
602 call RunDbgCmd(buf, 'backtrace', [
603 \ '>backtrace',
604 \ ' 1 function GlobalFunction[1]',
605 \ '->0 CallAFunction',
606 \ 'line 2: call File2Function()'])
607
608 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
609 call RunDbgCmd(buf, 'backtrace', [
610 \ '>backtrace',
611 \ ' 2 function GlobalFunction[1]',
612 \ ' 1 CallAFunction[2]',
613 \ '->0 File2Function',
614 \ 'line 1: call DoAThing()'])
615
616 call StopVimInTerminal(buf)
617 call delete('Xtest1.vim')
618 call delete('Xtest2.vim')
619endfunc
620
621func Test_Backtrace_Autocmd()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200622 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200623 let file1 =<< trim END
624 func SourceAnotherFile()
625 source Xtest2.vim
626 endfunc
627
628 func CallAFunction()
629 call SourceAnotherFile()
630 call File2Function()
631 endfunc
632
633 func GlobalFunction()
634 call CallAFunction()
635 endfunc
636
637 au User TestGlobalFunction :call GlobalFunction() | echo "Done"
638 END
639 call writefile(file1, 'Xtest1.vim')
640
641 let file2 =<< trim END
642 func DoAThing()
643 echo "DoAThing"
644 endfunc
645
646 func File2Function()
647 call DoAThing()
648 endfunc
649
650 call File2Function()
651 END
652 call writefile(file2, 'Xtest2.vim')
653
654 let buf = RunVimInTerminal('-S Xtest1.vim', {})
655
656 call RunDbgCmd(buf,
657 \ ':debug doautocmd User TestGlobalFunction',
658 \ ['cmd: doautocmd User TestGlobalFunction'])
659 call RunDbgCmd(buf, 'step', ['cmd: call GlobalFunction() | echo "Done"'])
660
Dominique Pelle923dce22021-11-21 11:36:04 +0000661 " At this point the only thing in the stack is the autocommand
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200662 call RunDbgCmd(buf, 'backtrace', [
663 \ '>backtrace',
664 \ '->0 User Autocommands for "TestGlobalFunction"',
665 \ 'cmd: call GlobalFunction() | echo "Done"'])
666
667 " And now we're back into the call stack
668 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
669 call RunDbgCmd(buf, 'backtrace', [
670 \ '>backtrace',
671 \ ' 1 User Autocommands for "TestGlobalFunction"',
672 \ '->0 function GlobalFunction',
673 \ 'line 1: call CallAFunction()'])
674
675 call RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()'])
676 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
677
678 call RunDbgCmd(buf, 'backtrace', [
679 \ '>backtrace',
680 \ ' 3 User Autocommands for "TestGlobalFunction"',
681 \ ' 2 function GlobalFunction[1]',
682 \ ' 1 CallAFunction[1]',
683 \ '->0 SourceAnotherFile',
684 \ 'line 1: source Xtest2.vim'])
685
686 " Step into the 'source' command. Note that we print the full trace all the
687 " way though the source command.
688 call RunDbgCmd(buf, 'step', ['line 1: func DoAThing()'])
689 call RunDbgCmd(buf, 'backtrace', [
690 \ '>backtrace',
691 \ ' 4 User Autocommands for "TestGlobalFunction"',
692 \ ' 3 function GlobalFunction[1]',
693 \ ' 2 CallAFunction[1]',
694 \ ' 1 SourceAnotherFile[1]',
695 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
696 \ 'line 1: func DoAThing()'])
697
Bram Moolenaarc63b72b2020-08-22 16:04:52 +0200698 call RunDbgCmd( buf, 'up' )
699 call RunDbgCmd( buf, 'backtrace', [
700 \ '>backtrace',
701 \ ' 4 User Autocommands for "TestGlobalFunction"',
702 \ ' 3 function GlobalFunction[1]',
703 \ ' 2 CallAFunction[1]',
704 \ '->1 SourceAnotherFile[1]',
705 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
706 \ 'line 1: func DoAThing()' ] )
707
708 call RunDbgCmd( buf, 'up' )
709 call RunDbgCmd( buf, 'backtrace', [
710 \ '>backtrace',
711 \ ' 4 User Autocommands for "TestGlobalFunction"',
712 \ ' 3 function GlobalFunction[1]',
713 \ '->2 CallAFunction[1]',
714 \ ' 1 SourceAnotherFile[1]',
715 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
716 \ 'line 1: func DoAThing()' ] )
717
718 call RunDbgCmd( buf, 'up' )
719 call RunDbgCmd( buf, 'backtrace', [
720 \ '>backtrace',
721 \ ' 4 User Autocommands for "TestGlobalFunction"',
722 \ '->3 function GlobalFunction[1]',
723 \ ' 2 CallAFunction[1]',
724 \ ' 1 SourceAnotherFile[1]',
725 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
726 \ 'line 1: func DoAThing()' ] )
727
728 call RunDbgCmd( buf, 'up' )
729 call RunDbgCmd( buf, 'backtrace', [
730 \ '>backtrace',
731 \ '->4 User Autocommands for "TestGlobalFunction"',
732 \ ' 3 function GlobalFunction[1]',
733 \ ' 2 CallAFunction[1]',
734 \ ' 1 SourceAnotherFile[1]',
735 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
736 \ 'line 1: func DoAThing()' ] )
737
738 call RunDbgCmd( buf, 'up', [ 'frame at highest level: 4' ] )
739 call RunDbgCmd( buf, 'backtrace', [
740 \ '>backtrace',
741 \ '->4 User Autocommands for "TestGlobalFunction"',
742 \ ' 3 function GlobalFunction[1]',
743 \ ' 2 CallAFunction[1]',
744 \ ' 1 SourceAnotherFile[1]',
745 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
746 \ 'line 1: func DoAThing()' ] )
747
748 call RunDbgCmd( buf, 'down' )
749 call RunDbgCmd( buf, 'backtrace', [
750 \ '>backtrace',
751 \ ' 4 User Autocommands for "TestGlobalFunction"',
752 \ '->3 function GlobalFunction[1]',
753 \ ' 2 CallAFunction[1]',
754 \ ' 1 SourceAnotherFile[1]',
755 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
756 \ 'line 1: func DoAThing()' ] )
757
758
759 call RunDbgCmd( buf, 'down' )
760 call RunDbgCmd( buf, 'backtrace', [
761 \ '>backtrace',
762 \ ' 4 User Autocommands for "TestGlobalFunction"',
763 \ ' 3 function GlobalFunction[1]',
764 \ '->2 CallAFunction[1]',
765 \ ' 1 SourceAnotherFile[1]',
766 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
767 \ 'line 1: func DoAThing()' ] )
768
769 call RunDbgCmd( buf, 'down' )
770 call RunDbgCmd( buf, 'backtrace', [
771 \ '>backtrace',
772 \ ' 4 User Autocommands for "TestGlobalFunction"',
773 \ ' 3 function GlobalFunction[1]',
774 \ ' 2 CallAFunction[1]',
775 \ '->1 SourceAnotherFile[1]',
776 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
777 \ 'line 1: func DoAThing()' ] )
778
779 call RunDbgCmd( buf, 'down' )
780 call RunDbgCmd( buf, 'backtrace', [
781 \ '>backtrace',
782 \ ' 4 User Autocommands for "TestGlobalFunction"',
783 \ ' 3 function GlobalFunction[1]',
784 \ ' 2 CallAFunction[1]',
785 \ ' 1 SourceAnotherFile[1]',
786 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
787 \ 'line 1: func DoAThing()' ] )
788
789 call RunDbgCmd( buf, 'down', [ 'frame is zero' ] )
790
Dominique Pelle923dce22021-11-21 11:36:04 +0000791 " step until we have another meaningful trace
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200792 call RunDbgCmd(buf, 'step', ['line 5: func File2Function()'])
793 call RunDbgCmd(buf, 'step', ['line 9: call File2Function()'])
794 call RunDbgCmd(buf, 'backtrace', [
795 \ '>backtrace',
796 \ ' 4 User Autocommands for "TestGlobalFunction"',
797 \ ' 3 function GlobalFunction[1]',
798 \ ' 2 CallAFunction[1]',
799 \ ' 1 SourceAnotherFile[1]',
800 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
801 \ 'line 9: call File2Function()'])
802
803 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
804 call RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"'])
805 call RunDbgCmd(buf, 'backtrace', [
806 \ '>backtrace',
807 \ ' 6 User Autocommands for "TestGlobalFunction"',
808 \ ' 5 function GlobalFunction[1]',
809 \ ' 4 CallAFunction[1]',
810 \ ' 3 SourceAnotherFile[1]',
811 \ ' 2 script ' .. getcwd() .. '/Xtest2.vim[9]',
812 \ ' 1 function File2Function[1]',
813 \ '->0 DoAThing',
814 \ 'line 1: echo "DoAThing"'])
815
816 " Now, step (back to Xfile1.vim), and call the function _in_ Xfile2.vim
817 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
818 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
819 call RunDbgCmd(buf, 'step', ['line 10: End of sourced file'])
820 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
821 call RunDbgCmd(buf, 'step', ['line 2: call File2Function()'])
822 call RunDbgCmd(buf, 'backtrace', [
823 \ '>backtrace',
824 \ ' 2 User Autocommands for "TestGlobalFunction"',
825 \ ' 1 function GlobalFunction[1]',
826 \ '->0 CallAFunction',
827 \ 'line 2: call File2Function()'])
828
829 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
830 call RunDbgCmd(buf, 'backtrace', [
831 \ '>backtrace',
832 \ ' 3 User Autocommands for "TestGlobalFunction"',
833 \ ' 2 function GlobalFunction[1]',
834 \ ' 1 CallAFunction[2]',
835 \ '->0 File2Function',
836 \ 'line 1: call DoAThing()'])
837
838
839 " Now unwind so that we get back to the original autocommand (and the second
840 " cmd echo "Done")
841 call RunDbgCmd(buf, 'finish', ['line 1: End of function'])
842 call RunDbgCmd(buf, 'backtrace', [
843 \ '>backtrace',
844 \ ' 3 User Autocommands for "TestGlobalFunction"',
845 \ ' 2 function GlobalFunction[1]',
846 \ ' 1 CallAFunction[2]',
847 \ '->0 File2Function',
848 \ 'line 1: End of function'])
849
850 call RunDbgCmd(buf, 'finish', ['line 2: End of function'])
851 call RunDbgCmd(buf, 'backtrace', [
852 \ '>backtrace',
853 \ ' 2 User Autocommands for "TestGlobalFunction"',
854 \ ' 1 function GlobalFunction[1]',
855 \ '->0 CallAFunction',
856 \ 'line 2: End of function'])
857
858 call RunDbgCmd(buf, 'finish', ['line 1: End of function'])
859 call RunDbgCmd(buf, 'backtrace', [
860 \ '>backtrace',
861 \ ' 1 User Autocommands for "TestGlobalFunction"',
862 \ '->0 function GlobalFunction',
863 \ 'line 1: End of function'])
864
865 call RunDbgCmd(buf, 'step', ['cmd: echo "Done"'])
866 call RunDbgCmd(buf, 'backtrace', [
867 \ '>backtrace',
868 \ '->0 User Autocommands for "TestGlobalFunction"',
869 \ 'cmd: echo "Done"'])
870
871 call StopVimInTerminal(buf)
872 call delete('Xtest1.vim')
873 call delete('Xtest2.vim')
874endfunc
875
876func Test_Backtrace_CmdLine()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200877 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200878 let file1 =<< trim END
879 func SourceAnotherFile()
880 source Xtest2.vim
881 endfunc
882
883 func CallAFunction()
884 call SourceAnotherFile()
885 call File2Function()
886 endfunc
887
888 func GlobalFunction()
889 call CallAFunction()
890 endfunc
891
892 au User TestGlobalFunction :call GlobalFunction() | echo "Done"
893 END
894 call writefile(file1, 'Xtest1.vim')
895
896 let file2 =<< trim END
897 func DoAThing()
898 echo "DoAThing"
899 endfunc
900
901 func File2Function()
902 call DoAThing()
903 endfunc
904
905 call File2Function()
906 END
907 call writefile(file2, 'Xtest2.vim')
908
909 let buf = RunVimInTerminal(
910 \ '-S Xtest1.vim -c "debug call GlobalFunction()"',
911 \ {'wait_for_ruler': 0})
912
Bram Moolenaar18dc3552020-11-22 14:24:00 +0100913 " Need to wait for the vim-in-terminal to be ready.
914 " With valgrind this can take quite long.
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200915 call CheckDbgOutput(buf, ['command line',
Bram Moolenaar18dc3552020-11-22 14:24:00 +0100916 \ 'cmd: call GlobalFunction()'], #{msec: 5000})
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200917
Dominique Pelle923dce22021-11-21 11:36:04 +0000918 " At this point the only thing in the stack is the cmdline
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200919 call RunDbgCmd(buf, 'backtrace', [
920 \ '>backtrace',
921 \ '->0 command line',
922 \ 'cmd: call GlobalFunction()'])
923
924 " And now we're back into the call stack
925 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
926 call RunDbgCmd(buf, 'backtrace', [
927 \ '>backtrace',
928 \ ' 1 command line',
929 \ '->0 function GlobalFunction',
930 \ 'line 1: call CallAFunction()'])
931
932 call StopVimInTerminal(buf)
933 call delete('Xtest1.vim')
934 call delete('Xtest2.vim')
935endfunc
936
937func Test_Backtrace_DefFunction()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200938 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200939 let file1 =<< trim END
940 vim9script
Bram Moolenaar84c62d52022-01-06 21:31:19 +0000941 import './Xtest2.vim' as imp
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200942
943 def SourceAnotherFile()
944 source Xtest2.vim
945 enddef
946
947 def CallAFunction()
948 SourceAnotherFile()
Bram Moolenaar84c62d52022-01-06 21:31:19 +0000949 imp.File2Function()
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200950 enddef
951
952 def g:GlobalFunction()
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +0200953 var some = "some var"
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200954 CallAFunction()
955 enddef
956
957 defcompile
958 END
959 call writefile(file1, 'Xtest1.vim')
960
961 let file2 =<< trim END
962 vim9script
963
964 def DoAThing(): number
Bram Moolenaar1bdae402020-10-03 14:14:56 +0200965 var a = 100 * 2
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200966 a += 3
967 return a
968 enddef
969
970 export def File2Function()
971 DoAThing()
972 enddef
973
974 defcompile
975 File2Function()
976 END
977 call writefile(file2, 'Xtest2.vim')
978
979 let buf = RunVimInTerminal('-S Xtest1.vim', {})
980
981 call RunDbgCmd(buf,
982 \ ':debug call GlobalFunction()',
983 \ ['cmd: call GlobalFunction()'])
984
Bram Moolenaar4cea5362021-06-16 22:24:40 +0200985 call RunDbgCmd(buf, 'step', ['line 1: var some = "some var"'])
986 call RunDbgCmd(buf, 'step', ['line 2: CallAFunction()'])
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +0200987 call RunDbgCmd(buf, 'echo some', ['some var'])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200988
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200989 call RunDbgCmd(buf, 'backtrace', [
990 \ '\V>backtrace',
Bram Moolenaare99d4222021-06-13 14:01:26 +0200991 \ '\V->0 function GlobalFunction',
Bram Moolenaar4cea5362021-06-16 22:24:40 +0200992 \ '\Vline 2: CallAFunction()',
Bram Moolenaare99d4222021-06-13 14:01:26 +0200993 \ ],
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200994 \ #{match: 'pattern'})
995
Bram Moolenaar4cea5362021-06-16 22:24:40 +0200996 call RunDbgCmd(buf, 'step', ['line 1: SourceAnotherFile()'])
997 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
Dominique Pelleaf4a61a2021-12-27 17:21:41 +0000998 " Repeated line, because we first are in the compiled function before the
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +0200999 " EXEC and then in do_cmdline() before the :source command.
Bram Moolenaare99d4222021-06-13 14:01:26 +02001000 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +02001001 call RunDbgCmd(buf, 'step', ['line 1: vim9script'])
1002 call RunDbgCmd(buf, 'step', ['line 3: def DoAThing(): number'])
1003 call RunDbgCmd(buf, 'step', ['line 9: export def File2Function()'])
1004 call RunDbgCmd(buf, 'step', ['line 9: def File2Function()'])
1005 call RunDbgCmd(buf, 'step', ['line 13: defcompile'])
1006 call RunDbgCmd(buf, 'step', ['line 14: File2Function()'])
1007 call RunDbgCmd(buf, 'backtrace', [
1008 \ '\V>backtrace',
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +02001009 \ '\V 3 function GlobalFunction[2]',
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +02001010 \ '\V 2 <SNR>\.\*_CallAFunction[1]',
1011 \ '\V 1 <SNR>\.\*_SourceAnotherFile[1]',
1012 \ '\V->0 script ' .. getcwd() .. '/Xtest2.vim',
1013 \ '\Vline 14: File2Function()'],
1014 \ #{match: 'pattern'})
1015
1016 " Don't step into compiled functions...
Bram Moolenaare99d4222021-06-13 14:01:26 +02001017 call RunDbgCmd(buf, 'next', ['line 15: End of sourced file'])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +02001018 call RunDbgCmd(buf, 'backtrace', [
1019 \ '\V>backtrace',
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +02001020 \ '\V 3 function GlobalFunction[2]',
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +02001021 \ '\V 2 <SNR>\.\*_CallAFunction[1]',
1022 \ '\V 1 <SNR>\.\*_SourceAnotherFile[1]',
1023 \ '\V->0 script ' .. getcwd() .. '/Xtest2.vim',
1024 \ '\Vline 15: End of sourced file'],
1025 \ #{match: 'pattern'})
1026
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +02001027 call StopVimInTerminal(buf)
1028 call delete('Xtest1.vim')
1029 call delete('Xtest2.vim')
1030endfunc
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001031
Bram Moolenaar26a44842021-09-02 18:49:06 +02001032func Test_DefFunction_expr()
1033 CheckCWD
1034 let file3 =<< trim END
1035 vim9script
1036 g:someVar = "foo"
1037 def g:ChangeVar()
1038 g:someVar = "bar"
1039 echo "changed"
1040 enddef
1041 defcompile
1042 END
1043 call writefile(file3, 'Xtest3.vim')
1044 let buf = RunVimInTerminal('-S Xtest3.vim', {})
1045
1046 call RunDbgCmd(buf, ':breakadd expr g:someVar')
1047 call RunDbgCmd(buf, ':call g:ChangeVar()', ['Oldval = "''foo''"', 'Newval = "''bar''"', 'function ChangeVar', 'line 2: echo "changed"'])
1048
1049 call StopVimInTerminal(buf)
1050 call delete('Xtest3.vim')
1051endfunc
1052
Bram Moolenaar17d868b2021-06-27 16:29:53 +02001053func Test_debug_def_and_legacy_function()
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001054 CheckCWD
1055 let file =<< trim END
1056 vim9script
1057 def g:SomeFunc()
1058 echo "here"
1059 echo "and"
1060 echo "there"
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001061 breakadd func 2 LocalFunc
1062 LocalFunc()
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001063 enddef
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001064
1065 def LocalFunc()
1066 echo "first"
1067 echo "second"
Bram Moolenaar8cec9272021-06-23 20:20:53 +02001068 breakadd func LegacyFunc
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001069 LegacyFunc()
1070 enddef
1071
1072 func LegacyFunc()
1073 echo "legone"
1074 echo "legtwo"
1075 endfunc
1076
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001077 breakadd func 2 g:SomeFunc
1078 END
1079 call writefile(file, 'XtestDebug.vim')
1080
1081 let buf = RunVimInTerminal('-S XtestDebug.vim', {})
1082
1083 call RunDbgCmd(buf,':call SomeFunc()', ['line 2: echo "and"'])
1084 call RunDbgCmd(buf,'next', ['line 3: echo "there"'])
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001085 call RunDbgCmd(buf,'next', ['line 4: breakadd func 2 LocalFunc'])
1086
1087 " continue, next breakpoint is in LocalFunc()
1088 call RunDbgCmd(buf,'cont', ['line 2: echo "second"'])
1089
1090 " continue, next breakpoint is in LegacyFunc()
1091 call RunDbgCmd(buf,'cont', ['line 1: echo "legone"'])
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001092
1093 call RunDbgCmd(buf, 'cont')
1094
1095 call StopVimInTerminal(buf)
Dominique Pelle6c72fd52021-07-04 12:30:06 +02001096 call delete('XtestDebug.vim')
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001097endfunc
1098
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001099func Test_debug_def_function()
1100 CheckCWD
1101 let file =<< trim END
1102 vim9script
1103 def g:Func()
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001104 var n: number
1105 def Closure(): number
1106 return n + 3
1107 enddef
1108 n += Closure()
1109 echo 'result: ' .. n
1110 enddef
1111
1112 def g:FuncWithArgs(text: string, nr: number, ...items: list<number>)
1113 echo text .. nr
1114 for it in items
1115 echo it
1116 endfor
1117 echo "done"
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001118 enddef
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001119
1120 def g:FuncWithDict()
1121 var d = {
1122 a: 1,
1123 b: 2,
1124 }
Bram Moolenaar59b50c32021-06-17 22:27:48 +02001125 # comment
1126 def Inner()
Bram Moolenaar31e21762021-07-10 20:43:59 +02001127 eval 1 + 2
Bram Moolenaar59b50c32021-06-17 22:27:48 +02001128 enddef
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001129 enddef
Bram Moolenaar303215d2021-07-07 20:10:43 +02001130
Bram Moolenaar8cec9272021-06-23 20:20:53 +02001131 def g:FuncComment()
1132 # comment
1133 echo "first"
1134 .. "one"
1135 # comment
1136 echo "second"
1137 enddef
Bram Moolenaar303215d2021-07-07 20:10:43 +02001138
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001139 def g:FuncForLoop()
Bram Moolenaar31e21762021-07-10 20:43:59 +02001140 eval 1 + 2
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001141 for i in [11, 22, 33]
Bram Moolenaar31e21762021-07-10 20:43:59 +02001142 eval i + 2
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001143 endfor
1144 echo "done"
1145 enddef
Bram Moolenaar303215d2021-07-07 20:10:43 +02001146
1147 def g:FuncWithSplitLine()
Bram Moolenaar31e21762021-07-10 20:43:59 +02001148 eval 1 + 2
1149 | eval 2 + 3
Bram Moolenaar303215d2021-07-07 20:10:43 +02001150 enddef
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001151 END
1152 call writefile(file, 'Xtest.vim')
1153
1154 let buf = RunVimInTerminal('-S Xtest.vim', {})
1155
1156 call RunDbgCmd(buf,
1157 \ ':debug call Func()',
1158 \ ['cmd: call Func()'])
1159 call RunDbgCmd(buf, 'next', ['result: 3'])
1160 call term_sendkeys(buf, "\r")
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001161 call RunDbgCmd(buf, 'cont')
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001162
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001163 call RunDbgCmd(buf,
1164 \ ':debug call FuncWithArgs("asdf", 42, 1, 2, 3)',
1165 \ ['cmd: call FuncWithArgs("asdf", 42, 1, 2, 3)'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001166 call RunDbgCmd(buf, 'step', ['line 1: echo text .. nr'])
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001167 call RunDbgCmd(buf, 'echo text', ['asdf'])
1168 call RunDbgCmd(buf, 'echo nr', ['42'])
1169 call RunDbgCmd(buf, 'echo items', ['[1, 2, 3]'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001170 call RunDbgCmd(buf, 'step', ['asdf42', 'function FuncWithArgs', 'line 2: for it in items'])
1171 call RunDbgCmd(buf, 'step', ['function FuncWithArgs', 'line 2: for it in items'])
1172 call RunDbgCmd(buf, 'echo it', ['0'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001173 call RunDbgCmd(buf, 'step', ['line 3: echo it'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001174 call RunDbgCmd(buf, 'echo it', ['1'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001175 call RunDbgCmd(buf, 'step', ['1', 'function FuncWithArgs', 'line 4: endfor'])
1176 call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001177 call RunDbgCmd(buf, 'echo it', ['1'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001178 call RunDbgCmd(buf, 'step', ['line 3: echo it'])
1179 call RunDbgCmd(buf, 'step', ['2', 'function FuncWithArgs', 'line 4: endfor'])
1180 call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001181 call RunDbgCmd(buf, 'echo it', ['2'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001182 call RunDbgCmd(buf, 'step', ['line 3: echo it'])
1183 call RunDbgCmd(buf, 'step', ['3', 'function FuncWithArgs', 'line 4: endfor'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001184 call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001185 call RunDbgCmd(buf, 'step', ['line 5: echo "done"'])
1186 call RunDbgCmd(buf, 'cont')
1187
1188 call RunDbgCmd(buf,
1189 \ ':debug call FuncWithDict()',
1190 \ ['cmd: call FuncWithDict()'])
1191 call RunDbgCmd(buf, 'step', ['line 1: var d = { a: 1, b: 2, }'])
Bram Moolenaar59b50c32021-06-17 22:27:48 +02001192 call RunDbgCmd(buf, 'step', ['line 6: def Inner()'])
Bram Moolenaar8cec9272021-06-23 20:20:53 +02001193 call RunDbgCmd(buf, 'cont')
1194
1195 call RunDbgCmd(buf, ':breakadd func 1 FuncComment')
1196 call RunDbgCmd(buf, ':call FuncComment()', ['function FuncComment', 'line 2: echo "first" .. "one"'])
1197 call RunDbgCmd(buf, ':breakadd func 3 FuncComment')
1198 call RunDbgCmd(buf, 'cont', ['function FuncComment', 'line 5: echo "second"'])
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001199 call RunDbgCmd(buf, 'cont')
1200
1201 call RunDbgCmd(buf, ':breakadd func 2 FuncForLoop')
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001202 call RunDbgCmd(buf, ':call FuncForLoop()', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]'])
1203 call RunDbgCmd(buf, 'step', ['line 2: for i in [11, 22, 33]'])
Bram Moolenaar31e21762021-07-10 20:43:59 +02001204 call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 3: eval i + 2'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001205 call RunDbgCmd(buf, 'echo i', ['11'])
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001206 call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 4: endfor'])
1207 call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001208 call RunDbgCmd(buf, 'next', ['line 3: eval i + 2'])
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001209 call RunDbgCmd(buf, 'echo i', ['22'])
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001210
Bram Moolenaar303215d2021-07-07 20:10:43 +02001211 call RunDbgCmd(buf, 'breakdel *')
1212 call RunDbgCmd(buf, 'cont')
1213
1214 call RunDbgCmd(buf, ':breakadd func FuncWithSplitLine')
Bram Moolenaar31e21762021-07-10 20:43:59 +02001215 call RunDbgCmd(buf, ':call FuncWithSplitLine()', ['function FuncWithSplitLine', 'line 1: eval 1 + 2 | eval 2 + 3'])
Bram Moolenaar303215d2021-07-07 20:10:43 +02001216
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001217 call RunDbgCmd(buf, 'cont')
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001218 call StopVimInTerminal(buf)
1219 call delete('Xtest.vim')
1220endfunc
1221
Bram Moolenaar17d868b2021-06-27 16:29:53 +02001222func Test_debug_def_function_with_lambda()
1223 CheckCWD
1224 let lines =<< trim END
1225 vim9script
1226 def g:Func()
1227 var s = 'a'
1228 ['b']->map((_, v) => s)
1229 echo "done"
1230 enddef
1231 breakadd func 2 g:Func
1232 END
1233 call writefile(lines, 'XtestLambda.vim')
1234
1235 let buf = RunVimInTerminal('-S XtestLambda.vim', {})
1236
1237 call RunDbgCmd(buf,
1238 \ ':call g:Func()',
1239 \ ['function Func', 'line 2: [''b'']->map((_, v) => s)'])
1240 call RunDbgCmd(buf,
1241 \ 'next',
1242 \ ['function Func', 'line 3: echo "done"'])
1243
1244 call RunDbgCmd(buf, 'cont')
1245 call StopVimInTerminal(buf)
1246 call delete('XtestLambda.vim')
1247endfunc
1248
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001249func Test_debug_backtrace_level()
1250 CheckCWD
1251 let lines =<< trim END
1252 let s:file1_var = 'file1'
1253 let g:global_var = 'global'
1254
1255 func s:File1Func( arg )
1256 let s:file1_var .= a:arg
1257 let local_var = s:file1_var .. ' test1'
1258 let g:global_var .= local_var
1259 source Xtest2.vim
1260 endfunc
1261
1262 call s:File1Func( 'arg1' )
1263 END
1264 call writefile(lines, 'Xtest1.vim')
1265
1266 let lines =<< trim END
1267 let s:file2_var = 'file2'
1268
1269 func s:File2Func( arg )
1270 let s:file2_var .= a:arg
1271 let local_var = s:file2_var .. ' test2'
1272 let g:global_var .= local_var
1273 endfunc
1274
1275 call s:File2Func( 'arg2' )
1276 END
1277 call writefile(lines, 'Xtest2.vim')
1278
1279 let file1 = getcwd() .. '/Xtest1.vim'
1280 let file2 = getcwd() .. '/Xtest2.vim'
1281
1282 " set a breakpoint and source file1.vim
1283 let buf = RunVimInTerminal(
1284 \ '-c "breakadd file 1 Xtest1.vim" -S Xtest1.vim',
Bram Moolenaar18dc3552020-11-22 14:24:00 +01001285 \ #{wait_for_ruler: 0})
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001286
1287 call CheckDbgOutput(buf, [
1288 \ 'Breakpoint in "' .. file1 .. '" line 1',
1289 \ 'Entering Debug mode. Type "cont" to continue.',
1290 \ 'command line..script ' .. file1,
1291 \ 'line 1: let s:file1_var = ''file1'''
Bram Moolenaar18dc3552020-11-22 14:24:00 +01001292 \ ], #{msec: 5000})
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001293
Bram Moolenaar8e7d6222020-12-18 19:49:56 +01001294 " step through the initial declarations
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001295 call RunDbgCmd(buf, 'step', [ 'line 2: let g:global_var = ''global''' ] )
1296 call RunDbgCmd(buf, 'step', [ 'line 4: func s:File1Func( arg )' ] )
1297 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1298 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1299 call RunDbgCmd(buf, 'echo global_var', [ 'global' ] )
1300
1301 " step in to the first function
1302 call RunDbgCmd(buf, 'step', [ 'line 11: call s:File1Func( ''arg1'' )' ] )
1303 call RunDbgCmd(buf, 'step', [ 'line 1: let s:file1_var .= a:arg' ] )
1304 call RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] )
1305 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1306 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1307 call RunDbgCmd(buf,
1308 \'echo global_var',
1309 \[ 'E121: Undefined variable: global_var' ] )
1310 call RunDbgCmd(buf,
1311 \'echo local_var',
1312 \[ 'E121: Undefined variable: local_var' ] )
1313 call RunDbgCmd(buf,
1314 \'echo l:local_var',
1315 \[ 'E121: Undefined variable: l:local_var' ] )
1316
1317 " backtrace up
1318 call RunDbgCmd(buf, 'backtrace', [
1319 \ '\V>backtrace',
1320 \ '\V 2 command line',
1321 \ '\V 1 script ' .. file1 .. '[11]',
1322 \ '\V->0 function <SNR>\.\*_File1Func',
1323 \ '\Vline 1: let s:file1_var .= a:arg',
1324 \ ],
1325 \ #{ match: 'pattern' } )
1326 call RunDbgCmd(buf, 'up', [ '>up' ] )
1327
1328 call RunDbgCmd(buf, 'backtrace', [
1329 \ '\V>backtrace',
1330 \ '\V 2 command line',
1331 \ '\V->1 script ' .. file1 .. '[11]',
1332 \ '\V 0 function <SNR>\.\*_File1Func',
1333 \ '\Vline 1: let s:file1_var .= a:arg',
1334 \ ],
1335 \ #{ match: 'pattern' } )
1336
1337 " Expression evaluation in the script frame (not the function frame)
Dominique Pelle923dce22021-11-21 11:36:04 +00001338 " FIXME: Unexpected in this scope (a: should not be visible)
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001339 call RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] )
1340 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1341 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1342 " FIXME: Unexpected in this scope (global should be found)
1343 call RunDbgCmd(buf,
1344 \'echo global_var',
1345 \[ 'E121: Undefined variable: global_var' ] )
1346 call RunDbgCmd(buf,
1347 \'echo local_var',
1348 \[ 'E121: Undefined variable: local_var' ] )
1349 call RunDbgCmd(buf,
1350 \'echo l:local_var',
1351 \[ 'E121: Undefined variable: l:local_var' ] )
1352
1353
1354 " step while backtraced jumps to the latest frame
1355 call RunDbgCmd(buf, 'step', [
1356 \ 'line 2: let local_var = s:file1_var .. '' test1''' ] )
1357 call RunDbgCmd(buf, 'backtrace', [
1358 \ '\V>backtrace',
1359 \ '\V 2 command line',
1360 \ '\V 1 script ' .. file1 .. '[11]',
1361 \ '\V->0 function <SNR>\.\*_File1Func',
1362 \ '\Vline 2: let local_var = s:file1_var .. '' test1''',
1363 \ ],
1364 \ #{ match: 'pattern' } )
1365
1366 call RunDbgCmd(buf, 'step', [ 'line 3: let g:global_var .= local_var' ] )
1367 call RunDbgCmd(buf, 'echo local_var', [ 'file1arg1 test1' ] )
1368 call RunDbgCmd(buf, 'echo l:local_var', [ 'file1arg1 test1' ] )
1369
1370 call RunDbgCmd(buf, 'step', [ 'line 4: source Xtest2.vim' ] )
1371 call RunDbgCmd(buf, 'step', [ 'line 1: let s:file2_var = ''file2''' ] )
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 1: let s:file2_var = ''file2''',
1379 \ ],
1380 \ #{ match: 'pattern' } )
1381
1382 " Expression evaluation in the script frame file2 (not the function frame)
1383 call RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] )
1384 call RunDbgCmd(buf,
1385 \ 'echo s:file1_var',
1386 \ [ 'E121: Undefined variable: s:file1_var' ] )
1387 call RunDbgCmd(buf, 'echo g:global_var', [ 'globalfile1arg1 test1' ] )
1388 call RunDbgCmd(buf, 'echo global_var', [ 'globalfile1arg1 test1' ] )
1389 call RunDbgCmd(buf,
1390 \'echo local_var',
1391 \[ 'E121: Undefined variable: local_var' ] )
1392 call RunDbgCmd(buf,
1393 \'echo l:local_var',
1394 \[ 'E121: Undefined variable: l:local_var' ] )
1395 call RunDbgCmd(buf,
1396 \ 'echo s:file2_var',
1397 \ [ 'E121: Undefined variable: s:file2_var' ] )
1398
1399 call RunDbgCmd(buf, 'step', [ 'line 3: func s:File2Func( arg )' ] )
1400 call RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] )
1401
1402 " Up the stack to the other script context
1403 call RunDbgCmd(buf, 'up')
1404 call RunDbgCmd(buf, 'backtrace', [
1405 \ '\V>backtrace',
1406 \ '\V 3 command line',
1407 \ '\V 2 script ' .. file1 .. '[11]',
1408 \ '\V->1 function <SNR>\.\*_File1Func[4]',
1409 \ '\V 0 script ' .. file2,
1410 \ '\Vline 3: func s:File2Func( arg )',
1411 \ ],
1412 \ #{ match: 'pattern' } )
1413 " FIXME: Unexpected. Should see the a: and l: dicts from File1Func
1414 call RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] )
1415 call RunDbgCmd(buf,
1416 \ 'echo l:local_var',
1417 \ [ 'E121: Undefined variable: l:local_var' ] )
1418
1419 call RunDbgCmd(buf, 'up')
1420 call RunDbgCmd(buf, 'backtrace', [
1421 \ '\V>backtrace',
1422 \ '\V 3 command line',
1423 \ '\V->2 script ' .. file1 .. '[11]',
1424 \ '\V 1 function <SNR>\.\*_File1Func[4]',
1425 \ '\V 0 script ' .. file2,
1426 \ '\Vline 3: func s:File2Func( arg )',
1427 \ ],
1428 \ #{ match: 'pattern' } )
1429
1430 " FIXME: Unexpected (wrong script vars are used)
1431 call RunDbgCmd(buf,
1432 \ 'echo s:file1_var',
1433 \ [ 'E121: Undefined variable: s:file1_var' ] )
1434 call RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] )
1435
Bram Moolenaare99d4222021-06-13 14:01:26 +02001436 call RunDbgCmd(buf, 'cont')
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001437 call StopVimInTerminal(buf)
1438 call delete('Xtest1.vim')
1439 call delete('Xtest2.vim')
1440endfunc
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001441
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001442" Test for setting a breakpoint on a :endif where the :if condition is false
1443" and then quit the script. This should generate an interrupt.
1444func Test_breakpt_endif_intr()
1445 func F()
1446 let g:Xpath ..= 'a'
1447 if v:false
1448 let g:Xpath ..= 'b'
1449 endif
1450 invalid_command
1451 endfunc
1452
1453 let g:Xpath = ''
1454 breakadd func 4 F
1455 try
1456 let caught_intr = 0
1457 debuggreedy
1458 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001459 catch /^Vim:Interrupt$/
1460 call assert_match('\.F, line 4', v:throwpoint)
1461 let caught_intr = 1
1462 endtry
1463 0debuggreedy
1464 call assert_equal(1, caught_intr)
1465 call assert_equal('a', g:Xpath)
1466 breakdel *
1467 delfunc F
1468endfunc
1469
1470" Test for setting a breakpoint on a :else where the :if condition is false
1471" and then quit the script. This should generate an interrupt.
1472func Test_breakpt_else_intr()
1473 func F()
1474 let g:Xpath ..= 'a'
1475 if v:false
1476 let g:Xpath ..= 'b'
1477 else
1478 invalid_command
1479 endif
1480 invalid_command
1481 endfunc
1482
1483 let g:Xpath = ''
1484 breakadd func 4 F
1485 try
1486 let caught_intr = 0
1487 debuggreedy
1488 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001489 catch /^Vim:Interrupt$/
1490 call assert_match('\.F, line 4', v:throwpoint)
1491 let caught_intr = 1
1492 endtry
1493 0debuggreedy
1494 call assert_equal(1, caught_intr)
1495 call assert_equal('a', g:Xpath)
1496 breakdel *
1497 delfunc F
1498endfunc
1499
1500" Test for setting a breakpoint on a :endwhile where the :while condition is
1501" false and then quit the script. This should generate an interrupt.
1502func Test_breakpt_endwhile_intr()
1503 func F()
1504 let g:Xpath ..= 'a'
1505 while v:false
1506 let g:Xpath ..= 'b'
1507 endwhile
1508 invalid_command
1509 endfunc
1510
1511 let g:Xpath = ''
1512 breakadd func 4 F
1513 try
1514 let caught_intr = 0
1515 debuggreedy
1516 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001517 catch /^Vim:Interrupt$/
1518 call assert_match('\.F, line 4', v:throwpoint)
1519 let caught_intr = 1
1520 endtry
1521 0debuggreedy
1522 call assert_equal(1, caught_intr)
1523 call assert_equal('a', g:Xpath)
1524 breakdel *
1525 delfunc F
1526endfunc
1527
Bram Moolenaar16c62322020-08-13 19:20:04 +02001528" Test for setting a breakpoint on a script local function
1529func Test_breakpt_scriptlocal_func()
1530 let g:Xpath = ''
1531 func s:G()
1532 let g:Xpath ..= 'a'
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001533 endfunc
1534
Bram Moolenaar16c62322020-08-13 19:20:04 +02001535 let funcname = expand("<SID>") .. "G"
1536 exe "breakadd func 1 " .. funcname
1537 debuggreedy
1538 redir => output
1539 call feedkeys(":call " .. funcname .. "()\<CR>c\<CR>", "xt")
1540 redir END
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001541 0debuggreedy
Bram Moolenaar16c62322020-08-13 19:20:04 +02001542 call assert_match('Breakpoint in "' .. funcname .. '" line 1', output)
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001543 call assert_equal('a', g:Xpath)
1544 breakdel *
Bram Moolenaar16c62322020-08-13 19:20:04 +02001545 exe "delfunc " .. funcname
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001546endfunc
1547
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001548" vim: shiftwidth=2 sts=2 expandtab