blob: e873b772529538f7fff6f380f92d35ad261adfb5 [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()
James McCoydb7a88d2022-08-03 16:13:27 +0100367 CheckCWD
368
Yegappan Lakshmanan885de442022-04-23 10:51:14 +0100369 let lines =<< trim END
370 let g:Xtest_var += 1
371 END
372 call writefile(lines, 'Xtest.vim')
373
374 " Start Vim in a terminal
375 let buf = RunVimInTerminal('Xtest.vim', {})
376 call RunDbgCmd(buf, ':let g:Xtest_var = 10')
377 call RunDbgCmd(buf, ':breakadd expr g:Xtest_var')
378 call RunDbgCmd(buf, ':source %')
379 let expected =<< eval trim END
380 Oldval = "10"
381 Newval = "11"
LemonBoy2eaef102022-05-06 13:14:50 +0100382 {fnamemodify('Xtest.vim', ':p')}
Yegappan Lakshmanan885de442022-04-23 10:51:14 +0100383 line 1: let g:Xtest_var += 1
384 END
385 call RunDbgCmd(buf, ':source %', expected)
386 call RunDbgCmd(buf, 'cont')
387 let expected =<< eval trim END
388 Oldval = "11"
389 Newval = "12"
LemonBoy2eaef102022-05-06 13:14:50 +0100390 {fnamemodify('Xtest.vim', ':p')}
Yegappan Lakshmanan885de442022-04-23 10:51:14 +0100391 line 1: let g:Xtest_var += 1
392 END
393 call RunDbgCmd(buf, ':source %', expected)
394
395 call StopVimInTerminal(buf)
396 call delete('Xtest.vim')
397endfunc
398
399def Test_Debugger_breakadd_vim9_expr()
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200400 var lines =<< trim END
401 vim9script
402 func g:EarlyFunc()
403 endfunc
404 breakadd expr DoesNotExist()
405 func g:LaterFunc()
406 endfunc
407 breakdel *
408 END
409 writefile(lines, 'Xtest.vim')
410
411 # Start Vim in a terminal
Bram Moolenaar62aec932022-01-29 21:45:34 +0000412 var buf = g:RunVimInTerminal('-S Xtest.vim', {wait_for_ruler: 0})
Bram Moolenaare366ed42022-06-19 20:13:56 +0100413 call g:TermWait(buf, g:RunningWithValgrind() ? 1000 : 50)
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200414
415 # Despite the failure the functions are defined
Bram Moolenaar62aec932022-01-29 21:45:34 +0000416 g:RunDbgCmd(buf, ':function g:EarlyFunc',
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200417 ['function EarlyFunc()', 'endfunction'], {match: 'pattern'})
Bram Moolenaar62aec932022-01-29 21:45:34 +0000418 g:RunDbgCmd(buf, ':function g:LaterFunc',
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200419 ['function LaterFunc()', 'endfunction'], {match: 'pattern'})
420
Bram Moolenaar62aec932022-01-29 21:45:34 +0000421 call g:StopVimInTerminal(buf)
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200422 call delete('Xtest.vim')
423enddef
424
Bram Moolenaar112bed02021-11-23 22:16:34 +0000425def Test_Debugger_break_at_return()
426 var lines =<< trim END
427 vim9script
428 def g:GetNum(): number
429 return 1
430 + 2
431 + 3
432 enddef
433 breakadd func GetNum
434 END
435 writefile(lines, 'Xtest.vim')
436
437 # Start Vim in a terminal
Bram Moolenaar62aec932022-01-29 21:45:34 +0000438 var buf = g:RunVimInTerminal('-S Xtest.vim', {wait_for_ruler: 0})
Bram Moolenaare366ed42022-06-19 20:13:56 +0100439 call g:TermWait(buf, g:RunningWithValgrind() ? 1000 : 50)
Bram Moolenaar112bed02021-11-23 22:16:34 +0000440
Bram Moolenaar62aec932022-01-29 21:45:34 +0000441 g:RunDbgCmd(buf, ':call GetNum()',
Bram Moolenaar112bed02021-11-23 22:16:34 +0000442 ['line 1: return 1 + 2 + 3'], {match: 'pattern'})
443
Bram Moolenaar62aec932022-01-29 21:45:34 +0000444 call g:StopVimInTerminal(buf)
Bram Moolenaar112bed02021-11-23 22:16:34 +0000445 call delete('Xtest.vim')
446enddef
447
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200448func Test_Backtrace_Through_Source()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200449 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200450 let file1 =<< trim END
451 func SourceAnotherFile()
452 source Xtest2.vim
453 endfunc
454
455 func CallAFunction()
456 call SourceAnotherFile()
457 call File2Function()
458 endfunc
459
460 func GlobalFunction()
461 call CallAFunction()
462 endfunc
463 END
464 call writefile(file1, 'Xtest1.vim')
465
466 let file2 =<< trim END
467 func DoAThing()
468 echo "DoAThing"
469 endfunc
470
471 func File2Function()
472 call DoAThing()
473 endfunc
474
475 call File2Function()
476 END
477 call writefile(file2, 'Xtest2.vim')
478
479 let buf = RunVimInTerminal('-S Xtest1.vim', {})
480
481 call RunDbgCmd(buf,
482 \ ':debug call GlobalFunction()',
483 \ ['cmd: call GlobalFunction()'])
484 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
485
486 call RunDbgCmd(buf, 'backtrace', ['>backtrace',
487 \ '->0 function GlobalFunction',
488 \ 'line 1: call CallAFunction()'])
489
490 call RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()'])
491 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
492
493 call RunDbgCmd(buf, 'backtrace', ['>backtrace',
494 \ ' 2 function GlobalFunction[1]',
495 \ ' 1 CallAFunction[1]',
496 \ '->0 SourceAnotherFile',
497 \ 'line 1: source Xtest2.vim'])
498
499 " Step into the 'source' command. Note that we print the full trace all the
500 " way though the source command.
501 call RunDbgCmd(buf, 'step', ['line 1: func DoAThing()'])
502 call RunDbgCmd(buf, 'backtrace', [
503 \ '>backtrace',
504 \ ' 3 function GlobalFunction[1]',
505 \ ' 2 CallAFunction[1]',
506 \ ' 1 SourceAnotherFile[1]',
507 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
508 \ 'line 1: func DoAThing()'])
509
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200510 call RunDbgCmd( buf, 'up' )
511 call RunDbgCmd( buf, 'backtrace', [
512 \ '>backtrace',
513 \ ' 3 function GlobalFunction[1]',
514 \ ' 2 CallAFunction[1]',
515 \ '->1 SourceAnotherFile[1]',
516 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
517 \ 'line 1: func DoAThing()' ] )
518
519 call RunDbgCmd( buf, 'up' )
520 call RunDbgCmd( buf, 'backtrace', [
521 \ '>backtrace',
522 \ ' 3 function GlobalFunction[1]',
523 \ '->2 CallAFunction[1]',
524 \ ' 1 SourceAnotherFile[1]',
525 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
526 \ 'line 1: func DoAThing()' ] )
527
528 call RunDbgCmd( buf, 'up' )
529 call RunDbgCmd( buf, 'backtrace', [
530 \ '>backtrace',
531 \ '->3 function GlobalFunction[1]',
532 \ ' 2 CallAFunction[1]',
533 \ ' 1 SourceAnotherFile[1]',
534 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
535 \ 'line 1: func DoAThing()' ] )
536
537 call RunDbgCmd( buf, 'up', [ 'frame at highest level: 3' ] )
538 call RunDbgCmd( buf, 'backtrace', [
539 \ '>backtrace',
540 \ '->3 function GlobalFunction[1]',
541 \ ' 2 CallAFunction[1]',
542 \ ' 1 SourceAnotherFile[1]',
543 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
544 \ 'line 1: func DoAThing()' ] )
545
546 call RunDbgCmd( buf, 'down' )
547 call RunDbgCmd( buf, 'backtrace', [
548 \ '>backtrace',
549 \ ' 3 function GlobalFunction[1]',
550 \ '->2 CallAFunction[1]',
551 \ ' 1 SourceAnotherFile[1]',
552 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
553 \ 'line 1: func DoAThing()' ] )
554
555 call RunDbgCmd( buf, 'down' )
556 call RunDbgCmd( buf, 'backtrace', [
557 \ '>backtrace',
558 \ ' 3 function GlobalFunction[1]',
559 \ ' 2 CallAFunction[1]',
560 \ '->1 SourceAnotherFile[1]',
561 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
562 \ 'line 1: func DoAThing()' ] )
563
564 call RunDbgCmd( buf, 'down' )
565 call RunDbgCmd( buf, 'backtrace', [
566 \ '>backtrace',
567 \ ' 3 function GlobalFunction[1]',
568 \ ' 2 CallAFunction[1]',
569 \ ' 1 SourceAnotherFile[1]',
570 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
571 \ 'line 1: func DoAThing()' ] )
572
573 call RunDbgCmd( buf, 'down', [ 'frame is zero' ] )
574
Dominique Pelle923dce22021-11-21 11:36:04 +0000575 " step until we have another meaningful trace
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200576 call RunDbgCmd(buf, 'step', ['line 5: func File2Function()'])
577 call RunDbgCmd(buf, 'step', ['line 9: call File2Function()'])
578 call RunDbgCmd(buf, 'backtrace', [
579 \ '>backtrace',
580 \ ' 3 function GlobalFunction[1]',
581 \ ' 2 CallAFunction[1]',
582 \ ' 1 SourceAnotherFile[1]',
583 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
584 \ 'line 9: call File2Function()'])
585
586 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
587 call RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"'])
588 call RunDbgCmd(buf, 'backtrace', [
589 \ '>backtrace',
590 \ ' 5 function GlobalFunction[1]',
591 \ ' 4 CallAFunction[1]',
592 \ ' 3 SourceAnotherFile[1]',
593 \ ' 2 script ' .. getcwd() .. '/Xtest2.vim[9]',
594 \ ' 1 function File2Function[1]',
595 \ '->0 DoAThing',
596 \ 'line 1: echo "DoAThing"'])
597
598 " Now, step (back to Xfile1.vim), and call the function _in_ Xfile2.vim
599 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
600 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
601 call RunDbgCmd(buf, 'step', ['line 10: End of sourced file'])
602 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
603 call RunDbgCmd(buf, 'step', ['line 2: call File2Function()'])
604 call RunDbgCmd(buf, 'backtrace', [
605 \ '>backtrace',
606 \ ' 1 function GlobalFunction[1]',
607 \ '->0 CallAFunction',
608 \ 'line 2: call File2Function()'])
609
610 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
611 call RunDbgCmd(buf, 'backtrace', [
612 \ '>backtrace',
613 \ ' 2 function GlobalFunction[1]',
614 \ ' 1 CallAFunction[2]',
615 \ '->0 File2Function',
616 \ 'line 1: call DoAThing()'])
617
618 call StopVimInTerminal(buf)
619 call delete('Xtest1.vim')
620 call delete('Xtest2.vim')
621endfunc
622
623func Test_Backtrace_Autocmd()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200624 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200625 let file1 =<< trim END
626 func SourceAnotherFile()
627 source Xtest2.vim
628 endfunc
629
630 func CallAFunction()
631 call SourceAnotherFile()
632 call File2Function()
633 endfunc
634
635 func GlobalFunction()
636 call CallAFunction()
637 endfunc
638
639 au User TestGlobalFunction :call GlobalFunction() | echo "Done"
640 END
641 call writefile(file1, 'Xtest1.vim')
642
643 let file2 =<< trim END
644 func DoAThing()
645 echo "DoAThing"
646 endfunc
647
648 func File2Function()
649 call DoAThing()
650 endfunc
651
652 call File2Function()
653 END
654 call writefile(file2, 'Xtest2.vim')
655
656 let buf = RunVimInTerminal('-S Xtest1.vim', {})
657
658 call RunDbgCmd(buf,
659 \ ':debug doautocmd User TestGlobalFunction',
660 \ ['cmd: doautocmd User TestGlobalFunction'])
661 call RunDbgCmd(buf, 'step', ['cmd: call GlobalFunction() | echo "Done"'])
662
Dominique Pelle923dce22021-11-21 11:36:04 +0000663 " At this point the only thing in the stack is the autocommand
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200664 call RunDbgCmd(buf, 'backtrace', [
665 \ '>backtrace',
666 \ '->0 User Autocommands for "TestGlobalFunction"',
667 \ 'cmd: call GlobalFunction() | echo "Done"'])
668
669 " And now we're back into the call stack
670 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
671 call RunDbgCmd(buf, 'backtrace', [
672 \ '>backtrace',
673 \ ' 1 User Autocommands for "TestGlobalFunction"',
674 \ '->0 function GlobalFunction',
675 \ 'line 1: call CallAFunction()'])
676
677 call RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()'])
678 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
679
680 call RunDbgCmd(buf, 'backtrace', [
681 \ '>backtrace',
682 \ ' 3 User Autocommands for "TestGlobalFunction"',
683 \ ' 2 function GlobalFunction[1]',
684 \ ' 1 CallAFunction[1]',
685 \ '->0 SourceAnotherFile',
686 \ 'line 1: source Xtest2.vim'])
687
688 " Step into the 'source' command. Note that we print the full trace all the
689 " way though the source command.
690 call RunDbgCmd(buf, 'step', ['line 1: func DoAThing()'])
691 call RunDbgCmd(buf, 'backtrace', [
692 \ '>backtrace',
693 \ ' 4 User Autocommands for "TestGlobalFunction"',
694 \ ' 3 function GlobalFunction[1]',
695 \ ' 2 CallAFunction[1]',
696 \ ' 1 SourceAnotherFile[1]',
697 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
698 \ 'line 1: func DoAThing()'])
699
Bram Moolenaarc63b72b2020-08-22 16:04:52 +0200700 call RunDbgCmd( buf, 'up' )
701 call RunDbgCmd( buf, 'backtrace', [
702 \ '>backtrace',
703 \ ' 4 User Autocommands for "TestGlobalFunction"',
704 \ ' 3 function GlobalFunction[1]',
705 \ ' 2 CallAFunction[1]',
706 \ '->1 SourceAnotherFile[1]',
707 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
708 \ 'line 1: func DoAThing()' ] )
709
710 call RunDbgCmd( buf, 'up' )
711 call RunDbgCmd( buf, 'backtrace', [
712 \ '>backtrace',
713 \ ' 4 User Autocommands for "TestGlobalFunction"',
714 \ ' 3 function GlobalFunction[1]',
715 \ '->2 CallAFunction[1]',
716 \ ' 1 SourceAnotherFile[1]',
717 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
718 \ 'line 1: func DoAThing()' ] )
719
720 call RunDbgCmd( buf, 'up' )
721 call RunDbgCmd( buf, 'backtrace', [
722 \ '>backtrace',
723 \ ' 4 User Autocommands for "TestGlobalFunction"',
724 \ '->3 function GlobalFunction[1]',
725 \ ' 2 CallAFunction[1]',
726 \ ' 1 SourceAnotherFile[1]',
727 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
728 \ 'line 1: func DoAThing()' ] )
729
730 call RunDbgCmd( buf, 'up' )
731 call RunDbgCmd( buf, 'backtrace', [
732 \ '>backtrace',
733 \ '->4 User Autocommands for "TestGlobalFunction"',
734 \ ' 3 function GlobalFunction[1]',
735 \ ' 2 CallAFunction[1]',
736 \ ' 1 SourceAnotherFile[1]',
737 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
738 \ 'line 1: func DoAThing()' ] )
739
740 call RunDbgCmd( buf, 'up', [ 'frame at highest level: 4' ] )
741 call RunDbgCmd( buf, 'backtrace', [
742 \ '>backtrace',
743 \ '->4 User Autocommands for "TestGlobalFunction"',
744 \ ' 3 function GlobalFunction[1]',
745 \ ' 2 CallAFunction[1]',
746 \ ' 1 SourceAnotherFile[1]',
747 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
748 \ 'line 1: func DoAThing()' ] )
749
750 call RunDbgCmd( buf, 'down' )
751 call RunDbgCmd( buf, 'backtrace', [
752 \ '>backtrace',
753 \ ' 4 User Autocommands for "TestGlobalFunction"',
754 \ '->3 function GlobalFunction[1]',
755 \ ' 2 CallAFunction[1]',
756 \ ' 1 SourceAnotherFile[1]',
757 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
758 \ 'line 1: func DoAThing()' ] )
759
760
761 call RunDbgCmd( buf, 'down' )
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 1: func DoAThing()' ] )
770
771 call RunDbgCmd( buf, 'down' )
772 call RunDbgCmd( buf, 'backtrace', [
773 \ '>backtrace',
774 \ ' 4 User Autocommands for "TestGlobalFunction"',
775 \ ' 3 function GlobalFunction[1]',
776 \ ' 2 CallAFunction[1]',
777 \ '->1 SourceAnotherFile[1]',
778 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
779 \ 'line 1: func DoAThing()' ] )
780
781 call RunDbgCmd( buf, 'down' )
782 call RunDbgCmd( buf, 'backtrace', [
783 \ '>backtrace',
784 \ ' 4 User Autocommands for "TestGlobalFunction"',
785 \ ' 3 function GlobalFunction[1]',
786 \ ' 2 CallAFunction[1]',
787 \ ' 1 SourceAnotherFile[1]',
788 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
789 \ 'line 1: func DoAThing()' ] )
790
791 call RunDbgCmd( buf, 'down', [ 'frame is zero' ] )
792
Dominique Pelle923dce22021-11-21 11:36:04 +0000793 " step until we have another meaningful trace
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200794 call RunDbgCmd(buf, 'step', ['line 5: func File2Function()'])
795 call RunDbgCmd(buf, 'step', ['line 9: call File2Function()'])
796 call RunDbgCmd(buf, 'backtrace', [
797 \ '>backtrace',
798 \ ' 4 User Autocommands for "TestGlobalFunction"',
799 \ ' 3 function GlobalFunction[1]',
800 \ ' 2 CallAFunction[1]',
801 \ ' 1 SourceAnotherFile[1]',
802 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
803 \ 'line 9: call File2Function()'])
804
805 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
806 call RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"'])
807 call RunDbgCmd(buf, 'backtrace', [
808 \ '>backtrace',
809 \ ' 6 User Autocommands for "TestGlobalFunction"',
810 \ ' 5 function GlobalFunction[1]',
811 \ ' 4 CallAFunction[1]',
812 \ ' 3 SourceAnotherFile[1]',
813 \ ' 2 script ' .. getcwd() .. '/Xtest2.vim[9]',
814 \ ' 1 function File2Function[1]',
815 \ '->0 DoAThing',
816 \ 'line 1: echo "DoAThing"'])
817
818 " Now, step (back to Xfile1.vim), and call the function _in_ Xfile2.vim
819 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
820 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
821 call RunDbgCmd(buf, 'step', ['line 10: End of sourced file'])
822 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
823 call RunDbgCmd(buf, 'step', ['line 2: call File2Function()'])
824 call RunDbgCmd(buf, 'backtrace', [
825 \ '>backtrace',
826 \ ' 2 User Autocommands for "TestGlobalFunction"',
827 \ ' 1 function GlobalFunction[1]',
828 \ '->0 CallAFunction',
829 \ 'line 2: call File2Function()'])
830
831 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
832 call RunDbgCmd(buf, 'backtrace', [
833 \ '>backtrace',
834 \ ' 3 User Autocommands for "TestGlobalFunction"',
835 \ ' 2 function GlobalFunction[1]',
836 \ ' 1 CallAFunction[2]',
837 \ '->0 File2Function',
838 \ 'line 1: call DoAThing()'])
839
840
841 " Now unwind so that we get back to the original autocommand (and the second
842 " cmd echo "Done")
843 call RunDbgCmd(buf, 'finish', ['line 1: End of function'])
844 call RunDbgCmd(buf, 'backtrace', [
845 \ '>backtrace',
846 \ ' 3 User Autocommands for "TestGlobalFunction"',
847 \ ' 2 function GlobalFunction[1]',
848 \ ' 1 CallAFunction[2]',
849 \ '->0 File2Function',
850 \ 'line 1: End of function'])
851
852 call RunDbgCmd(buf, 'finish', ['line 2: End of function'])
853 call RunDbgCmd(buf, 'backtrace', [
854 \ '>backtrace',
855 \ ' 2 User Autocommands for "TestGlobalFunction"',
856 \ ' 1 function GlobalFunction[1]',
857 \ '->0 CallAFunction',
858 \ 'line 2: End of function'])
859
860 call RunDbgCmd(buf, 'finish', ['line 1: End of function'])
861 call RunDbgCmd(buf, 'backtrace', [
862 \ '>backtrace',
863 \ ' 1 User Autocommands for "TestGlobalFunction"',
864 \ '->0 function GlobalFunction',
865 \ 'line 1: End of function'])
866
867 call RunDbgCmd(buf, 'step', ['cmd: echo "Done"'])
868 call RunDbgCmd(buf, 'backtrace', [
869 \ '>backtrace',
870 \ '->0 User Autocommands for "TestGlobalFunction"',
871 \ 'cmd: echo "Done"'])
872
873 call StopVimInTerminal(buf)
874 call delete('Xtest1.vim')
875 call delete('Xtest2.vim')
876endfunc
877
878func Test_Backtrace_CmdLine()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200879 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200880 let file1 =<< trim END
881 func SourceAnotherFile()
882 source Xtest2.vim
883 endfunc
884
885 func CallAFunction()
886 call SourceAnotherFile()
887 call File2Function()
888 endfunc
889
890 func GlobalFunction()
891 call CallAFunction()
892 endfunc
893
894 au User TestGlobalFunction :call GlobalFunction() | echo "Done"
895 END
896 call writefile(file1, 'Xtest1.vim')
897
898 let file2 =<< trim END
899 func DoAThing()
900 echo "DoAThing"
901 endfunc
902
903 func File2Function()
904 call DoAThing()
905 endfunc
906
907 call File2Function()
908 END
909 call writefile(file2, 'Xtest2.vim')
910
911 let buf = RunVimInTerminal(
912 \ '-S Xtest1.vim -c "debug call GlobalFunction()"',
913 \ {'wait_for_ruler': 0})
914
Bram Moolenaar18dc3552020-11-22 14:24:00 +0100915 " Need to wait for the vim-in-terminal to be ready.
916 " With valgrind this can take quite long.
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200917 call CheckDbgOutput(buf, ['command line',
Bram Moolenaar18dc3552020-11-22 14:24:00 +0100918 \ 'cmd: call GlobalFunction()'], #{msec: 5000})
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200919
Dominique Pelle923dce22021-11-21 11:36:04 +0000920 " At this point the only thing in the stack is the cmdline
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200921 call RunDbgCmd(buf, 'backtrace', [
922 \ '>backtrace',
923 \ '->0 command line',
924 \ 'cmd: call GlobalFunction()'])
925
926 " And now we're back into the call stack
927 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
928 call RunDbgCmd(buf, 'backtrace', [
929 \ '>backtrace',
930 \ ' 1 command line',
931 \ '->0 function GlobalFunction',
932 \ 'line 1: call CallAFunction()'])
933
934 call StopVimInTerminal(buf)
935 call delete('Xtest1.vim')
936 call delete('Xtest2.vim')
937endfunc
938
939func Test_Backtrace_DefFunction()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200940 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200941 let file1 =<< trim END
942 vim9script
Bram Moolenaar84c62d52022-01-06 21:31:19 +0000943 import './Xtest2.vim' as imp
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200944
945 def SourceAnotherFile()
946 source Xtest2.vim
947 enddef
948
949 def CallAFunction()
950 SourceAnotherFile()
Bram Moolenaar84c62d52022-01-06 21:31:19 +0000951 imp.File2Function()
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200952 enddef
953
954 def g:GlobalFunction()
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +0200955 var some = "some var"
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200956 CallAFunction()
957 enddef
958
959 defcompile
960 END
961 call writefile(file1, 'Xtest1.vim')
962
963 let file2 =<< trim END
964 vim9script
965
966 def DoAThing(): number
Bram Moolenaar1bdae402020-10-03 14:14:56 +0200967 var a = 100 * 2
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200968 a += 3
969 return a
970 enddef
971
972 export def File2Function()
973 DoAThing()
974 enddef
975
976 defcompile
977 File2Function()
978 END
979 call writefile(file2, 'Xtest2.vim')
980
981 let buf = RunVimInTerminal('-S Xtest1.vim', {})
982
983 call RunDbgCmd(buf,
984 \ ':debug call GlobalFunction()',
985 \ ['cmd: call GlobalFunction()'])
986
Bram Moolenaar4cea5362021-06-16 22:24:40 +0200987 call RunDbgCmd(buf, 'step', ['line 1: var some = "some var"'])
988 call RunDbgCmd(buf, 'step', ['line 2: CallAFunction()'])
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +0200989 call RunDbgCmd(buf, 'echo some', ['some var'])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200990
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200991 call RunDbgCmd(buf, 'backtrace', [
992 \ '\V>backtrace',
Bram Moolenaare99d4222021-06-13 14:01:26 +0200993 \ '\V->0 function GlobalFunction',
Bram Moolenaar4cea5362021-06-16 22:24:40 +0200994 \ '\Vline 2: CallAFunction()',
Bram Moolenaare99d4222021-06-13 14:01:26 +0200995 \ ],
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200996 \ #{match: 'pattern'})
997
Bram Moolenaar4cea5362021-06-16 22:24:40 +0200998 call RunDbgCmd(buf, 'step', ['line 1: SourceAnotherFile()'])
999 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
Dominique Pelleaf4a61a2021-12-27 17:21:41 +00001000 " Repeated line, because we first are in the compiled function before the
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +02001001 " EXEC and then in do_cmdline() before the :source command.
Bram Moolenaare99d4222021-06-13 14:01:26 +02001002 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +02001003 call RunDbgCmd(buf, 'step', ['line 1: vim9script'])
1004 call RunDbgCmd(buf, 'step', ['line 3: def DoAThing(): number'])
1005 call RunDbgCmd(buf, 'step', ['line 9: export def File2Function()'])
1006 call RunDbgCmd(buf, 'step', ['line 9: def File2Function()'])
1007 call RunDbgCmd(buf, 'step', ['line 13: defcompile'])
1008 call RunDbgCmd(buf, 'step', ['line 14: File2Function()'])
1009 call RunDbgCmd(buf, 'backtrace', [
1010 \ '\V>backtrace',
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +02001011 \ '\V 3 function GlobalFunction[2]',
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +02001012 \ '\V 2 <SNR>\.\*_CallAFunction[1]',
1013 \ '\V 1 <SNR>\.\*_SourceAnotherFile[1]',
1014 \ '\V->0 script ' .. getcwd() .. '/Xtest2.vim',
1015 \ '\Vline 14: File2Function()'],
1016 \ #{match: 'pattern'})
1017
1018 " Don't step into compiled functions...
Bram Moolenaare99d4222021-06-13 14:01:26 +02001019 call RunDbgCmd(buf, 'next', ['line 15: End of sourced file'])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +02001020 call RunDbgCmd(buf, 'backtrace', [
1021 \ '\V>backtrace',
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +02001022 \ '\V 3 function GlobalFunction[2]',
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +02001023 \ '\V 2 <SNR>\.\*_CallAFunction[1]',
1024 \ '\V 1 <SNR>\.\*_SourceAnotherFile[1]',
1025 \ '\V->0 script ' .. getcwd() .. '/Xtest2.vim',
1026 \ '\Vline 15: End of sourced file'],
1027 \ #{match: 'pattern'})
1028
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +02001029 call StopVimInTerminal(buf)
1030 call delete('Xtest1.vim')
1031 call delete('Xtest2.vim')
1032endfunc
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001033
Bram Moolenaar26a44842021-09-02 18:49:06 +02001034func Test_DefFunction_expr()
1035 CheckCWD
1036 let file3 =<< trim END
1037 vim9script
1038 g:someVar = "foo"
1039 def g:ChangeVar()
1040 g:someVar = "bar"
1041 echo "changed"
1042 enddef
1043 defcompile
1044 END
1045 call writefile(file3, 'Xtest3.vim')
1046 let buf = RunVimInTerminal('-S Xtest3.vim', {})
1047
1048 call RunDbgCmd(buf, ':breakadd expr g:someVar')
1049 call RunDbgCmd(buf, ':call g:ChangeVar()', ['Oldval = "''foo''"', 'Newval = "''bar''"', 'function ChangeVar', 'line 2: echo "changed"'])
1050
1051 call StopVimInTerminal(buf)
1052 call delete('Xtest3.vim')
1053endfunc
1054
Bram Moolenaar17d868b2021-06-27 16:29:53 +02001055func Test_debug_def_and_legacy_function()
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001056 CheckCWD
1057 let file =<< trim END
1058 vim9script
1059 def g:SomeFunc()
1060 echo "here"
1061 echo "and"
1062 echo "there"
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001063 breakadd func 2 LocalFunc
1064 LocalFunc()
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001065 enddef
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001066
1067 def LocalFunc()
1068 echo "first"
1069 echo "second"
Bram Moolenaar8cec9272021-06-23 20:20:53 +02001070 breakadd func LegacyFunc
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001071 LegacyFunc()
1072 enddef
1073
1074 func LegacyFunc()
1075 echo "legone"
1076 echo "legtwo"
1077 endfunc
1078
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001079 breakadd func 2 g:SomeFunc
1080 END
1081 call writefile(file, 'XtestDebug.vim')
1082
1083 let buf = RunVimInTerminal('-S XtestDebug.vim', {})
1084
1085 call RunDbgCmd(buf,':call SomeFunc()', ['line 2: echo "and"'])
1086 call RunDbgCmd(buf,'next', ['line 3: echo "there"'])
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001087 call RunDbgCmd(buf,'next', ['line 4: breakadd func 2 LocalFunc'])
1088
1089 " continue, next breakpoint is in LocalFunc()
1090 call RunDbgCmd(buf,'cont', ['line 2: echo "second"'])
1091
1092 " continue, next breakpoint is in LegacyFunc()
1093 call RunDbgCmd(buf,'cont', ['line 1: echo "legone"'])
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001094
1095 call RunDbgCmd(buf, 'cont')
1096
1097 call StopVimInTerminal(buf)
Dominique Pelle6c72fd52021-07-04 12:30:06 +02001098 call delete('XtestDebug.vim')
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001099endfunc
1100
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001101func Test_debug_def_function()
1102 CheckCWD
1103 let file =<< trim END
1104 vim9script
1105 def g:Func()
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001106 var n: number
1107 def Closure(): number
1108 return n + 3
1109 enddef
1110 n += Closure()
1111 echo 'result: ' .. n
1112 enddef
1113
1114 def g:FuncWithArgs(text: string, nr: number, ...items: list<number>)
1115 echo text .. nr
1116 for it in items
1117 echo it
1118 endfor
1119 echo "done"
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001120 enddef
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001121
1122 def g:FuncWithDict()
1123 var d = {
1124 a: 1,
1125 b: 2,
1126 }
Bram Moolenaar59b50c32021-06-17 22:27:48 +02001127 # comment
1128 def Inner()
Bram Moolenaar31e21762021-07-10 20:43:59 +02001129 eval 1 + 2
Bram Moolenaar59b50c32021-06-17 22:27:48 +02001130 enddef
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001131 enddef
Bram Moolenaar303215d2021-07-07 20:10:43 +02001132
Bram Moolenaar8cec9272021-06-23 20:20:53 +02001133 def g:FuncComment()
1134 # comment
1135 echo "first"
1136 .. "one"
1137 # comment
1138 echo "second"
1139 enddef
Bram Moolenaar303215d2021-07-07 20:10:43 +02001140
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001141 def g:FuncForLoop()
Bram Moolenaar31e21762021-07-10 20:43:59 +02001142 eval 1 + 2
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001143 for i in [11, 22, 33]
Bram Moolenaar31e21762021-07-10 20:43:59 +02001144 eval i + 2
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001145 endfor
1146 echo "done"
1147 enddef
Bram Moolenaar303215d2021-07-07 20:10:43 +02001148
1149 def g:FuncWithSplitLine()
Bram Moolenaar31e21762021-07-10 20:43:59 +02001150 eval 1 + 2
1151 | eval 2 + 3
Bram Moolenaar303215d2021-07-07 20:10:43 +02001152 enddef
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001153 END
1154 call writefile(file, 'Xtest.vim')
1155
1156 let buf = RunVimInTerminal('-S Xtest.vim', {})
1157
1158 call RunDbgCmd(buf,
1159 \ ':debug call Func()',
1160 \ ['cmd: call Func()'])
1161 call RunDbgCmd(buf, 'next', ['result: 3'])
1162 call term_sendkeys(buf, "\r")
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001163 call RunDbgCmd(buf, 'cont')
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001164
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001165 call RunDbgCmd(buf,
1166 \ ':debug call FuncWithArgs("asdf", 42, 1, 2, 3)',
1167 \ ['cmd: call FuncWithArgs("asdf", 42, 1, 2, 3)'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001168 call RunDbgCmd(buf, 'step', ['line 1: echo text .. nr'])
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001169 call RunDbgCmd(buf, 'echo text', ['asdf'])
1170 call RunDbgCmd(buf, 'echo nr', ['42'])
1171 call RunDbgCmd(buf, 'echo items', ['[1, 2, 3]'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001172 call RunDbgCmd(buf, 'step', ['asdf42', 'function FuncWithArgs', 'line 2: for it in items'])
1173 call RunDbgCmd(buf, 'step', ['function FuncWithArgs', 'line 2: for it in items'])
1174 call RunDbgCmd(buf, 'echo it', ['0'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001175 call RunDbgCmd(buf, 'step', ['line 3: echo it'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001176 call RunDbgCmd(buf, 'echo it', ['1'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001177 call RunDbgCmd(buf, 'step', ['1', 'function FuncWithArgs', 'line 4: endfor'])
1178 call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001179 call RunDbgCmd(buf, 'echo it', ['1'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001180 call RunDbgCmd(buf, 'step', ['line 3: echo it'])
1181 call RunDbgCmd(buf, 'step', ['2', 'function FuncWithArgs', 'line 4: endfor'])
1182 call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001183 call RunDbgCmd(buf, 'echo it', ['2'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001184 call RunDbgCmd(buf, 'step', ['line 3: echo it'])
1185 call RunDbgCmd(buf, 'step', ['3', 'function FuncWithArgs', 'line 4: endfor'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001186 call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001187 call RunDbgCmd(buf, 'step', ['line 5: echo "done"'])
1188 call RunDbgCmd(buf, 'cont')
1189
1190 call RunDbgCmd(buf,
1191 \ ':debug call FuncWithDict()',
1192 \ ['cmd: call FuncWithDict()'])
1193 call RunDbgCmd(buf, 'step', ['line 1: var d = { a: 1, b: 2, }'])
Bram Moolenaar59b50c32021-06-17 22:27:48 +02001194 call RunDbgCmd(buf, 'step', ['line 6: def Inner()'])
Bram Moolenaar8cec9272021-06-23 20:20:53 +02001195 call RunDbgCmd(buf, 'cont')
1196
1197 call RunDbgCmd(buf, ':breakadd func 1 FuncComment')
1198 call RunDbgCmd(buf, ':call FuncComment()', ['function FuncComment', 'line 2: echo "first" .. "one"'])
1199 call RunDbgCmd(buf, ':breakadd func 3 FuncComment')
1200 call RunDbgCmd(buf, 'cont', ['function FuncComment', 'line 5: echo "second"'])
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001201 call RunDbgCmd(buf, 'cont')
1202
1203 call RunDbgCmd(buf, ':breakadd func 2 FuncForLoop')
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001204 call RunDbgCmd(buf, ':call FuncForLoop()', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]'])
1205 call RunDbgCmd(buf, 'step', ['line 2: for i in [11, 22, 33]'])
Bram Moolenaar31e21762021-07-10 20:43:59 +02001206 call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 3: eval i + 2'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001207 call RunDbgCmd(buf, 'echo i', ['11'])
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001208 call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 4: endfor'])
1209 call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001210 call RunDbgCmd(buf, 'next', ['line 3: eval i + 2'])
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001211 call RunDbgCmd(buf, 'echo i', ['22'])
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001212
Bram Moolenaar303215d2021-07-07 20:10:43 +02001213 call RunDbgCmd(buf, 'breakdel *')
1214 call RunDbgCmd(buf, 'cont')
1215
1216 call RunDbgCmd(buf, ':breakadd func FuncWithSplitLine')
Bram Moolenaar31e21762021-07-10 20:43:59 +02001217 call RunDbgCmd(buf, ':call FuncWithSplitLine()', ['function FuncWithSplitLine', 'line 1: eval 1 + 2 | eval 2 + 3'])
Bram Moolenaar303215d2021-07-07 20:10:43 +02001218
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001219 call RunDbgCmd(buf, 'cont')
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001220 call StopVimInTerminal(buf)
1221 call delete('Xtest.vim')
1222endfunc
1223
Bram Moolenaar17d868b2021-06-27 16:29:53 +02001224func Test_debug_def_function_with_lambda()
1225 CheckCWD
1226 let lines =<< trim END
1227 vim9script
1228 def g:Func()
1229 var s = 'a'
1230 ['b']->map((_, v) => s)
1231 echo "done"
1232 enddef
1233 breakadd func 2 g:Func
1234 END
1235 call writefile(lines, 'XtestLambda.vim')
1236
1237 let buf = RunVimInTerminal('-S XtestLambda.vim', {})
1238
1239 call RunDbgCmd(buf,
1240 \ ':call g:Func()',
1241 \ ['function Func', 'line 2: [''b'']->map((_, v) => s)'])
1242 call RunDbgCmd(buf,
1243 \ 'next',
1244 \ ['function Func', 'line 3: echo "done"'])
1245
1246 call RunDbgCmd(buf, 'cont')
1247 call StopVimInTerminal(buf)
1248 call delete('XtestLambda.vim')
1249endfunc
1250
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001251func Test_debug_backtrace_level()
1252 CheckCWD
1253 let lines =<< trim END
1254 let s:file1_var = 'file1'
1255 let g:global_var = 'global'
1256
1257 func s:File1Func( arg )
1258 let s:file1_var .= a:arg
1259 let local_var = s:file1_var .. ' test1'
1260 let g:global_var .= local_var
1261 source Xtest2.vim
1262 endfunc
1263
1264 call s:File1Func( 'arg1' )
1265 END
1266 call writefile(lines, 'Xtest1.vim')
1267
1268 let lines =<< trim END
1269 let s:file2_var = 'file2'
1270
1271 func s:File2Func( arg )
1272 let s:file2_var .= a:arg
1273 let local_var = s:file2_var .. ' test2'
1274 let g:global_var .= local_var
1275 endfunc
1276
1277 call s:File2Func( 'arg2' )
1278 END
1279 call writefile(lines, 'Xtest2.vim')
1280
1281 let file1 = getcwd() .. '/Xtest1.vim'
1282 let file2 = getcwd() .. '/Xtest2.vim'
1283
1284 " set a breakpoint and source file1.vim
1285 let buf = RunVimInTerminal(
1286 \ '-c "breakadd file 1 Xtest1.vim" -S Xtest1.vim',
Bram Moolenaar18dc3552020-11-22 14:24:00 +01001287 \ #{wait_for_ruler: 0})
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001288
1289 call CheckDbgOutput(buf, [
1290 \ 'Breakpoint in "' .. file1 .. '" line 1',
1291 \ 'Entering Debug mode. Type "cont" to continue.',
1292 \ 'command line..script ' .. file1,
1293 \ 'line 1: let s:file1_var = ''file1'''
Bram Moolenaar18dc3552020-11-22 14:24:00 +01001294 \ ], #{msec: 5000})
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001295
Bram Moolenaar8e7d6222020-12-18 19:49:56 +01001296 " step through the initial declarations
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001297 call RunDbgCmd(buf, 'step', [ 'line 2: let g:global_var = ''global''' ] )
1298 call RunDbgCmd(buf, 'step', [ 'line 4: func s:File1Func( arg )' ] )
1299 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1300 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1301 call RunDbgCmd(buf, 'echo global_var', [ 'global' ] )
1302
1303 " step in to the first function
1304 call RunDbgCmd(buf, 'step', [ 'line 11: call s:File1Func( ''arg1'' )' ] )
1305 call RunDbgCmd(buf, 'step', [ 'line 1: let s:file1_var .= a:arg' ] )
1306 call RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] )
1307 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1308 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1309 call RunDbgCmd(buf,
1310 \'echo global_var',
1311 \[ 'E121: Undefined variable: global_var' ] )
1312 call RunDbgCmd(buf,
1313 \'echo local_var',
1314 \[ 'E121: Undefined variable: local_var' ] )
1315 call RunDbgCmd(buf,
1316 \'echo l:local_var',
1317 \[ 'E121: Undefined variable: l:local_var' ] )
1318
1319 " backtrace up
1320 call RunDbgCmd(buf, 'backtrace', [
1321 \ '\V>backtrace',
1322 \ '\V 2 command line',
1323 \ '\V 1 script ' .. file1 .. '[11]',
1324 \ '\V->0 function <SNR>\.\*_File1Func',
1325 \ '\Vline 1: let s:file1_var .= a:arg',
1326 \ ],
1327 \ #{ match: 'pattern' } )
1328 call RunDbgCmd(buf, 'up', [ '>up' ] )
1329
1330 call RunDbgCmd(buf, 'backtrace', [
1331 \ '\V>backtrace',
1332 \ '\V 2 command line',
1333 \ '\V->1 script ' .. file1 .. '[11]',
1334 \ '\V 0 function <SNR>\.\*_File1Func',
1335 \ '\Vline 1: let s:file1_var .= a:arg',
1336 \ ],
1337 \ #{ match: 'pattern' } )
1338
1339 " Expression evaluation in the script frame (not the function frame)
Dominique Pelle923dce22021-11-21 11:36:04 +00001340 " FIXME: Unexpected in this scope (a: should not be visible)
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001341 call RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] )
1342 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1343 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1344 " FIXME: Unexpected in this scope (global should be found)
1345 call RunDbgCmd(buf,
1346 \'echo global_var',
1347 \[ 'E121: Undefined variable: global_var' ] )
1348 call RunDbgCmd(buf,
1349 \'echo local_var',
1350 \[ 'E121: Undefined variable: local_var' ] )
1351 call RunDbgCmd(buf,
1352 \'echo l:local_var',
1353 \[ 'E121: Undefined variable: l:local_var' ] )
1354
1355
1356 " step while backtraced jumps to the latest frame
1357 call RunDbgCmd(buf, 'step', [
1358 \ 'line 2: let local_var = s:file1_var .. '' test1''' ] )
1359 call RunDbgCmd(buf, 'backtrace', [
1360 \ '\V>backtrace',
1361 \ '\V 2 command line',
1362 \ '\V 1 script ' .. file1 .. '[11]',
1363 \ '\V->0 function <SNR>\.\*_File1Func',
1364 \ '\Vline 2: let local_var = s:file1_var .. '' test1''',
1365 \ ],
1366 \ #{ match: 'pattern' } )
1367
1368 call RunDbgCmd(buf, 'step', [ 'line 3: let g:global_var .= local_var' ] )
1369 call RunDbgCmd(buf, 'echo local_var', [ 'file1arg1 test1' ] )
1370 call RunDbgCmd(buf, 'echo l:local_var', [ 'file1arg1 test1' ] )
1371
1372 call RunDbgCmd(buf, 'step', [ 'line 4: source Xtest2.vim' ] )
1373 call RunDbgCmd(buf, 'step', [ 'line 1: let s:file2_var = ''file2''' ] )
1374 call RunDbgCmd(buf, 'backtrace', [
1375 \ '\V>backtrace',
1376 \ '\V 3 command line',
1377 \ '\V 2 script ' .. file1 .. '[11]',
1378 \ '\V 1 function <SNR>\.\*_File1Func[4]',
1379 \ '\V->0 script ' .. file2,
1380 \ '\Vline 1: let s:file2_var = ''file2''',
1381 \ ],
1382 \ #{ match: 'pattern' } )
1383
1384 " Expression evaluation in the script frame file2 (not the function frame)
1385 call RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] )
1386 call RunDbgCmd(buf,
1387 \ 'echo s:file1_var',
1388 \ [ 'E121: Undefined variable: s:file1_var' ] )
1389 call RunDbgCmd(buf, 'echo g:global_var', [ 'globalfile1arg1 test1' ] )
1390 call RunDbgCmd(buf, 'echo global_var', [ 'globalfile1arg1 test1' ] )
1391 call RunDbgCmd(buf,
1392 \'echo local_var',
1393 \[ 'E121: Undefined variable: local_var' ] )
1394 call RunDbgCmd(buf,
1395 \'echo l:local_var',
1396 \[ 'E121: Undefined variable: l:local_var' ] )
1397 call RunDbgCmd(buf,
1398 \ 'echo s:file2_var',
1399 \ [ 'E121: Undefined variable: s:file2_var' ] )
1400
1401 call RunDbgCmd(buf, 'step', [ 'line 3: func s:File2Func( arg )' ] )
1402 call RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] )
1403
1404 " Up the stack to the other script context
1405 call RunDbgCmd(buf, 'up')
1406 call RunDbgCmd(buf, 'backtrace', [
1407 \ '\V>backtrace',
1408 \ '\V 3 command line',
1409 \ '\V 2 script ' .. file1 .. '[11]',
1410 \ '\V->1 function <SNR>\.\*_File1Func[4]',
1411 \ '\V 0 script ' .. file2,
1412 \ '\Vline 3: func s:File2Func( arg )',
1413 \ ],
1414 \ #{ match: 'pattern' } )
1415 " FIXME: Unexpected. Should see the a: and l: dicts from File1Func
1416 call RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] )
1417 call RunDbgCmd(buf,
1418 \ 'echo l:local_var',
1419 \ [ 'E121: Undefined variable: l:local_var' ] )
1420
1421 call RunDbgCmd(buf, 'up')
1422 call RunDbgCmd(buf, 'backtrace', [
1423 \ '\V>backtrace',
1424 \ '\V 3 command line',
1425 \ '\V->2 script ' .. file1 .. '[11]',
1426 \ '\V 1 function <SNR>\.\*_File1Func[4]',
1427 \ '\V 0 script ' .. file2,
1428 \ '\Vline 3: func s:File2Func( arg )',
1429 \ ],
1430 \ #{ match: 'pattern' } )
1431
1432 " FIXME: Unexpected (wrong script vars are used)
1433 call RunDbgCmd(buf,
1434 \ 'echo s:file1_var',
1435 \ [ 'E121: Undefined variable: s:file1_var' ] )
1436 call RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] )
1437
Bram Moolenaare99d4222021-06-13 14:01:26 +02001438 call RunDbgCmd(buf, 'cont')
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001439 call StopVimInTerminal(buf)
1440 call delete('Xtest1.vim')
1441 call delete('Xtest2.vim')
1442endfunc
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001443
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001444" Test for setting a breakpoint on a :endif where the :if condition is false
1445" and then quit the script. This should generate an interrupt.
1446func Test_breakpt_endif_intr()
1447 func F()
1448 let g:Xpath ..= 'a'
1449 if v:false
1450 let g:Xpath ..= 'b'
1451 endif
1452 invalid_command
1453 endfunc
1454
1455 let g:Xpath = ''
1456 breakadd func 4 F
1457 try
1458 let caught_intr = 0
1459 debuggreedy
1460 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001461 catch /^Vim:Interrupt$/
1462 call assert_match('\.F, line 4', v:throwpoint)
1463 let caught_intr = 1
1464 endtry
1465 0debuggreedy
1466 call assert_equal(1, caught_intr)
1467 call assert_equal('a', g:Xpath)
1468 breakdel *
1469 delfunc F
1470endfunc
1471
1472" Test for setting a breakpoint on a :else where the :if condition is false
1473" and then quit the script. This should generate an interrupt.
1474func Test_breakpt_else_intr()
1475 func F()
1476 let g:Xpath ..= 'a'
1477 if v:false
1478 let g:Xpath ..= 'b'
1479 else
1480 invalid_command
1481 endif
1482 invalid_command
1483 endfunc
1484
1485 let g:Xpath = ''
1486 breakadd func 4 F
1487 try
1488 let caught_intr = 0
1489 debuggreedy
1490 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001491 catch /^Vim:Interrupt$/
1492 call assert_match('\.F, line 4', v:throwpoint)
1493 let caught_intr = 1
1494 endtry
1495 0debuggreedy
1496 call assert_equal(1, caught_intr)
1497 call assert_equal('a', g:Xpath)
1498 breakdel *
1499 delfunc F
1500endfunc
1501
1502" Test for setting a breakpoint on a :endwhile where the :while condition is
1503" false and then quit the script. This should generate an interrupt.
1504func Test_breakpt_endwhile_intr()
1505 func F()
1506 let g:Xpath ..= 'a'
1507 while v:false
1508 let g:Xpath ..= 'b'
1509 endwhile
1510 invalid_command
1511 endfunc
1512
1513 let g:Xpath = ''
1514 breakadd func 4 F
1515 try
1516 let caught_intr = 0
1517 debuggreedy
1518 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001519 catch /^Vim:Interrupt$/
1520 call assert_match('\.F, line 4', v:throwpoint)
1521 let caught_intr = 1
1522 endtry
1523 0debuggreedy
1524 call assert_equal(1, caught_intr)
1525 call assert_equal('a', g:Xpath)
1526 breakdel *
1527 delfunc F
1528endfunc
1529
Bram Moolenaar16c62322020-08-13 19:20:04 +02001530" Test for setting a breakpoint on a script local function
1531func Test_breakpt_scriptlocal_func()
1532 let g:Xpath = ''
1533 func s:G()
1534 let g:Xpath ..= 'a'
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001535 endfunc
1536
Bram Moolenaar16c62322020-08-13 19:20:04 +02001537 let funcname = expand("<SID>") .. "G"
1538 exe "breakadd func 1 " .. funcname
1539 debuggreedy
1540 redir => output
1541 call feedkeys(":call " .. funcname .. "()\<CR>c\<CR>", "xt")
1542 redir END
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001543 0debuggreedy
Bram Moolenaar16c62322020-08-13 19:20:04 +02001544 call assert_match('Breakpoint in "' .. funcname .. '" line 1', output)
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001545 call assert_equal('a', g:Xpath)
1546 breakdel *
Bram Moolenaar16c62322020-08-13 19:20:04 +02001547 exe "delfunc " .. funcname
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001548endfunc
1549
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001550" vim: shiftwidth=2 sts=2 expandtab