blob: 957f5ac795a2402b3e77c620b1646c30f67c4d09 [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
76 END
77 call writefile(lines, 'Xtest.vim')
Bram Moolenaar113bf062019-04-17 16:54:05 +020078
79 " Start Vim in a terminal
80 let buf = RunVimInTerminal('-S Xtest.vim', {})
81
82 " Start the Vim debugger
Bram Moolenaarddd33082019-06-03 23:07:25 +020083 call RunDbgCmd(buf, ':debug echo Foo()', ['cmd: echo Foo()'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020084
85 " Create a few stack frames by stepping through functions
Bram Moolenaarddd33082019-06-03 23:07:25 +020086 call RunDbgCmd(buf, 'step', ['line 1: let var1 = 1'])
87 call RunDbgCmd(buf, 'step', ['line 2: let var2 = Bar(var1) + 9'])
88 call RunDbgCmd(buf, 'step', ['line 1: let var1 = 2 + a:var'])
89 call RunDbgCmd(buf, 'step', ['line 2: let var2 = Bazz(var1) + 4'])
90 call RunDbgCmd(buf, 'step', ['line 1: try'])
91 call RunDbgCmd(buf, 'step', ['line 2: let var1 = 3 + a:var'])
92 call RunDbgCmd(buf, 'step', ['line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020093
94 " check backtrace
95 call RunDbgCmd(buf, 'backtrace', [
96 \ ' 2 function Foo[2]',
97 \ ' 1 Bar[2]',
98 \ '->0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +020099 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200100
101 " Check variables in different stack frames
102 call RunDbgCmd(buf, 'echo var1', ['6'])
103
104 call RunDbgCmd(buf, 'up')
105 call RunDbgCmd(buf, 'back', [
106 \ ' 2 function Foo[2]',
107 \ '->1 Bar[2]',
108 \ ' 0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200109 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200110 call RunDbgCmd(buf, 'echo var1', ['3'])
111
112 call RunDbgCmd(buf, 'u')
113 call RunDbgCmd(buf, 'bt', [
114 \ '->2 function Foo[2]',
115 \ ' 1 Bar[2]',
116 \ ' 0 Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200117 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200118 call RunDbgCmd(buf, 'echo var1', ['1'])
119
120 " Undefined variables
121 call RunDbgCmd(buf, 'step')
122 call RunDbgCmd(buf, 'frame 2')
123 call RunDbgCmd(buf, 'echo var3', [
124 \ 'Error detected while processing function Foo[2]..Bar[2]..Bazz:',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200125 \ 'line 4:',
Bram Moolenaar113bf062019-04-17 16:54:05 +0200126 \ 'E121: Undefined variable: var3'])
127
128 " var3 is defined in this level with some other value
129 call RunDbgCmd(buf, 'fr 0')
130 call RunDbgCmd(buf, 'echo var3', ['another var'])
131
132 call RunDbgCmd(buf, 'step')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200133 call RunDbgCmd(buf, '')
134 call RunDbgCmd(buf, '')
135 call RunDbgCmd(buf, '')
136 call RunDbgCmd(buf, '')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200137 call RunDbgCmd(buf, 'step', [
138 \ 'function Foo[2]..Bar',
139 \ 'line 3: End of function'])
140 call RunDbgCmd(buf, 'up')
141
142 " Undefined var2
143 call RunDbgCmd(buf, 'echo var2', [
144 \ 'Error detected while processing function Foo[2]..Bar:',
145 \ 'line 3:',
146 \ 'E121: Undefined variable: var2'])
147
148 " Var2 is defined with 10
149 call RunDbgCmd(buf, 'down')
150 call RunDbgCmd(buf, 'echo var2', ['10'])
151
152 " Backtrace movements
153 call RunDbgCmd(buf, 'b', [
154 \ ' 1 function Foo[2]',
155 \ '->0 Bar',
156 \ 'line 3: End of function'])
157
158 " next command cannot go down, we are on bottom
159 call RunDbgCmd(buf, 'down', ['frame is zero'])
160 call RunDbgCmd(buf, 'up')
161
162 " next command cannot go up, we are on top
163 call RunDbgCmd(buf, 'up', ['frame at highest level: 1'])
164 call RunDbgCmd(buf, 'where', [
165 \ '->1 function Foo[2]',
166 \ ' 0 Bar',
167 \ 'line 3: End of function'])
168
169 " fil is not frame or finish, it is file
170 call RunDbgCmd(buf, 'fil', ['"[No Name]" --No lines in buffer--'])
171
172 " relative backtrace movement
173 call RunDbgCmd(buf, 'fr -1')
174 call RunDbgCmd(buf, 'frame', [
175 \ ' 1 function Foo[2]',
176 \ '->0 Bar',
177 \ 'line 3: End of function'])
178
179 call RunDbgCmd(buf, 'fr +1')
180 call RunDbgCmd(buf, 'fram', [
181 \ '->1 function Foo[2]',
182 \ ' 0 Bar',
183 \ 'line 3: End of function'])
184
185 " go beyond limits does not crash
186 call RunDbgCmd(buf, 'fr 100', ['frame at highest level: 1'])
187 call RunDbgCmd(buf, 'fra', [
188 \ '->1 function Foo[2]',
189 \ ' 0 Bar',
190 \ 'line 3: End of function'])
191
192 call RunDbgCmd(buf, 'frame -40', ['frame is zero'])
193 call RunDbgCmd(buf, 'fram', [
194 \ ' 1 function Foo[2]',
195 \ '->0 Bar',
196 \ 'line 3: End of function'])
197
198 " final result 19
199 call RunDbgCmd(buf, 'cont', ['19'])
200
201 " breakpoints tests
202
203 " Start a debug session, so that reading the last line from the terminal
204 " works properly.
Bram Moolenaar18dc3552020-11-22 14:24:00 +0100205 call RunDbgCmd(buf, ':debug echo Foo()', ['cmd: echo Foo()'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200206
207 " No breakpoints
208 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
209
210 " Place some breakpoints
211 call RunDbgCmd(buf, 'breaka func Bar')
212 call RunDbgCmd(buf, 'breaklis', [' 1 func Bar line 1'])
213 call RunDbgCmd(buf, 'breakadd func 3 Bazz')
214 call RunDbgCmd(buf, 'breaklist', [' 1 func Bar line 1',
215 \ ' 2 func Bazz line 3'])
216
217 " Check whether the breakpoints are hit
218 call RunDbgCmd(buf, 'cont', [
219 \ 'Breakpoint in "Bar" line 1',
220 \ 'function Foo[2]..Bar',
221 \ 'line 1: let var1 = 2 + a:var'])
222 call RunDbgCmd(buf, 'cont', [
223 \ 'Breakpoint in "Bazz" line 3',
224 \ 'function Foo[2]..Bar[2]..Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200225 \ 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200226
227 " Delete the breakpoints
228 call RunDbgCmd(buf, 'breakd 1')
229 call RunDbgCmd(buf, 'breakli', [' 2 func Bazz line 3'])
230 call RunDbgCmd(buf, 'breakdel func 3 Bazz')
231 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
232
233 call RunDbgCmd(buf, 'cont')
234
235 " Make sure the breakpoints are removed
236 call RunDbgCmd(buf, ':echo Foo()', ['19'])
237
238 " Delete a non-existing breakpoint
239 call RunDbgCmd(buf, ':breakdel 2', ['E161: Breakpoint not found: 2'])
240
241 " Expression breakpoint
242 call RunDbgCmd(buf, ':breakadd func 2 Bazz')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200243 call RunDbgCmd(buf, ':echo Bazz(1)', [
244 \ 'Entering Debug mode. Type "cont" to continue.',
245 \ 'function Bazz',
246 \ 'line 2: let var1 = 3 + a:var'])
247 call RunDbgCmd(buf, 'step')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200248 call RunDbgCmd(buf, 'step')
249 call RunDbgCmd(buf, 'breaka expr var3')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200250 call RunDbgCmd(buf, 'breakl', [' 3 func Bazz line 2',
251 \ ' 4 expr var3'])
252 call RunDbgCmd(buf, 'cont', ['Breakpoint in "Bazz" line 5',
Bram Moolenaar113bf062019-04-17 16:54:05 +0200253 \ 'Oldval = "''another var''"',
254 \ 'Newval = "''value2''"',
255 \ 'function Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200256 \ 'line 5: catch'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200257
258 call RunDbgCmd(buf, 'breakdel *')
259 call RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
260
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200261 " Check for error cases
262 call RunDbgCmd(buf, 'breakadd abcd', [
263 \ 'Error detected while processing function Bazz:',
264 \ 'line 5:',
265 \ 'E475: Invalid argument: abcd'])
266 call RunDbgCmd(buf, 'breakadd func', ['E475: Invalid argument: func'])
267 call RunDbgCmd(buf, 'breakadd func 2', ['E475: Invalid argument: func 2'])
268 call RunDbgCmd(buf, 'breaka func a()', ['E475: Invalid argument: func a()'])
269 call RunDbgCmd(buf, 'breakd abcd', ['E475: Invalid argument: abcd'])
270 call RunDbgCmd(buf, 'breakd func', ['E475: Invalid argument: func'])
271 call RunDbgCmd(buf, 'breakd func a()', ['E475: Invalid argument: func a()'])
272 call RunDbgCmd(buf, 'breakd func a', ['E161: Breakpoint not found: func a'])
273 call RunDbgCmd(buf, 'breakd expr', ['E475: Invalid argument: expr'])
Bram Moolenaar0325d392021-09-09 12:34:19 +0200274 call RunDbgCmd(buf, 'breakd expr x', ['E161: Breakpoint not found: expr x'])
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200275
Bram Moolenaar113bf062019-04-17 16:54:05 +0200276 " finish the current function
277 call RunDbgCmd(buf, 'finish', [
278 \ 'function Bazz',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200279 \ 'line 8: End of function'])
280 call RunDbgCmd(buf, 'cont')
281
282 " Test for :next
283 call RunDbgCmd(buf, ':debug echo Bar(1)')
284 call RunDbgCmd(buf, 'step')
285 call RunDbgCmd(buf, 'next')
286 call RunDbgCmd(buf, '', [
287 \ 'function Bar',
288 \ 'line 3: return var2'])
289 call RunDbgCmd(buf, 'c')
290
291 " Test for :interrupt
292 call RunDbgCmd(buf, ':debug echo Bazz(1)')
293 call RunDbgCmd(buf, 'step')
294 call RunDbgCmd(buf, 'step')
295 call RunDbgCmd(buf, 'interrupt', [
296 \ 'Exception thrown: Vim:Interrupt',
297 \ 'function Bazz',
298 \ 'line 5: catch'])
299 call RunDbgCmd(buf, 'c')
300
301 " Test for :quit
302 call RunDbgCmd(buf, ':debug echo Foo()')
303 call RunDbgCmd(buf, 'breakdel *')
304 call RunDbgCmd(buf, 'breakadd func 3 Foo')
305 call RunDbgCmd(buf, 'breakadd func 3 Bazz')
306 call RunDbgCmd(buf, 'cont', [
307 \ 'Breakpoint in "Bazz" line 3',
308 \ 'function Foo[2]..Bar[2]..Bazz',
309 \ 'line 3: let var3 = "another var"'])
310 call RunDbgCmd(buf, 'quit', [
311 \ 'Breakpoint in "Foo" line 3',
312 \ 'function Foo',
313 \ 'line 3: return var2'])
314 call RunDbgCmd(buf, 'breakdel *')
315 call RunDbgCmd(buf, 'quit')
316 call RunDbgCmd(buf, 'enew! | only!')
317
318 call StopVimInTerminal(buf)
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200319endfunc
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200320
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200321func Test_Debugger_breakadd()
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200322 " Tests for :breakadd file and :breakadd here
323 " Breakpoints should be set before sourcing the file
324
Bram Moolenaare7eb9272019-06-24 00:58:07 +0200325 let lines =<< trim END
326 let var1 = 10
327 let var2 = 20
328 let var3 = 30
329 let var4 = 40
330 END
331 call writefile(lines, 'Xtest.vim')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200332
333 " Start Vim in a terminal
334 let buf = RunVimInTerminal('Xtest.vim', {})
335 call RunDbgCmd(buf, ':breakadd file 2 Xtest.vim')
336 call RunDbgCmd(buf, ':4 | breakadd here')
337 call RunDbgCmd(buf, ':source Xtest.vim', ['line 2: let var2 = 20'])
338 call RunDbgCmd(buf, 'cont', ['line 4: let var4 = 40'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200339 call RunDbgCmd(buf, 'cont')
340
341 call StopVimInTerminal(buf)
342
343 call delete('Xtest.vim')
Bram Moolenaar16c62322020-08-13 19:20:04 +0200344 %bw!
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200345
Bram Moolenaar16c62322020-08-13 19:20:04 +0200346 call assert_fails('breakadd here', 'E32:')
Bram Moolenaar531be472020-09-23 22:38:05 +0200347 call assert_fails('breakadd file Xtest.vim /\)/', 'E55:')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200348endfunc
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200349
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200350def Test_Debugger_breakadd_expr()
351 var lines =<< trim END
352 vim9script
353 func g:EarlyFunc()
354 endfunc
355 breakadd expr DoesNotExist()
356 func g:LaterFunc()
357 endfunc
358 breakdel *
359 END
360 writefile(lines, 'Xtest.vim')
361
362 # Start Vim in a terminal
363 var buf = RunVimInTerminal('-S Xtest.vim', {wait_for_ruler: 0})
364 call TermWait(buf)
365
366 # Despite the failure the functions are defined
367 RunDbgCmd(buf, ':function g:EarlyFunc',
368 ['function EarlyFunc()', 'endfunction'], {match: 'pattern'})
369 RunDbgCmd(buf, ':function g:LaterFunc',
370 ['function LaterFunc()', 'endfunction'], {match: 'pattern'})
371
372 call StopVimInTerminal(buf)
373 call delete('Xtest.vim')
374enddef
375
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200376func Test_Backtrace_Through_Source()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200377 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200378 let file1 =<< trim END
379 func SourceAnotherFile()
380 source Xtest2.vim
381 endfunc
382
383 func CallAFunction()
384 call SourceAnotherFile()
385 call File2Function()
386 endfunc
387
388 func GlobalFunction()
389 call CallAFunction()
390 endfunc
391 END
392 call writefile(file1, 'Xtest1.vim')
393
394 let file2 =<< trim END
395 func DoAThing()
396 echo "DoAThing"
397 endfunc
398
399 func File2Function()
400 call DoAThing()
401 endfunc
402
403 call File2Function()
404 END
405 call writefile(file2, 'Xtest2.vim')
406
407 let buf = RunVimInTerminal('-S Xtest1.vim', {})
408
409 call RunDbgCmd(buf,
410 \ ':debug call GlobalFunction()',
411 \ ['cmd: call GlobalFunction()'])
412 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
413
414 call RunDbgCmd(buf, 'backtrace', ['>backtrace',
415 \ '->0 function GlobalFunction',
416 \ 'line 1: call CallAFunction()'])
417
418 call RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()'])
419 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
420
421 call RunDbgCmd(buf, 'backtrace', ['>backtrace',
422 \ ' 2 function GlobalFunction[1]',
423 \ ' 1 CallAFunction[1]',
424 \ '->0 SourceAnotherFile',
425 \ 'line 1: source Xtest2.vim'])
426
427 " Step into the 'source' command. Note that we print the full trace all the
428 " way though the source command.
429 call RunDbgCmd(buf, 'step', ['line 1: func DoAThing()'])
430 call RunDbgCmd(buf, 'backtrace', [
431 \ '>backtrace',
432 \ ' 3 function GlobalFunction[1]',
433 \ ' 2 CallAFunction[1]',
434 \ ' 1 SourceAnotherFile[1]',
435 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
436 \ 'line 1: func DoAThing()'])
437
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200438 call RunDbgCmd( buf, 'up' )
439 call RunDbgCmd( buf, 'backtrace', [
440 \ '>backtrace',
441 \ ' 3 function GlobalFunction[1]',
442 \ ' 2 CallAFunction[1]',
443 \ '->1 SourceAnotherFile[1]',
444 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
445 \ 'line 1: func DoAThing()' ] )
446
447 call RunDbgCmd( buf, 'up' )
448 call RunDbgCmd( buf, 'backtrace', [
449 \ '>backtrace',
450 \ ' 3 function GlobalFunction[1]',
451 \ '->2 CallAFunction[1]',
452 \ ' 1 SourceAnotherFile[1]',
453 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
454 \ 'line 1: func DoAThing()' ] )
455
456 call RunDbgCmd( buf, 'up' )
457 call RunDbgCmd( buf, 'backtrace', [
458 \ '>backtrace',
459 \ '->3 function GlobalFunction[1]',
460 \ ' 2 CallAFunction[1]',
461 \ ' 1 SourceAnotherFile[1]',
462 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
463 \ 'line 1: func DoAThing()' ] )
464
465 call RunDbgCmd( buf, 'up', [ 'frame at highest level: 3' ] )
466 call RunDbgCmd( buf, 'backtrace', [
467 \ '>backtrace',
468 \ '->3 function GlobalFunction[1]',
469 \ ' 2 CallAFunction[1]',
470 \ ' 1 SourceAnotherFile[1]',
471 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
472 \ 'line 1: func DoAThing()' ] )
473
474 call RunDbgCmd( buf, 'down' )
475 call RunDbgCmd( buf, 'backtrace', [
476 \ '>backtrace',
477 \ ' 3 function GlobalFunction[1]',
478 \ '->2 CallAFunction[1]',
479 \ ' 1 SourceAnotherFile[1]',
480 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
481 \ 'line 1: func DoAThing()' ] )
482
483 call RunDbgCmd( buf, 'down' )
484 call RunDbgCmd( buf, 'backtrace', [
485 \ '>backtrace',
486 \ ' 3 function GlobalFunction[1]',
487 \ ' 2 CallAFunction[1]',
488 \ '->1 SourceAnotherFile[1]',
489 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
490 \ 'line 1: func DoAThing()' ] )
491
492 call RunDbgCmd( buf, 'down' )
493 call RunDbgCmd( buf, 'backtrace', [
494 \ '>backtrace',
495 \ ' 3 function GlobalFunction[1]',
496 \ ' 2 CallAFunction[1]',
497 \ ' 1 SourceAnotherFile[1]',
498 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
499 \ 'line 1: func DoAThing()' ] )
500
501 call RunDbgCmd( buf, 'down', [ 'frame is zero' ] )
502
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200503 " step until we have another meaninfgul trace
504 call RunDbgCmd(buf, 'step', ['line 5: func File2Function()'])
505 call RunDbgCmd(buf, 'step', ['line 9: call File2Function()'])
506 call RunDbgCmd(buf, 'backtrace', [
507 \ '>backtrace',
508 \ ' 3 function GlobalFunction[1]',
509 \ ' 2 CallAFunction[1]',
510 \ ' 1 SourceAnotherFile[1]',
511 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
512 \ 'line 9: call File2Function()'])
513
514 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
515 call RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"'])
516 call RunDbgCmd(buf, 'backtrace', [
517 \ '>backtrace',
518 \ ' 5 function GlobalFunction[1]',
519 \ ' 4 CallAFunction[1]',
520 \ ' 3 SourceAnotherFile[1]',
521 \ ' 2 script ' .. getcwd() .. '/Xtest2.vim[9]',
522 \ ' 1 function File2Function[1]',
523 \ '->0 DoAThing',
524 \ 'line 1: echo "DoAThing"'])
525
526 " Now, step (back to Xfile1.vim), and call the function _in_ Xfile2.vim
527 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
528 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
529 call RunDbgCmd(buf, 'step', ['line 10: End of sourced file'])
530 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
531 call RunDbgCmd(buf, 'step', ['line 2: call File2Function()'])
532 call RunDbgCmd(buf, 'backtrace', [
533 \ '>backtrace',
534 \ ' 1 function GlobalFunction[1]',
535 \ '->0 CallAFunction',
536 \ 'line 2: call File2Function()'])
537
538 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
539 call RunDbgCmd(buf, 'backtrace', [
540 \ '>backtrace',
541 \ ' 2 function GlobalFunction[1]',
542 \ ' 1 CallAFunction[2]',
543 \ '->0 File2Function',
544 \ 'line 1: call DoAThing()'])
545
546 call StopVimInTerminal(buf)
547 call delete('Xtest1.vim')
548 call delete('Xtest2.vim')
549endfunc
550
551func Test_Backtrace_Autocmd()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200552 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200553 let file1 =<< trim END
554 func SourceAnotherFile()
555 source Xtest2.vim
556 endfunc
557
558 func CallAFunction()
559 call SourceAnotherFile()
560 call File2Function()
561 endfunc
562
563 func GlobalFunction()
564 call CallAFunction()
565 endfunc
566
567 au User TestGlobalFunction :call GlobalFunction() | echo "Done"
568 END
569 call writefile(file1, 'Xtest1.vim')
570
571 let file2 =<< trim END
572 func DoAThing()
573 echo "DoAThing"
574 endfunc
575
576 func File2Function()
577 call DoAThing()
578 endfunc
579
580 call File2Function()
581 END
582 call writefile(file2, 'Xtest2.vim')
583
584 let buf = RunVimInTerminal('-S Xtest1.vim', {})
585
586 call RunDbgCmd(buf,
587 \ ':debug doautocmd User TestGlobalFunction',
588 \ ['cmd: doautocmd User TestGlobalFunction'])
589 call RunDbgCmd(buf, 'step', ['cmd: call GlobalFunction() | echo "Done"'])
590
591 " At this point the ontly thing in the stack is the autocommand
592 call RunDbgCmd(buf, 'backtrace', [
593 \ '>backtrace',
594 \ '->0 User Autocommands for "TestGlobalFunction"',
595 \ 'cmd: call GlobalFunction() | echo "Done"'])
596
597 " And now we're back into the call stack
598 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
599 call RunDbgCmd(buf, 'backtrace', [
600 \ '>backtrace',
601 \ ' 1 User Autocommands for "TestGlobalFunction"',
602 \ '->0 function GlobalFunction',
603 \ 'line 1: call CallAFunction()'])
604
605 call RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()'])
606 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
607
608 call RunDbgCmd(buf, 'backtrace', [
609 \ '>backtrace',
610 \ ' 3 User Autocommands for "TestGlobalFunction"',
611 \ ' 2 function GlobalFunction[1]',
612 \ ' 1 CallAFunction[1]',
613 \ '->0 SourceAnotherFile',
614 \ 'line 1: source Xtest2.vim'])
615
616 " Step into the 'source' command. Note that we print the full trace all the
617 " way though the source command.
618 call RunDbgCmd(buf, 'step', ['line 1: func DoAThing()'])
619 call RunDbgCmd(buf, 'backtrace', [
620 \ '>backtrace',
621 \ ' 4 User Autocommands for "TestGlobalFunction"',
622 \ ' 3 function GlobalFunction[1]',
623 \ ' 2 CallAFunction[1]',
624 \ ' 1 SourceAnotherFile[1]',
625 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
626 \ 'line 1: func DoAThing()'])
627
Bram Moolenaarc63b72b2020-08-22 16:04:52 +0200628 call RunDbgCmd( buf, 'up' )
629 call RunDbgCmd( buf, 'backtrace', [
630 \ '>backtrace',
631 \ ' 4 User Autocommands for "TestGlobalFunction"',
632 \ ' 3 function GlobalFunction[1]',
633 \ ' 2 CallAFunction[1]',
634 \ '->1 SourceAnotherFile[1]',
635 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
636 \ 'line 1: func DoAThing()' ] )
637
638 call RunDbgCmd( buf, 'up' )
639 call RunDbgCmd( buf, 'backtrace', [
640 \ '>backtrace',
641 \ ' 4 User Autocommands for "TestGlobalFunction"',
642 \ ' 3 function GlobalFunction[1]',
643 \ '->2 CallAFunction[1]',
644 \ ' 1 SourceAnotherFile[1]',
645 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
646 \ 'line 1: func DoAThing()' ] )
647
648 call RunDbgCmd( buf, 'up' )
649 call RunDbgCmd( buf, 'backtrace', [
650 \ '>backtrace',
651 \ ' 4 User Autocommands for "TestGlobalFunction"',
652 \ '->3 function GlobalFunction[1]',
653 \ ' 2 CallAFunction[1]',
654 \ ' 1 SourceAnotherFile[1]',
655 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
656 \ 'line 1: func DoAThing()' ] )
657
658 call RunDbgCmd( buf, 'up' )
659 call RunDbgCmd( buf, 'backtrace', [
660 \ '>backtrace',
661 \ '->4 User Autocommands for "TestGlobalFunction"',
662 \ ' 3 function GlobalFunction[1]',
663 \ ' 2 CallAFunction[1]',
664 \ ' 1 SourceAnotherFile[1]',
665 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
666 \ 'line 1: func DoAThing()' ] )
667
668 call RunDbgCmd( buf, 'up', [ 'frame at highest level: 4' ] )
669 call RunDbgCmd( buf, 'backtrace', [
670 \ '>backtrace',
671 \ '->4 User Autocommands for "TestGlobalFunction"',
672 \ ' 3 function GlobalFunction[1]',
673 \ ' 2 CallAFunction[1]',
674 \ ' 1 SourceAnotherFile[1]',
675 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
676 \ 'line 1: func DoAThing()' ] )
677
678 call RunDbgCmd( buf, 'down' )
679 call RunDbgCmd( buf, 'backtrace', [
680 \ '>backtrace',
681 \ ' 4 User Autocommands for "TestGlobalFunction"',
682 \ '->3 function GlobalFunction[1]',
683 \ ' 2 CallAFunction[1]',
684 \ ' 1 SourceAnotherFile[1]',
685 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
686 \ 'line 1: func DoAThing()' ] )
687
688
689 call RunDbgCmd( buf, 'down' )
690 call RunDbgCmd( buf, 'backtrace', [
691 \ '>backtrace',
692 \ ' 4 User Autocommands for "TestGlobalFunction"',
693 \ ' 3 function GlobalFunction[1]',
694 \ '->2 CallAFunction[1]',
695 \ ' 1 SourceAnotherFile[1]',
696 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
697 \ 'line 1: func DoAThing()' ] )
698
699 call RunDbgCmd( buf, 'down' )
700 call RunDbgCmd( buf, 'backtrace', [
701 \ '>backtrace',
702 \ ' 4 User Autocommands for "TestGlobalFunction"',
703 \ ' 3 function GlobalFunction[1]',
704 \ ' 2 CallAFunction[1]',
705 \ '->1 SourceAnotherFile[1]',
706 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
707 \ 'line 1: func DoAThing()' ] )
708
709 call RunDbgCmd( buf, 'down' )
710 call RunDbgCmd( buf, 'backtrace', [
711 \ '>backtrace',
712 \ ' 4 User Autocommands for "TestGlobalFunction"',
713 \ ' 3 function GlobalFunction[1]',
714 \ ' 2 CallAFunction[1]',
715 \ ' 1 SourceAnotherFile[1]',
716 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
717 \ 'line 1: func DoAThing()' ] )
718
719 call RunDbgCmd( buf, 'down', [ 'frame is zero' ] )
720
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200721 " step until we have another meaninfgul trace
722 call RunDbgCmd(buf, 'step', ['line 5: func File2Function()'])
723 call RunDbgCmd(buf, 'step', ['line 9: call File2Function()'])
724 call RunDbgCmd(buf, 'backtrace', [
725 \ '>backtrace',
726 \ ' 4 User Autocommands for "TestGlobalFunction"',
727 \ ' 3 function GlobalFunction[1]',
728 \ ' 2 CallAFunction[1]',
729 \ ' 1 SourceAnotherFile[1]',
730 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
731 \ 'line 9: call File2Function()'])
732
733 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
734 call RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"'])
735 call RunDbgCmd(buf, 'backtrace', [
736 \ '>backtrace',
737 \ ' 6 User Autocommands for "TestGlobalFunction"',
738 \ ' 5 function GlobalFunction[1]',
739 \ ' 4 CallAFunction[1]',
740 \ ' 3 SourceAnotherFile[1]',
741 \ ' 2 script ' .. getcwd() .. '/Xtest2.vim[9]',
742 \ ' 1 function File2Function[1]',
743 \ '->0 DoAThing',
744 \ 'line 1: echo "DoAThing"'])
745
746 " Now, step (back to Xfile1.vim), and call the function _in_ Xfile2.vim
747 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
748 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
749 call RunDbgCmd(buf, 'step', ['line 10: End of sourced file'])
750 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
751 call RunDbgCmd(buf, 'step', ['line 2: call File2Function()'])
752 call RunDbgCmd(buf, 'backtrace', [
753 \ '>backtrace',
754 \ ' 2 User Autocommands for "TestGlobalFunction"',
755 \ ' 1 function GlobalFunction[1]',
756 \ '->0 CallAFunction',
757 \ 'line 2: call File2Function()'])
758
759 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
760 call RunDbgCmd(buf, 'backtrace', [
761 \ '>backtrace',
762 \ ' 3 User Autocommands for "TestGlobalFunction"',
763 \ ' 2 function GlobalFunction[1]',
764 \ ' 1 CallAFunction[2]',
765 \ '->0 File2Function',
766 \ 'line 1: call DoAThing()'])
767
768
769 " Now unwind so that we get back to the original autocommand (and the second
770 " cmd echo "Done")
771 call RunDbgCmd(buf, 'finish', ['line 1: End of function'])
772 call RunDbgCmd(buf, 'backtrace', [
773 \ '>backtrace',
774 \ ' 3 User Autocommands for "TestGlobalFunction"',
775 \ ' 2 function GlobalFunction[1]',
776 \ ' 1 CallAFunction[2]',
777 \ '->0 File2Function',
778 \ 'line 1: End of function'])
779
780 call RunDbgCmd(buf, 'finish', ['line 2: End of function'])
781 call RunDbgCmd(buf, 'backtrace', [
782 \ '>backtrace',
783 \ ' 2 User Autocommands for "TestGlobalFunction"',
784 \ ' 1 function GlobalFunction[1]',
785 \ '->0 CallAFunction',
786 \ 'line 2: End of function'])
787
788 call RunDbgCmd(buf, 'finish', ['line 1: End of function'])
789 call RunDbgCmd(buf, 'backtrace', [
790 \ '>backtrace',
791 \ ' 1 User Autocommands for "TestGlobalFunction"',
792 \ '->0 function GlobalFunction',
793 \ 'line 1: End of function'])
794
795 call RunDbgCmd(buf, 'step', ['cmd: echo "Done"'])
796 call RunDbgCmd(buf, 'backtrace', [
797 \ '>backtrace',
798 \ '->0 User Autocommands for "TestGlobalFunction"',
799 \ 'cmd: echo "Done"'])
800
801 call StopVimInTerminal(buf)
802 call delete('Xtest1.vim')
803 call delete('Xtest2.vim')
804endfunc
805
806func Test_Backtrace_CmdLine()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200807 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200808 let file1 =<< trim END
809 func SourceAnotherFile()
810 source Xtest2.vim
811 endfunc
812
813 func CallAFunction()
814 call SourceAnotherFile()
815 call File2Function()
816 endfunc
817
818 func GlobalFunction()
819 call CallAFunction()
820 endfunc
821
822 au User TestGlobalFunction :call GlobalFunction() | echo "Done"
823 END
824 call writefile(file1, 'Xtest1.vim')
825
826 let file2 =<< trim END
827 func DoAThing()
828 echo "DoAThing"
829 endfunc
830
831 func File2Function()
832 call DoAThing()
833 endfunc
834
835 call File2Function()
836 END
837 call writefile(file2, 'Xtest2.vim')
838
839 let buf = RunVimInTerminal(
840 \ '-S Xtest1.vim -c "debug call GlobalFunction()"',
841 \ {'wait_for_ruler': 0})
842
Bram Moolenaar18dc3552020-11-22 14:24:00 +0100843 " Need to wait for the vim-in-terminal to be ready.
844 " With valgrind this can take quite long.
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200845 call CheckDbgOutput(buf, ['command line',
Bram Moolenaar18dc3552020-11-22 14:24:00 +0100846 \ 'cmd: call GlobalFunction()'], #{msec: 5000})
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200847
848 " At this point the ontly thing in the stack is the cmdline
849 call RunDbgCmd(buf, 'backtrace', [
850 \ '>backtrace',
851 \ '->0 command line',
852 \ 'cmd: call GlobalFunction()'])
853
854 " And now we're back into the call stack
855 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
856 call RunDbgCmd(buf, 'backtrace', [
857 \ '>backtrace',
858 \ ' 1 command line',
859 \ '->0 function GlobalFunction',
860 \ 'line 1: call CallAFunction()'])
861
862 call StopVimInTerminal(buf)
863 call delete('Xtest1.vim')
864 call delete('Xtest2.vim')
865endfunc
866
867func Test_Backtrace_DefFunction()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200868 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200869 let file1 =<< trim END
870 vim9script
871 import File2Function from './Xtest2.vim'
872
873 def SourceAnotherFile()
874 source Xtest2.vim
875 enddef
876
877 def CallAFunction()
878 SourceAnotherFile()
879 File2Function()
880 enddef
881
882 def g:GlobalFunction()
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +0200883 var some = "some var"
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200884 CallAFunction()
885 enddef
886
887 defcompile
888 END
889 call writefile(file1, 'Xtest1.vim')
890
891 let file2 =<< trim END
892 vim9script
893
894 def DoAThing(): number
Bram Moolenaar1bdae402020-10-03 14:14:56 +0200895 var a = 100 * 2
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200896 a += 3
897 return a
898 enddef
899
900 export def File2Function()
901 DoAThing()
902 enddef
903
904 defcompile
905 File2Function()
906 END
907 call writefile(file2, 'Xtest2.vim')
908
909 let buf = RunVimInTerminal('-S Xtest1.vim', {})
910
911 call RunDbgCmd(buf,
912 \ ':debug call GlobalFunction()',
913 \ ['cmd: call GlobalFunction()'])
914
Bram Moolenaar4cea5362021-06-16 22:24:40 +0200915 call RunDbgCmd(buf, 'step', ['line 1: var some = "some var"'])
916 call RunDbgCmd(buf, 'step', ['line 2: CallAFunction()'])
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +0200917 call RunDbgCmd(buf, 'echo some', ['some var'])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200918
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200919 call RunDbgCmd(buf, 'backtrace', [
920 \ '\V>backtrace',
Bram Moolenaare99d4222021-06-13 14:01:26 +0200921 \ '\V->0 function GlobalFunction',
Bram Moolenaar4cea5362021-06-16 22:24:40 +0200922 \ '\Vline 2: CallAFunction()',
Bram Moolenaare99d4222021-06-13 14:01:26 +0200923 \ ],
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200924 \ #{match: 'pattern'})
925
Bram Moolenaar4cea5362021-06-16 22:24:40 +0200926 call RunDbgCmd(buf, 'step', ['line 1: SourceAnotherFile()'])
927 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +0200928 " Repeated line, because we fist are in the compiled function before the
929 " EXEC and then in do_cmdline() before the :source command.
Bram Moolenaare99d4222021-06-13 14:01:26 +0200930 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200931 call RunDbgCmd(buf, 'step', ['line 1: vim9script'])
932 call RunDbgCmd(buf, 'step', ['line 3: def DoAThing(): number'])
933 call RunDbgCmd(buf, 'step', ['line 9: export def File2Function()'])
934 call RunDbgCmd(buf, 'step', ['line 9: def File2Function()'])
935 call RunDbgCmd(buf, 'step', ['line 13: defcompile'])
936 call RunDbgCmd(buf, 'step', ['line 14: File2Function()'])
937 call RunDbgCmd(buf, 'backtrace', [
938 \ '\V>backtrace',
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +0200939 \ '\V 3 function GlobalFunction[2]',
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200940 \ '\V 2 <SNR>\.\*_CallAFunction[1]',
941 \ '\V 1 <SNR>\.\*_SourceAnotherFile[1]',
942 \ '\V->0 script ' .. getcwd() .. '/Xtest2.vim',
943 \ '\Vline 14: File2Function()'],
944 \ #{match: 'pattern'})
945
946 " Don't step into compiled functions...
Bram Moolenaare99d4222021-06-13 14:01:26 +0200947 call RunDbgCmd(buf, 'next', ['line 15: End of sourced file'])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200948 call RunDbgCmd(buf, 'backtrace', [
949 \ '\V>backtrace',
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +0200950 \ '\V 3 function GlobalFunction[2]',
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200951 \ '\V 2 <SNR>\.\*_CallAFunction[1]',
952 \ '\V 1 <SNR>\.\*_SourceAnotherFile[1]',
953 \ '\V->0 script ' .. getcwd() .. '/Xtest2.vim',
954 \ '\Vline 15: End of sourced file'],
955 \ #{match: 'pattern'})
956
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200957 call StopVimInTerminal(buf)
958 call delete('Xtest1.vim')
959 call delete('Xtest2.vim')
960endfunc
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200961
Bram Moolenaar26a44842021-09-02 18:49:06 +0200962func Test_DefFunction_expr()
963 CheckCWD
964 let file3 =<< trim END
965 vim9script
966 g:someVar = "foo"
967 def g:ChangeVar()
968 g:someVar = "bar"
969 echo "changed"
970 enddef
971 defcompile
972 END
973 call writefile(file3, 'Xtest3.vim')
974 let buf = RunVimInTerminal('-S Xtest3.vim', {})
975
976 call RunDbgCmd(buf, ':breakadd expr g:someVar')
977 call RunDbgCmd(buf, ':call g:ChangeVar()', ['Oldval = "''foo''"', 'Newval = "''bar''"', 'function ChangeVar', 'line 2: echo "changed"'])
978
979 call StopVimInTerminal(buf)
980 call delete('Xtest3.vim')
981endfunc
982
Bram Moolenaar17d868b2021-06-27 16:29:53 +0200983func Test_debug_def_and_legacy_function()
Bram Moolenaar4f8f5422021-06-20 19:28:14 +0200984 CheckCWD
985 let file =<< trim END
986 vim9script
987 def g:SomeFunc()
988 echo "here"
989 echo "and"
990 echo "there"
Bram Moolenaar2ac4b252021-06-20 20:09:42 +0200991 breakadd func 2 LocalFunc
992 LocalFunc()
Bram Moolenaar4f8f5422021-06-20 19:28:14 +0200993 enddef
Bram Moolenaar2ac4b252021-06-20 20:09:42 +0200994
995 def LocalFunc()
996 echo "first"
997 echo "second"
Bram Moolenaar8cec9272021-06-23 20:20:53 +0200998 breakadd func LegacyFunc
Bram Moolenaar2ac4b252021-06-20 20:09:42 +0200999 LegacyFunc()
1000 enddef
1001
1002 func LegacyFunc()
1003 echo "legone"
1004 echo "legtwo"
1005 endfunc
1006
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001007 breakadd func 2 g:SomeFunc
1008 END
1009 call writefile(file, 'XtestDebug.vim')
1010
1011 let buf = RunVimInTerminal('-S XtestDebug.vim', {})
1012
1013 call RunDbgCmd(buf,':call SomeFunc()', ['line 2: echo "and"'])
1014 call RunDbgCmd(buf,'next', ['line 3: echo "there"'])
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001015 call RunDbgCmd(buf,'next', ['line 4: breakadd func 2 LocalFunc'])
1016
1017 " continue, next breakpoint is in LocalFunc()
1018 call RunDbgCmd(buf,'cont', ['line 2: echo "second"'])
1019
1020 " continue, next breakpoint is in LegacyFunc()
1021 call RunDbgCmd(buf,'cont', ['line 1: echo "legone"'])
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001022
1023 call RunDbgCmd(buf, 'cont')
1024
1025 call StopVimInTerminal(buf)
Dominique Pelle6c72fd52021-07-04 12:30:06 +02001026 call delete('XtestDebug.vim')
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001027endfunc
1028
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001029func Test_debug_def_function()
1030 CheckCWD
1031 let file =<< trim END
1032 vim9script
1033 def g:Func()
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001034 var n: number
1035 def Closure(): number
1036 return n + 3
1037 enddef
1038 n += Closure()
1039 echo 'result: ' .. n
1040 enddef
1041
1042 def g:FuncWithArgs(text: string, nr: number, ...items: list<number>)
1043 echo text .. nr
1044 for it in items
1045 echo it
1046 endfor
1047 echo "done"
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001048 enddef
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001049
1050 def g:FuncWithDict()
1051 var d = {
1052 a: 1,
1053 b: 2,
1054 }
Bram Moolenaar59b50c32021-06-17 22:27:48 +02001055 # comment
1056 def Inner()
Bram Moolenaar31e21762021-07-10 20:43:59 +02001057 eval 1 + 2
Bram Moolenaar59b50c32021-06-17 22:27:48 +02001058 enddef
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001059 enddef
Bram Moolenaar303215d2021-07-07 20:10:43 +02001060
Bram Moolenaar8cec9272021-06-23 20:20:53 +02001061 def g:FuncComment()
1062 # comment
1063 echo "first"
1064 .. "one"
1065 # comment
1066 echo "second"
1067 enddef
Bram Moolenaar303215d2021-07-07 20:10:43 +02001068
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001069 def g:FuncForLoop()
Bram Moolenaar31e21762021-07-10 20:43:59 +02001070 eval 1 + 2
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001071 for i in [11, 22, 33]
Bram Moolenaar31e21762021-07-10 20:43:59 +02001072 eval i + 2
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001073 endfor
1074 echo "done"
1075 enddef
Bram Moolenaar303215d2021-07-07 20:10:43 +02001076
1077 def g:FuncWithSplitLine()
Bram Moolenaar31e21762021-07-10 20:43:59 +02001078 eval 1 + 2
1079 | eval 2 + 3
Bram Moolenaar303215d2021-07-07 20:10:43 +02001080 enddef
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001081 END
1082 call writefile(file, 'Xtest.vim')
1083
1084 let buf = RunVimInTerminal('-S Xtest.vim', {})
1085
1086 call RunDbgCmd(buf,
1087 \ ':debug call Func()',
1088 \ ['cmd: call Func()'])
1089 call RunDbgCmd(buf, 'next', ['result: 3'])
1090 call term_sendkeys(buf, "\r")
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001091 call RunDbgCmd(buf, 'cont')
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001092
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001093 call RunDbgCmd(buf,
1094 \ ':debug call FuncWithArgs("asdf", 42, 1, 2, 3)',
1095 \ ['cmd: call FuncWithArgs("asdf", 42, 1, 2, 3)'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001096 call RunDbgCmd(buf, 'step', ['line 1: echo text .. nr'])
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001097 call RunDbgCmd(buf, 'echo text', ['asdf'])
1098 call RunDbgCmd(buf, 'echo nr', ['42'])
1099 call RunDbgCmd(buf, 'echo items', ['[1, 2, 3]'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001100 call RunDbgCmd(buf, 'step', ['asdf42', 'function FuncWithArgs', 'line 2: for it in items'])
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001101 call RunDbgCmd(buf, 'echo it', ['1'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001102 call RunDbgCmd(buf, 'step', ['line 3: echo it'])
1103 call RunDbgCmd(buf, 'step', ['1', 'function FuncWithArgs', 'line 4: endfor'])
1104 call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001105 call RunDbgCmd(buf, 'echo it', ['2'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001106 call RunDbgCmd(buf, 'step', ['line 3: echo it'])
1107 call RunDbgCmd(buf, 'step', ['2', 'function FuncWithArgs', 'line 4: endfor'])
1108 call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001109 call RunDbgCmd(buf, 'echo it', ['3'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001110 call RunDbgCmd(buf, 'step', ['line 3: echo it'])
1111 call RunDbgCmd(buf, 'step', ['3', 'function FuncWithArgs', 'line 4: endfor'])
1112 call RunDbgCmd(buf, 'step', ['line 5: echo "done"'])
1113 call RunDbgCmd(buf, 'cont')
1114
1115 call RunDbgCmd(buf,
1116 \ ':debug call FuncWithDict()',
1117 \ ['cmd: call FuncWithDict()'])
1118 call RunDbgCmd(buf, 'step', ['line 1: var d = { a: 1, b: 2, }'])
Bram Moolenaar59b50c32021-06-17 22:27:48 +02001119 call RunDbgCmd(buf, 'step', ['line 6: def Inner()'])
Bram Moolenaar8cec9272021-06-23 20:20:53 +02001120 call RunDbgCmd(buf, 'cont')
1121
1122 call RunDbgCmd(buf, ':breakadd func 1 FuncComment')
1123 call RunDbgCmd(buf, ':call FuncComment()', ['function FuncComment', 'line 2: echo "first" .. "one"'])
1124 call RunDbgCmd(buf, ':breakadd func 3 FuncComment')
1125 call RunDbgCmd(buf, 'cont', ['function FuncComment', 'line 5: echo "second"'])
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001126 call RunDbgCmd(buf, 'cont')
1127
1128 call RunDbgCmd(buf, ':breakadd func 2 FuncForLoop')
1129 call RunDbgCmd(buf, ':call FuncForLoop()', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]'])
1130 call RunDbgCmd(buf, 'echo i', ['11'])
Bram Moolenaar31e21762021-07-10 20:43:59 +02001131 call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 3: eval i + 2'])
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001132 call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 4: endfor'])
1133 call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]'])
1134 call RunDbgCmd(buf, 'echo i', ['22'])
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001135
Bram Moolenaar303215d2021-07-07 20:10:43 +02001136 call RunDbgCmd(buf, 'breakdel *')
1137 call RunDbgCmd(buf, 'cont')
1138
1139 call RunDbgCmd(buf, ':breakadd func FuncWithSplitLine')
Bram Moolenaar31e21762021-07-10 20:43:59 +02001140 call RunDbgCmd(buf, ':call FuncWithSplitLine()', ['function FuncWithSplitLine', 'line 1: eval 1 + 2 | eval 2 + 3'])
Bram Moolenaar303215d2021-07-07 20:10:43 +02001141
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001142 call RunDbgCmd(buf, 'cont')
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001143 call StopVimInTerminal(buf)
1144 call delete('Xtest.vim')
1145endfunc
1146
Bram Moolenaar17d868b2021-06-27 16:29:53 +02001147func Test_debug_def_function_with_lambda()
1148 CheckCWD
1149 let lines =<< trim END
1150 vim9script
1151 def g:Func()
1152 var s = 'a'
1153 ['b']->map((_, v) => s)
1154 echo "done"
1155 enddef
1156 breakadd func 2 g:Func
1157 END
1158 call writefile(lines, 'XtestLambda.vim')
1159
1160 let buf = RunVimInTerminal('-S XtestLambda.vim', {})
1161
1162 call RunDbgCmd(buf,
1163 \ ':call g:Func()',
1164 \ ['function Func', 'line 2: [''b'']->map((_, v) => s)'])
1165 call RunDbgCmd(buf,
1166 \ 'next',
1167 \ ['function Func', 'line 3: echo "done"'])
1168
1169 call RunDbgCmd(buf, 'cont')
1170 call StopVimInTerminal(buf)
1171 call delete('XtestLambda.vim')
1172endfunc
1173
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001174func Test_debug_backtrace_level()
1175 CheckCWD
1176 let lines =<< trim END
1177 let s:file1_var = 'file1'
1178 let g:global_var = 'global'
1179
1180 func s:File1Func( arg )
1181 let s:file1_var .= a:arg
1182 let local_var = s:file1_var .. ' test1'
1183 let g:global_var .= local_var
1184 source Xtest2.vim
1185 endfunc
1186
1187 call s:File1Func( 'arg1' )
1188 END
1189 call writefile(lines, 'Xtest1.vim')
1190
1191 let lines =<< trim END
1192 let s:file2_var = 'file2'
1193
1194 func s:File2Func( arg )
1195 let s:file2_var .= a:arg
1196 let local_var = s:file2_var .. ' test2'
1197 let g:global_var .= local_var
1198 endfunc
1199
1200 call s:File2Func( 'arg2' )
1201 END
1202 call writefile(lines, 'Xtest2.vim')
1203
1204 let file1 = getcwd() .. '/Xtest1.vim'
1205 let file2 = getcwd() .. '/Xtest2.vim'
1206
1207 " set a breakpoint and source file1.vim
1208 let buf = RunVimInTerminal(
1209 \ '-c "breakadd file 1 Xtest1.vim" -S Xtest1.vim',
Bram Moolenaar18dc3552020-11-22 14:24:00 +01001210 \ #{wait_for_ruler: 0})
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001211
1212 call CheckDbgOutput(buf, [
1213 \ 'Breakpoint in "' .. file1 .. '" line 1',
1214 \ 'Entering Debug mode. Type "cont" to continue.',
1215 \ 'command line..script ' .. file1,
1216 \ 'line 1: let s:file1_var = ''file1'''
Bram Moolenaar18dc3552020-11-22 14:24:00 +01001217 \ ], #{msec: 5000})
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001218
Bram Moolenaar8e7d6222020-12-18 19:49:56 +01001219 " step through the initial declarations
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001220 call RunDbgCmd(buf, 'step', [ 'line 2: let g:global_var = ''global''' ] )
1221 call RunDbgCmd(buf, 'step', [ 'line 4: func s:File1Func( arg )' ] )
1222 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1223 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1224 call RunDbgCmd(buf, 'echo global_var', [ 'global' ] )
1225
1226 " step in to the first function
1227 call RunDbgCmd(buf, 'step', [ 'line 11: call s:File1Func( ''arg1'' )' ] )
1228 call RunDbgCmd(buf, 'step', [ 'line 1: let s:file1_var .= a:arg' ] )
1229 call RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] )
1230 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1231 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1232 call RunDbgCmd(buf,
1233 \'echo global_var',
1234 \[ 'E121: Undefined variable: global_var' ] )
1235 call RunDbgCmd(buf,
1236 \'echo local_var',
1237 \[ 'E121: Undefined variable: local_var' ] )
1238 call RunDbgCmd(buf,
1239 \'echo l:local_var',
1240 \[ 'E121: Undefined variable: l:local_var' ] )
1241
1242 " backtrace up
1243 call RunDbgCmd(buf, 'backtrace', [
1244 \ '\V>backtrace',
1245 \ '\V 2 command line',
1246 \ '\V 1 script ' .. file1 .. '[11]',
1247 \ '\V->0 function <SNR>\.\*_File1Func',
1248 \ '\Vline 1: let s:file1_var .= a:arg',
1249 \ ],
1250 \ #{ match: 'pattern' } )
1251 call RunDbgCmd(buf, 'up', [ '>up' ] )
1252
1253 call RunDbgCmd(buf, 'backtrace', [
1254 \ '\V>backtrace',
1255 \ '\V 2 command line',
1256 \ '\V->1 script ' .. file1 .. '[11]',
1257 \ '\V 0 function <SNR>\.\*_File1Func',
1258 \ '\Vline 1: let s:file1_var .= a:arg',
1259 \ ],
1260 \ #{ match: 'pattern' } )
1261
1262 " Expression evaluation in the script frame (not the function frame)
1263 " FIXME: Unexpected in this scope (a: should not be visibnle)
1264 call RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] )
1265 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1266 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1267 " FIXME: Unexpected in this scope (global should be found)
1268 call RunDbgCmd(buf,
1269 \'echo global_var',
1270 \[ 'E121: Undefined variable: global_var' ] )
1271 call RunDbgCmd(buf,
1272 \'echo local_var',
1273 \[ 'E121: Undefined variable: local_var' ] )
1274 call RunDbgCmd(buf,
1275 \'echo l:local_var',
1276 \[ 'E121: Undefined variable: l:local_var' ] )
1277
1278
1279 " step while backtraced jumps to the latest frame
1280 call RunDbgCmd(buf, 'step', [
1281 \ 'line 2: let local_var = s:file1_var .. '' test1''' ] )
1282 call RunDbgCmd(buf, 'backtrace', [
1283 \ '\V>backtrace',
1284 \ '\V 2 command line',
1285 \ '\V 1 script ' .. file1 .. '[11]',
1286 \ '\V->0 function <SNR>\.\*_File1Func',
1287 \ '\Vline 2: let local_var = s:file1_var .. '' test1''',
1288 \ ],
1289 \ #{ match: 'pattern' } )
1290
1291 call RunDbgCmd(buf, 'step', [ 'line 3: let g:global_var .= local_var' ] )
1292 call RunDbgCmd(buf, 'echo local_var', [ 'file1arg1 test1' ] )
1293 call RunDbgCmd(buf, 'echo l:local_var', [ 'file1arg1 test1' ] )
1294
1295 call RunDbgCmd(buf, 'step', [ 'line 4: source Xtest2.vim' ] )
1296 call RunDbgCmd(buf, 'step', [ 'line 1: let s:file2_var = ''file2''' ] )
1297 call RunDbgCmd(buf, 'backtrace', [
1298 \ '\V>backtrace',
1299 \ '\V 3 command line',
1300 \ '\V 2 script ' .. file1 .. '[11]',
1301 \ '\V 1 function <SNR>\.\*_File1Func[4]',
1302 \ '\V->0 script ' .. file2,
1303 \ '\Vline 1: let s:file2_var = ''file2''',
1304 \ ],
1305 \ #{ match: 'pattern' } )
1306
1307 " Expression evaluation in the script frame file2 (not the function frame)
1308 call RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] )
1309 call RunDbgCmd(buf,
1310 \ 'echo s:file1_var',
1311 \ [ 'E121: Undefined variable: s:file1_var' ] )
1312 call RunDbgCmd(buf, 'echo g:global_var', [ 'globalfile1arg1 test1' ] )
1313 call RunDbgCmd(buf, 'echo global_var', [ 'globalfile1arg1 test1' ] )
1314 call RunDbgCmd(buf,
1315 \'echo local_var',
1316 \[ 'E121: Undefined variable: local_var' ] )
1317 call RunDbgCmd(buf,
1318 \'echo l:local_var',
1319 \[ 'E121: Undefined variable: l:local_var' ] )
1320 call RunDbgCmd(buf,
1321 \ 'echo s:file2_var',
1322 \ [ 'E121: Undefined variable: s:file2_var' ] )
1323
1324 call RunDbgCmd(buf, 'step', [ 'line 3: func s:File2Func( arg )' ] )
1325 call RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] )
1326
1327 " Up the stack to the other script context
1328 call RunDbgCmd(buf, 'up')
1329 call RunDbgCmd(buf, 'backtrace', [
1330 \ '\V>backtrace',
1331 \ '\V 3 command line',
1332 \ '\V 2 script ' .. file1 .. '[11]',
1333 \ '\V->1 function <SNR>\.\*_File1Func[4]',
1334 \ '\V 0 script ' .. file2,
1335 \ '\Vline 3: func s:File2Func( arg )',
1336 \ ],
1337 \ #{ match: 'pattern' } )
1338 " FIXME: Unexpected. Should see the a: and l: dicts from File1Func
1339 call RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] )
1340 call RunDbgCmd(buf,
1341 \ 'echo l:local_var',
1342 \ [ 'E121: Undefined variable: l:local_var' ] )
1343
1344 call RunDbgCmd(buf, 'up')
1345 call RunDbgCmd(buf, 'backtrace', [
1346 \ '\V>backtrace',
1347 \ '\V 3 command line',
1348 \ '\V->2 script ' .. file1 .. '[11]',
1349 \ '\V 1 function <SNR>\.\*_File1Func[4]',
1350 \ '\V 0 script ' .. file2,
1351 \ '\Vline 3: func s:File2Func( arg )',
1352 \ ],
1353 \ #{ match: 'pattern' } )
1354
1355 " FIXME: Unexpected (wrong script vars are used)
1356 call RunDbgCmd(buf,
1357 \ 'echo s:file1_var',
1358 \ [ 'E121: Undefined variable: s:file1_var' ] )
1359 call RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] )
1360
Bram Moolenaare99d4222021-06-13 14:01:26 +02001361 call RunDbgCmd(buf, 'cont')
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001362 call StopVimInTerminal(buf)
1363 call delete('Xtest1.vim')
1364 call delete('Xtest2.vim')
1365endfunc
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001366
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001367" Test for setting a breakpoint on a :endif where the :if condition is false
1368" and then quit the script. This should generate an interrupt.
1369func Test_breakpt_endif_intr()
1370 func F()
1371 let g:Xpath ..= 'a'
1372 if v:false
1373 let g:Xpath ..= 'b'
1374 endif
1375 invalid_command
1376 endfunc
1377
1378 let g:Xpath = ''
1379 breakadd func 4 F
1380 try
1381 let caught_intr = 0
1382 debuggreedy
1383 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001384 catch /^Vim:Interrupt$/
1385 call assert_match('\.F, line 4', v:throwpoint)
1386 let caught_intr = 1
1387 endtry
1388 0debuggreedy
1389 call assert_equal(1, caught_intr)
1390 call assert_equal('a', g:Xpath)
1391 breakdel *
1392 delfunc F
1393endfunc
1394
1395" Test for setting a breakpoint on a :else where the :if condition is false
1396" and then quit the script. This should generate an interrupt.
1397func Test_breakpt_else_intr()
1398 func F()
1399 let g:Xpath ..= 'a'
1400 if v:false
1401 let g:Xpath ..= 'b'
1402 else
1403 invalid_command
1404 endif
1405 invalid_command
1406 endfunc
1407
1408 let g:Xpath = ''
1409 breakadd func 4 F
1410 try
1411 let caught_intr = 0
1412 debuggreedy
1413 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001414 catch /^Vim:Interrupt$/
1415 call assert_match('\.F, line 4', v:throwpoint)
1416 let caught_intr = 1
1417 endtry
1418 0debuggreedy
1419 call assert_equal(1, caught_intr)
1420 call assert_equal('a', g:Xpath)
1421 breakdel *
1422 delfunc F
1423endfunc
1424
1425" Test for setting a breakpoint on a :endwhile where the :while condition is
1426" false and then quit the script. This should generate an interrupt.
1427func Test_breakpt_endwhile_intr()
1428 func F()
1429 let g:Xpath ..= 'a'
1430 while v:false
1431 let g:Xpath ..= 'b'
1432 endwhile
1433 invalid_command
1434 endfunc
1435
1436 let g:Xpath = ''
1437 breakadd func 4 F
1438 try
1439 let caught_intr = 0
1440 debuggreedy
1441 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001442 catch /^Vim:Interrupt$/
1443 call assert_match('\.F, line 4', v:throwpoint)
1444 let caught_intr = 1
1445 endtry
1446 0debuggreedy
1447 call assert_equal(1, caught_intr)
1448 call assert_equal('a', g:Xpath)
1449 breakdel *
1450 delfunc F
1451endfunc
1452
Bram Moolenaar16c62322020-08-13 19:20:04 +02001453" Test for setting a breakpoint on a script local function
1454func Test_breakpt_scriptlocal_func()
1455 let g:Xpath = ''
1456 func s:G()
1457 let g:Xpath ..= 'a'
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001458 endfunc
1459
Bram Moolenaar16c62322020-08-13 19:20:04 +02001460 let funcname = expand("<SID>") .. "G"
1461 exe "breakadd func 1 " .. funcname
1462 debuggreedy
1463 redir => output
1464 call feedkeys(":call " .. funcname .. "()\<CR>c\<CR>", "xt")
1465 redir END
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001466 0debuggreedy
Bram Moolenaar16c62322020-08-13 19:20:04 +02001467 call assert_match('Breakpoint in "' .. funcname .. '" line 1', output)
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001468 call assert_equal('a', g:Xpath)
1469 breakdel *
Bram Moolenaar16c62322020-08-13 19:20:04 +02001470 exe "delfunc " .. funcname
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001471endfunc
1472
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001473" vim: shiftwidth=2 sts=2 expandtab