blob: 2b405d92096f1b1e7dfd98bf23bb5724360febf0 [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
Bram Moolenaar59173412022-09-20 22:01:33 +010084 call writefile(lines, 'XtestDebug.vim', 'D')
Bram Moolenaar113bf062019-04-17 16:54:05 +020085
86 " Start Vim in a terminal
Bram Moolenaar59173412022-09-20 22:01:33 +010087 let buf = RunVimInTerminal('-S XtestDebug.vim', {})
Bram Moolenaar113bf062019-04-17 16:54:05 +020088
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
Bram Moolenaar59173412022-09-20 22:01:33 +0100346 call writefile(lines, 'XdebugBreakadd.vim', 'D')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200347
348 " Start Vim in a terminal
Bram Moolenaar59173412022-09-20 22:01:33 +0100349 let buf = RunVimInTerminal('XdebugBreakadd.vim', {})
350 call RunDbgCmd(buf, ':breakadd file 2 XdebugBreakadd.vim')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200351 call RunDbgCmd(buf, ':4 | breakadd here')
Bram Moolenaar59173412022-09-20 22:01:33 +0100352 call RunDbgCmd(buf, ':source XdebugBreakadd.vim', ['line 2: let var2 = 20'])
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200353 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
Bram Moolenaar16c62322020-08-13 19:20:04 +0200358 %bw!
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200359
Bram Moolenaar16c62322020-08-13 19:20:04 +0200360 call assert_fails('breakadd here', 'E32:')
Bram Moolenaar531be472020-09-23 22:38:05 +0200361 call assert_fails('breakadd file Xtest.vim /\)/', 'E55:')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200362endfunc
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200363
Yegappan Lakshmanan885de442022-04-23 10:51:14 +0100364" Test for expression breakpoint set using ":breakadd expr <expr>"
365func Test_Debugger_breakadd_expr()
James McCoydb7a88d2022-08-03 16:13:27 +0100366 CheckCWD
367
Yegappan Lakshmanan885de442022-04-23 10:51:14 +0100368 let lines =<< trim END
369 let g:Xtest_var += 1
370 END
Bram Moolenaar59173412022-09-20 22:01:33 +0100371 call writefile(lines, 'XdebugBreakExpr.vim', 'D')
Yegappan Lakshmanan885de442022-04-23 10:51:14 +0100372
373 " Start Vim in a terminal
Bram Moolenaar59173412022-09-20 22:01:33 +0100374 let buf = RunVimInTerminal('XdebugBreakExpr.vim', {})
Yegappan Lakshmanan885de442022-04-23 10:51:14 +0100375 call RunDbgCmd(buf, ':let g:Xtest_var = 10')
376 call RunDbgCmd(buf, ':breakadd expr g:Xtest_var')
377 call RunDbgCmd(buf, ':source %')
Bram Moolenaar59173412022-09-20 22:01:33 +0100378 let expected =<< trim eval END
Yegappan Lakshmanan885de442022-04-23 10:51:14 +0100379 Oldval = "10"
380 Newval = "11"
Bram Moolenaar59173412022-09-20 22:01:33 +0100381 {fnamemodify('XdebugBreakExpr.vim', ':p')}
Yegappan Lakshmanan885de442022-04-23 10:51:14 +0100382 line 1: let g:Xtest_var += 1
383 END
384 call RunDbgCmd(buf, ':source %', expected)
385 call RunDbgCmd(buf, 'cont')
Bram Moolenaar59173412022-09-20 22:01:33 +0100386 let expected =<< trim eval END
Yegappan Lakshmanan885de442022-04-23 10:51:14 +0100387 Oldval = "11"
388 Newval = "12"
Bram Moolenaar59173412022-09-20 22:01:33 +0100389 {fnamemodify('XdebugBreakExpr.vim', ':p')}
Yegappan Lakshmanan885de442022-04-23 10:51:14 +0100390 line 1: let g:Xtest_var += 1
391 END
392 call RunDbgCmd(buf, ':source %', expected)
393
394 call StopVimInTerminal(buf)
Yegappan Lakshmanan885de442022-04-23 10:51:14 +0100395endfunc
396
397def Test_Debugger_breakadd_vim9_expr()
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200398 var lines =<< trim END
399 vim9script
400 func g:EarlyFunc()
401 endfunc
402 breakadd expr DoesNotExist()
403 func g:LaterFunc()
404 endfunc
405 breakdel *
406 END
Bram Moolenaar59173412022-09-20 22:01:33 +0100407 writefile(lines, 'XdebugBreak9expr.vim', 'D')
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200408
409 # Start Vim in a terminal
Bram Moolenaar59173412022-09-20 22:01:33 +0100410 var buf = g:RunVimInTerminal('-S XdebugBreak9expr.vim', {wait_for_ruler: 0})
Bram Moolenaare366ed42022-06-19 20:13:56 +0100411 call g:TermWait(buf, g:RunningWithValgrind() ? 1000 : 50)
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200412
413 # Despite the failure the functions are defined
Bram Moolenaar62aec932022-01-29 21:45:34 +0000414 g:RunDbgCmd(buf, ':function g:EarlyFunc',
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200415 ['function EarlyFunc()', 'endfunction'], {match: 'pattern'})
Bram Moolenaar62aec932022-01-29 21:45:34 +0000416 g:RunDbgCmd(buf, ':function g:LaterFunc',
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200417 ['function LaterFunc()', 'endfunction'], {match: 'pattern'})
418
Bram Moolenaar62aec932022-01-29 21:45:34 +0000419 call g:StopVimInTerminal(buf)
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200420enddef
421
Bram Moolenaar112bed02021-11-23 22:16:34 +0000422def Test_Debugger_break_at_return()
423 var lines =<< trim END
424 vim9script
425 def g:GetNum(): number
426 return 1
427 + 2
428 + 3
429 enddef
430 breakadd func GetNum
431 END
Bram Moolenaar59173412022-09-20 22:01:33 +0100432 writefile(lines, 'XdebugBreakRet.vim', 'D')
Bram Moolenaar112bed02021-11-23 22:16:34 +0000433
434 # Start Vim in a terminal
Bram Moolenaar59173412022-09-20 22:01:33 +0100435 var buf = g:RunVimInTerminal('-S XdebugBreakRet.vim', {wait_for_ruler: 0})
Bram Moolenaare366ed42022-06-19 20:13:56 +0100436 call g:TermWait(buf, g:RunningWithValgrind() ? 1000 : 50)
Bram Moolenaar112bed02021-11-23 22:16:34 +0000437
Bram Moolenaar62aec932022-01-29 21:45:34 +0000438 g:RunDbgCmd(buf, ':call GetNum()',
Bram Moolenaar112bed02021-11-23 22:16:34 +0000439 ['line 1: return 1 + 2 + 3'], {match: 'pattern'})
440
Bram Moolenaar62aec932022-01-29 21:45:34 +0000441 call g:StopVimInTerminal(buf)
Bram Moolenaar112bed02021-11-23 22:16:34 +0000442enddef
443
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200444func Test_Backtrace_Through_Source()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200445 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200446 let file1 =<< trim END
447 func SourceAnotherFile()
448 source Xtest2.vim
449 endfunc
450
451 func CallAFunction()
452 call SourceAnotherFile()
453 call File2Function()
454 endfunc
455
456 func GlobalFunction()
457 call CallAFunction()
458 endfunc
459 END
Bram Moolenaar59173412022-09-20 22:01:33 +0100460 call writefile(file1, 'Xtest1.vim', 'D')
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200461
462 let file2 =<< trim END
463 func DoAThing()
464 echo "DoAThing"
465 endfunc
466
467 func File2Function()
468 call DoAThing()
469 endfunc
470
471 call File2Function()
472 END
Bram Moolenaar59173412022-09-20 22:01:33 +0100473 call writefile(file2, 'Xtest2.vim', 'D')
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200474
475 let buf = RunVimInTerminal('-S Xtest1.vim', {})
476
477 call RunDbgCmd(buf,
478 \ ':debug call GlobalFunction()',
479 \ ['cmd: call GlobalFunction()'])
480 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
481
482 call RunDbgCmd(buf, 'backtrace', ['>backtrace',
483 \ '->0 function GlobalFunction',
484 \ 'line 1: call CallAFunction()'])
485
486 call RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()'])
487 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
488
489 call RunDbgCmd(buf, 'backtrace', ['>backtrace',
490 \ ' 2 function GlobalFunction[1]',
491 \ ' 1 CallAFunction[1]',
492 \ '->0 SourceAnotherFile',
493 \ 'line 1: source Xtest2.vim'])
494
495 " Step into the 'source' command. Note that we print the full trace all the
496 " way though the source command.
497 call RunDbgCmd(buf, 'step', ['line 1: func DoAThing()'])
498 call RunDbgCmd(buf, 'backtrace', [
499 \ '>backtrace',
500 \ ' 3 function GlobalFunction[1]',
501 \ ' 2 CallAFunction[1]',
502 \ ' 1 SourceAnotherFile[1]',
503 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
504 \ 'line 1: func DoAThing()'])
505
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200506 call RunDbgCmd( buf, 'up' )
507 call RunDbgCmd( buf, 'backtrace', [
508 \ '>backtrace',
509 \ ' 3 function GlobalFunction[1]',
510 \ ' 2 CallAFunction[1]',
511 \ '->1 SourceAnotherFile[1]',
512 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
513 \ 'line 1: func DoAThing()' ] )
514
515 call RunDbgCmd( buf, 'up' )
516 call RunDbgCmd( buf, 'backtrace', [
517 \ '>backtrace',
518 \ ' 3 function GlobalFunction[1]',
519 \ '->2 CallAFunction[1]',
520 \ ' 1 SourceAnotherFile[1]',
521 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
522 \ 'line 1: func DoAThing()' ] )
523
524 call RunDbgCmd( buf, 'up' )
525 call RunDbgCmd( buf, 'backtrace', [
526 \ '>backtrace',
527 \ '->3 function GlobalFunction[1]',
528 \ ' 2 CallAFunction[1]',
529 \ ' 1 SourceAnotherFile[1]',
530 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
531 \ 'line 1: func DoAThing()' ] )
532
533 call RunDbgCmd( buf, 'up', [ 'frame at highest level: 3' ] )
534 call RunDbgCmd( buf, 'backtrace', [
535 \ '>backtrace',
536 \ '->3 function GlobalFunction[1]',
537 \ ' 2 CallAFunction[1]',
538 \ ' 1 SourceAnotherFile[1]',
539 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
540 \ 'line 1: func DoAThing()' ] )
541
542 call RunDbgCmd( buf, 'down' )
543 call RunDbgCmd( buf, 'backtrace', [
544 \ '>backtrace',
545 \ ' 3 function GlobalFunction[1]',
546 \ '->2 CallAFunction[1]',
547 \ ' 1 SourceAnotherFile[1]',
548 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
549 \ 'line 1: func DoAThing()' ] )
550
551 call RunDbgCmd( buf, 'down' )
552 call RunDbgCmd( buf, 'backtrace', [
553 \ '>backtrace',
554 \ ' 3 function GlobalFunction[1]',
555 \ ' 2 CallAFunction[1]',
556 \ '->1 SourceAnotherFile[1]',
557 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
558 \ 'line 1: func DoAThing()' ] )
559
560 call RunDbgCmd( buf, 'down' )
561 call RunDbgCmd( buf, 'backtrace', [
562 \ '>backtrace',
563 \ ' 3 function GlobalFunction[1]',
564 \ ' 2 CallAFunction[1]',
565 \ ' 1 SourceAnotherFile[1]',
566 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
567 \ 'line 1: func DoAThing()' ] )
568
569 call RunDbgCmd( buf, 'down', [ 'frame is zero' ] )
570
Dominique Pelle923dce22021-11-21 11:36:04 +0000571 " step until we have another meaningful trace
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200572 call RunDbgCmd(buf, 'step', ['line 5: func File2Function()'])
573 call RunDbgCmd(buf, 'step', ['line 9: call File2Function()'])
574 call RunDbgCmd(buf, 'backtrace', [
575 \ '>backtrace',
576 \ ' 3 function GlobalFunction[1]',
577 \ ' 2 CallAFunction[1]',
578 \ ' 1 SourceAnotherFile[1]',
579 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
580 \ 'line 9: call File2Function()'])
581
582 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
583 call RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"'])
584 call RunDbgCmd(buf, 'backtrace', [
585 \ '>backtrace',
586 \ ' 5 function GlobalFunction[1]',
587 \ ' 4 CallAFunction[1]',
588 \ ' 3 SourceAnotherFile[1]',
589 \ ' 2 script ' .. getcwd() .. '/Xtest2.vim[9]',
590 \ ' 1 function File2Function[1]',
591 \ '->0 DoAThing',
592 \ 'line 1: echo "DoAThing"'])
593
594 " Now, step (back to Xfile1.vim), and call the function _in_ Xfile2.vim
595 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
596 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
597 call RunDbgCmd(buf, 'step', ['line 10: End of sourced file'])
598 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
599 call RunDbgCmd(buf, 'step', ['line 2: call File2Function()'])
600 call RunDbgCmd(buf, 'backtrace', [
601 \ '>backtrace',
602 \ ' 1 function GlobalFunction[1]',
603 \ '->0 CallAFunction',
604 \ 'line 2: call File2Function()'])
605
606 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
607 call RunDbgCmd(buf, 'backtrace', [
608 \ '>backtrace',
609 \ ' 2 function GlobalFunction[1]',
610 \ ' 1 CallAFunction[2]',
611 \ '->0 File2Function',
612 \ 'line 1: call DoAThing()'])
613
614 call StopVimInTerminal(buf)
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200615endfunc
616
617func Test_Backtrace_Autocmd()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200618 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200619 let file1 =<< trim END
620 func SourceAnotherFile()
621 source Xtest2.vim
622 endfunc
623
624 func CallAFunction()
625 call SourceAnotherFile()
626 call File2Function()
627 endfunc
628
629 func GlobalFunction()
630 call CallAFunction()
631 endfunc
632
633 au User TestGlobalFunction :call GlobalFunction() | echo "Done"
634 END
Bram Moolenaar59173412022-09-20 22:01:33 +0100635 call writefile(file1, 'Xtest1.vim', 'D')
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200636
637 let file2 =<< trim END
638 func DoAThing()
639 echo "DoAThing"
640 endfunc
641
642 func File2Function()
643 call DoAThing()
644 endfunc
645
646 call File2Function()
647 END
Bram Moolenaar59173412022-09-20 22:01:33 +0100648 call writefile(file2, 'Xtest2.vim', 'D')
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200649
650 let buf = RunVimInTerminal('-S Xtest1.vim', {})
651
652 call RunDbgCmd(buf,
653 \ ':debug doautocmd User TestGlobalFunction',
654 \ ['cmd: doautocmd User TestGlobalFunction'])
655 call RunDbgCmd(buf, 'step', ['cmd: call GlobalFunction() | echo "Done"'])
656
Dominique Pelle923dce22021-11-21 11:36:04 +0000657 " At this point the only thing in the stack is the autocommand
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200658 call RunDbgCmd(buf, 'backtrace', [
659 \ '>backtrace',
660 \ '->0 User Autocommands for "TestGlobalFunction"',
661 \ 'cmd: call GlobalFunction() | echo "Done"'])
662
663 " And now we're back into the call stack
664 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
665 call RunDbgCmd(buf, 'backtrace', [
666 \ '>backtrace',
667 \ ' 1 User Autocommands for "TestGlobalFunction"',
668 \ '->0 function GlobalFunction',
669 \ 'line 1: call CallAFunction()'])
670
671 call RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()'])
672 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
673
674 call RunDbgCmd(buf, 'backtrace', [
675 \ '>backtrace',
676 \ ' 3 User Autocommands for "TestGlobalFunction"',
677 \ ' 2 function GlobalFunction[1]',
678 \ ' 1 CallAFunction[1]',
679 \ '->0 SourceAnotherFile',
680 \ 'line 1: source Xtest2.vim'])
681
682 " Step into the 'source' command. Note that we print the full trace all the
683 " way though the source command.
684 call RunDbgCmd(buf, 'step', ['line 1: func DoAThing()'])
685 call RunDbgCmd(buf, 'backtrace', [
686 \ '>backtrace',
687 \ ' 4 User Autocommands for "TestGlobalFunction"',
688 \ ' 3 function GlobalFunction[1]',
689 \ ' 2 CallAFunction[1]',
690 \ ' 1 SourceAnotherFile[1]',
691 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
692 \ 'line 1: func DoAThing()'])
693
Bram Moolenaarc63b72b2020-08-22 16:04:52 +0200694 call RunDbgCmd( buf, 'up' )
695 call RunDbgCmd( buf, 'backtrace', [
696 \ '>backtrace',
697 \ ' 4 User Autocommands for "TestGlobalFunction"',
698 \ ' 3 function GlobalFunction[1]',
699 \ ' 2 CallAFunction[1]',
700 \ '->1 SourceAnotherFile[1]',
701 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
702 \ 'line 1: func DoAThing()' ] )
703
704 call RunDbgCmd( buf, 'up' )
705 call RunDbgCmd( buf, 'backtrace', [
706 \ '>backtrace',
707 \ ' 4 User Autocommands for "TestGlobalFunction"',
708 \ ' 3 function GlobalFunction[1]',
709 \ '->2 CallAFunction[1]',
710 \ ' 1 SourceAnotherFile[1]',
711 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
712 \ 'line 1: func DoAThing()' ] )
713
714 call RunDbgCmd( buf, 'up' )
715 call RunDbgCmd( buf, 'backtrace', [
716 \ '>backtrace',
717 \ ' 4 User Autocommands for "TestGlobalFunction"',
718 \ '->3 function GlobalFunction[1]',
719 \ ' 2 CallAFunction[1]',
720 \ ' 1 SourceAnotherFile[1]',
721 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
722 \ 'line 1: func DoAThing()' ] )
723
724 call RunDbgCmd( buf, 'up' )
725 call RunDbgCmd( buf, 'backtrace', [
726 \ '>backtrace',
727 \ '->4 User Autocommands for "TestGlobalFunction"',
728 \ ' 3 function GlobalFunction[1]',
729 \ ' 2 CallAFunction[1]',
730 \ ' 1 SourceAnotherFile[1]',
731 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
732 \ 'line 1: func DoAThing()' ] )
733
734 call RunDbgCmd( buf, 'up', [ 'frame at highest level: 4' ] )
735 call RunDbgCmd( buf, 'backtrace', [
736 \ '>backtrace',
737 \ '->4 User Autocommands for "TestGlobalFunction"',
738 \ ' 3 function GlobalFunction[1]',
739 \ ' 2 CallAFunction[1]',
740 \ ' 1 SourceAnotherFile[1]',
741 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
742 \ 'line 1: func DoAThing()' ] )
743
744 call RunDbgCmd( buf, 'down' )
745 call RunDbgCmd( buf, 'backtrace', [
746 \ '>backtrace',
747 \ ' 4 User Autocommands for "TestGlobalFunction"',
748 \ '->3 function GlobalFunction[1]',
749 \ ' 2 CallAFunction[1]',
750 \ ' 1 SourceAnotherFile[1]',
751 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
752 \ 'line 1: func DoAThing()' ] )
753
754
755 call RunDbgCmd( buf, 'down' )
756 call RunDbgCmd( buf, 'backtrace', [
757 \ '>backtrace',
758 \ ' 4 User Autocommands for "TestGlobalFunction"',
759 \ ' 3 function GlobalFunction[1]',
760 \ '->2 CallAFunction[1]',
761 \ ' 1 SourceAnotherFile[1]',
762 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
763 \ 'line 1: func DoAThing()' ] )
764
765 call RunDbgCmd( buf, 'down' )
766 call RunDbgCmd( buf, 'backtrace', [
767 \ '>backtrace',
768 \ ' 4 User Autocommands for "TestGlobalFunction"',
769 \ ' 3 function GlobalFunction[1]',
770 \ ' 2 CallAFunction[1]',
771 \ '->1 SourceAnotherFile[1]',
772 \ ' 0 script ' .. getcwd() .. '/Xtest2.vim',
773 \ 'line 1: func DoAThing()' ] )
774
775 call RunDbgCmd( buf, 'down' )
776 call RunDbgCmd( buf, 'backtrace', [
777 \ '>backtrace',
778 \ ' 4 User Autocommands for "TestGlobalFunction"',
779 \ ' 3 function GlobalFunction[1]',
780 \ ' 2 CallAFunction[1]',
781 \ ' 1 SourceAnotherFile[1]',
782 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
783 \ 'line 1: func DoAThing()' ] )
784
785 call RunDbgCmd( buf, 'down', [ 'frame is zero' ] )
786
Dominique Pelle923dce22021-11-21 11:36:04 +0000787 " step until we have another meaningful trace
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200788 call RunDbgCmd(buf, 'step', ['line 5: func File2Function()'])
789 call RunDbgCmd(buf, 'step', ['line 9: call File2Function()'])
790 call RunDbgCmd(buf, 'backtrace', [
791 \ '>backtrace',
792 \ ' 4 User Autocommands for "TestGlobalFunction"',
793 \ ' 3 function GlobalFunction[1]',
794 \ ' 2 CallAFunction[1]',
795 \ ' 1 SourceAnotherFile[1]',
796 \ '->0 script ' .. getcwd() .. '/Xtest2.vim',
797 \ 'line 9: call File2Function()'])
798
799 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
800 call RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"'])
801 call RunDbgCmd(buf, 'backtrace', [
802 \ '>backtrace',
803 \ ' 6 User Autocommands for "TestGlobalFunction"',
804 \ ' 5 function GlobalFunction[1]',
805 \ ' 4 CallAFunction[1]',
806 \ ' 3 SourceAnotherFile[1]',
807 \ ' 2 script ' .. getcwd() .. '/Xtest2.vim[9]',
808 \ ' 1 function File2Function[1]',
809 \ '->0 DoAThing',
810 \ 'line 1: echo "DoAThing"'])
811
812 " Now, step (back to Xfile1.vim), and call the function _in_ Xfile2.vim
813 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
814 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
815 call RunDbgCmd(buf, 'step', ['line 10: End of sourced file'])
816 call RunDbgCmd(buf, 'step', ['line 1: End of function'])
817 call RunDbgCmd(buf, 'step', ['line 2: call File2Function()'])
818 call RunDbgCmd(buf, 'backtrace', [
819 \ '>backtrace',
820 \ ' 2 User Autocommands for "TestGlobalFunction"',
821 \ ' 1 function GlobalFunction[1]',
822 \ '->0 CallAFunction',
823 \ 'line 2: call File2Function()'])
824
825 call RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
826 call RunDbgCmd(buf, 'backtrace', [
827 \ '>backtrace',
828 \ ' 3 User Autocommands for "TestGlobalFunction"',
829 \ ' 2 function GlobalFunction[1]',
830 \ ' 1 CallAFunction[2]',
831 \ '->0 File2Function',
832 \ 'line 1: call DoAThing()'])
833
834
835 " Now unwind so that we get back to the original autocommand (and the second
836 " cmd echo "Done")
837 call RunDbgCmd(buf, 'finish', ['line 1: End of function'])
838 call RunDbgCmd(buf, 'backtrace', [
839 \ '>backtrace',
840 \ ' 3 User Autocommands for "TestGlobalFunction"',
841 \ ' 2 function GlobalFunction[1]',
842 \ ' 1 CallAFunction[2]',
843 \ '->0 File2Function',
844 \ 'line 1: End of function'])
845
846 call RunDbgCmd(buf, 'finish', ['line 2: End of function'])
847 call RunDbgCmd(buf, 'backtrace', [
848 \ '>backtrace',
849 \ ' 2 User Autocommands for "TestGlobalFunction"',
850 \ ' 1 function GlobalFunction[1]',
851 \ '->0 CallAFunction',
852 \ 'line 2: End of function'])
853
854 call RunDbgCmd(buf, 'finish', ['line 1: End of function'])
855 call RunDbgCmd(buf, 'backtrace', [
856 \ '>backtrace',
857 \ ' 1 User Autocommands for "TestGlobalFunction"',
858 \ '->0 function GlobalFunction',
859 \ 'line 1: End of function'])
860
861 call RunDbgCmd(buf, 'step', ['cmd: echo "Done"'])
862 call RunDbgCmd(buf, 'backtrace', [
863 \ '>backtrace',
864 \ '->0 User Autocommands for "TestGlobalFunction"',
865 \ 'cmd: echo "Done"'])
866
867 call StopVimInTerminal(buf)
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200868endfunc
869
870func Test_Backtrace_CmdLine()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200871 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200872 let file1 =<< trim END
873 func SourceAnotherFile()
874 source Xtest2.vim
875 endfunc
876
877 func CallAFunction()
878 call SourceAnotherFile()
879 call File2Function()
880 endfunc
881
882 func GlobalFunction()
883 call CallAFunction()
884 endfunc
885
886 au User TestGlobalFunction :call GlobalFunction() | echo "Done"
887 END
Bram Moolenaar59173412022-09-20 22:01:33 +0100888 call writefile(file1, 'Xtest1.vim', 'D')
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200889
890 let file2 =<< trim END
891 func DoAThing()
892 echo "DoAThing"
893 endfunc
894
895 func File2Function()
896 call DoAThing()
897 endfunc
898
899 call File2Function()
900 END
Bram Moolenaar59173412022-09-20 22:01:33 +0100901 call writefile(file2, 'Xtest2.vim', 'D')
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200902
903 let buf = RunVimInTerminal(
904 \ '-S Xtest1.vim -c "debug call GlobalFunction()"',
905 \ {'wait_for_ruler': 0})
906
Bram Moolenaar18dc3552020-11-22 14:24:00 +0100907 " Need to wait for the vim-in-terminal to be ready.
908 " With valgrind this can take quite long.
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200909 call CheckDbgOutput(buf, ['command line',
Bram Moolenaar18dc3552020-11-22 14:24:00 +0100910 \ 'cmd: call GlobalFunction()'], #{msec: 5000})
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200911
Dominique Pelle923dce22021-11-21 11:36:04 +0000912 " At this point the only thing in the stack is the cmdline
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200913 call RunDbgCmd(buf, 'backtrace', [
914 \ '>backtrace',
915 \ '->0 command line',
916 \ 'cmd: call GlobalFunction()'])
917
918 " And now we're back into the call stack
919 call RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
920 call RunDbgCmd(buf, 'backtrace', [
921 \ '>backtrace',
922 \ ' 1 command line',
923 \ '->0 function GlobalFunction',
924 \ 'line 1: call CallAFunction()'])
925
926 call StopVimInTerminal(buf)
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200927endfunc
928
929func Test_Backtrace_DefFunction()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200930 CheckCWD
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200931 let file1 =<< trim END
932 vim9script
Bram Moolenaar84c62d52022-01-06 21:31:19 +0000933 import './Xtest2.vim' as imp
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200934
935 def SourceAnotherFile()
936 source Xtest2.vim
937 enddef
938
939 def CallAFunction()
940 SourceAnotherFile()
Bram Moolenaar84c62d52022-01-06 21:31:19 +0000941 imp.File2Function()
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200942 enddef
943
944 def g:GlobalFunction()
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +0200945 var some = "some var"
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200946 CallAFunction()
947 enddef
948
949 defcompile
950 END
Bram Moolenaar59173412022-09-20 22:01:33 +0100951 call writefile(file1, 'Xtest1.vim', 'D')
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200952
953 let file2 =<< trim END
954 vim9script
955
956 def DoAThing(): number
Bram Moolenaar1bdae402020-10-03 14:14:56 +0200957 var a = 100 * 2
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200958 a += 3
959 return a
960 enddef
961
962 export def File2Function()
963 DoAThing()
964 enddef
965
966 defcompile
967 File2Function()
968 END
Bram Moolenaar59173412022-09-20 22:01:33 +0100969 call writefile(file2, 'Xtest2.vim', 'D')
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200970
971 let buf = RunVimInTerminal('-S Xtest1.vim', {})
972
973 call RunDbgCmd(buf,
974 \ ':debug call GlobalFunction()',
975 \ ['cmd: call GlobalFunction()'])
976
Bram Moolenaar4cea5362021-06-16 22:24:40 +0200977 call RunDbgCmd(buf, 'step', ['line 1: var some = "some var"'])
978 call RunDbgCmd(buf, 'step', ['line 2: CallAFunction()'])
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +0200979 call RunDbgCmd(buf, 'echo some', ['some var'])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200980
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200981 call RunDbgCmd(buf, 'backtrace', [
982 \ '\V>backtrace',
Bram Moolenaare99d4222021-06-13 14:01:26 +0200983 \ '\V->0 function GlobalFunction',
Bram Moolenaar4cea5362021-06-16 22:24:40 +0200984 \ '\Vline 2: CallAFunction()',
Bram Moolenaare99d4222021-06-13 14:01:26 +0200985 \ ],
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200986 \ #{match: 'pattern'})
987
Bram Moolenaar4cea5362021-06-16 22:24:40 +0200988 call RunDbgCmd(buf, 'step', ['line 1: SourceAnotherFile()'])
989 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
Dominique Pelleaf4a61a2021-12-27 17:21:41 +0000990 " Repeated line, because we first are in the compiled function before the
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +0200991 " EXEC and then in do_cmdline() before the :source command.
Bram Moolenaare99d4222021-06-13 14:01:26 +0200992 call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200993 call RunDbgCmd(buf, 'step', ['line 1: vim9script'])
994 call RunDbgCmd(buf, 'step', ['line 3: def DoAThing(): number'])
995 call RunDbgCmd(buf, 'step', ['line 9: export def File2Function()'])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200996 call RunDbgCmd(buf, 'step', ['line 13: defcompile'])
997 call RunDbgCmd(buf, 'step', ['line 14: File2Function()'])
998 call RunDbgCmd(buf, 'backtrace', [
999 \ '\V>backtrace',
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +02001000 \ '\V 3 function GlobalFunction[2]',
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +02001001 \ '\V 2 <SNR>\.\*_CallAFunction[1]',
1002 \ '\V 1 <SNR>\.\*_SourceAnotherFile[1]',
1003 \ '\V->0 script ' .. getcwd() .. '/Xtest2.vim',
1004 \ '\Vline 14: File2Function()'],
1005 \ #{match: 'pattern'})
1006
1007 " Don't step into compiled functions...
Bram Moolenaare99d4222021-06-13 14:01:26 +02001008 call RunDbgCmd(buf, 'next', ['line 15: End of sourced file'])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +02001009 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 15: End of sourced file'],
1016 \ #{match: 'pattern'})
1017
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +02001018 call StopVimInTerminal(buf)
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +02001019endfunc
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001020
Bram Moolenaar26a44842021-09-02 18:49:06 +02001021func Test_DefFunction_expr()
1022 CheckCWD
1023 let file3 =<< trim END
1024 vim9script
1025 g:someVar = "foo"
1026 def g:ChangeVar()
1027 g:someVar = "bar"
1028 echo "changed"
1029 enddef
1030 defcompile
1031 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001032 call writefile(file3, 'Xtest3.vim', 'D')
Bram Moolenaar26a44842021-09-02 18:49:06 +02001033 let buf = RunVimInTerminal('-S Xtest3.vim', {})
1034
1035 call RunDbgCmd(buf, ':breakadd expr g:someVar')
1036 call RunDbgCmd(buf, ':call g:ChangeVar()', ['Oldval = "''foo''"', 'Newval = "''bar''"', 'function ChangeVar', 'line 2: echo "changed"'])
1037
1038 call StopVimInTerminal(buf)
Bram Moolenaar26a44842021-09-02 18:49:06 +02001039endfunc
1040
Bram Moolenaar17d868b2021-06-27 16:29:53 +02001041func Test_debug_def_and_legacy_function()
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001042 CheckCWD
1043 let file =<< trim END
1044 vim9script
1045 def g:SomeFunc()
1046 echo "here"
1047 echo "and"
1048 echo "there"
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001049 breakadd func 2 LocalFunc
1050 LocalFunc()
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001051 enddef
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001052
1053 def LocalFunc()
1054 echo "first"
1055 echo "second"
Bram Moolenaar8cec9272021-06-23 20:20:53 +02001056 breakadd func LegacyFunc
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001057 LegacyFunc()
1058 enddef
1059
1060 func LegacyFunc()
1061 echo "legone"
1062 echo "legtwo"
1063 endfunc
1064
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001065 breakadd func 2 g:SomeFunc
1066 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001067 call writefile(file, 'XtestDebug.vim', 'D')
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001068
1069 let buf = RunVimInTerminal('-S XtestDebug.vim', {})
1070
1071 call RunDbgCmd(buf,':call SomeFunc()', ['line 2: echo "and"'])
1072 call RunDbgCmd(buf,'next', ['line 3: echo "there"'])
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001073 call RunDbgCmd(buf,'next', ['line 4: breakadd func 2 LocalFunc'])
1074
1075 " continue, next breakpoint is in LocalFunc()
1076 call RunDbgCmd(buf,'cont', ['line 2: echo "second"'])
1077
1078 " continue, next breakpoint is in LegacyFunc()
1079 call RunDbgCmd(buf,'cont', ['line 1: echo "legone"'])
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001080
1081 call RunDbgCmd(buf, 'cont')
1082
1083 call StopVimInTerminal(buf)
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001084endfunc
1085
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001086func Test_debug_def_function()
1087 CheckCWD
1088 let file =<< trim END
1089 vim9script
1090 def g:Func()
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001091 var n: number
1092 def Closure(): number
1093 return n + 3
1094 enddef
1095 n += Closure()
1096 echo 'result: ' .. n
1097 enddef
1098
1099 def g:FuncWithArgs(text: string, nr: number, ...items: list<number>)
1100 echo text .. nr
1101 for it in items
1102 echo it
1103 endfor
1104 echo "done"
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001105 enddef
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001106
1107 def g:FuncWithDict()
1108 var d = {
1109 a: 1,
1110 b: 2,
1111 }
Bram Moolenaar59b50c32021-06-17 22:27:48 +02001112 # comment
1113 def Inner()
Bram Moolenaar31e21762021-07-10 20:43:59 +02001114 eval 1 + 2
Bram Moolenaar59b50c32021-06-17 22:27:48 +02001115 enddef
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001116 enddef
Bram Moolenaar303215d2021-07-07 20:10:43 +02001117
Bram Moolenaar8cec9272021-06-23 20:20:53 +02001118 def g:FuncComment()
1119 # comment
1120 echo "first"
1121 .. "one"
1122 # comment
1123 echo "second"
1124 enddef
Bram Moolenaar303215d2021-07-07 20:10:43 +02001125
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001126 def g:FuncForLoop()
Bram Moolenaar31e21762021-07-10 20:43:59 +02001127 eval 1 + 2
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001128 for i in [11, 22, 33]
Bram Moolenaar31e21762021-07-10 20:43:59 +02001129 eval i + 2
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001130 endfor
1131 echo "done"
1132 enddef
Bram Moolenaar303215d2021-07-07 20:10:43 +02001133
1134 def g:FuncWithSplitLine()
Bram Moolenaar31e21762021-07-10 20:43:59 +02001135 eval 1 + 2
1136 | eval 2 + 3
Bram Moolenaar303215d2021-07-07 20:10:43 +02001137 enddef
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001138 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001139 call writefile(file, 'Xtest.vim', 'D')
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001140
1141 let buf = RunVimInTerminal('-S Xtest.vim', {})
1142
1143 call RunDbgCmd(buf,
1144 \ ':debug call Func()',
1145 \ ['cmd: call Func()'])
1146 call RunDbgCmd(buf, 'next', ['result: 3'])
1147 call term_sendkeys(buf, "\r")
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001148 call RunDbgCmd(buf, 'cont')
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001149
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001150 call RunDbgCmd(buf,
1151 \ ':debug call FuncWithArgs("asdf", 42, 1, 2, 3)',
1152 \ ['cmd: call FuncWithArgs("asdf", 42, 1, 2, 3)'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001153 call RunDbgCmd(buf, 'step', ['line 1: echo text .. nr'])
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001154 call RunDbgCmd(buf, 'echo text', ['asdf'])
1155 call RunDbgCmd(buf, 'echo nr', ['42'])
1156 call RunDbgCmd(buf, 'echo items', ['[1, 2, 3]'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001157 call RunDbgCmd(buf, 'step', ['asdf42', 'function FuncWithArgs', 'line 2: for it in items'])
1158 call RunDbgCmd(buf, 'step', ['function FuncWithArgs', 'line 2: for it in items'])
1159 call RunDbgCmd(buf, 'echo it', ['0'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001160 call RunDbgCmd(buf, 'step', ['line 3: echo it'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001161 call RunDbgCmd(buf, 'echo it', ['1'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001162 call RunDbgCmd(buf, 'step', ['1', 'function FuncWithArgs', 'line 4: endfor'])
1163 call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001164 call RunDbgCmd(buf, 'echo it', ['1'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001165 call RunDbgCmd(buf, 'step', ['line 3: echo it'])
1166 call RunDbgCmd(buf, 'step', ['2', 'function FuncWithArgs', 'line 4: endfor'])
1167 call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001168 call RunDbgCmd(buf, 'echo it', ['2'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001169 call RunDbgCmd(buf, 'step', ['line 3: echo it'])
1170 call RunDbgCmd(buf, 'step', ['3', 'function FuncWithArgs', 'line 4: endfor'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001171 call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001172 call RunDbgCmd(buf, 'step', ['line 5: echo "done"'])
1173 call RunDbgCmd(buf, 'cont')
1174
1175 call RunDbgCmd(buf,
1176 \ ':debug call FuncWithDict()',
1177 \ ['cmd: call FuncWithDict()'])
1178 call RunDbgCmd(buf, 'step', ['line 1: var d = { a: 1, b: 2, }'])
Bram Moolenaar59b50c32021-06-17 22:27:48 +02001179 call RunDbgCmd(buf, 'step', ['line 6: def Inner()'])
Bram Moolenaar8cec9272021-06-23 20:20:53 +02001180 call RunDbgCmd(buf, 'cont')
1181
1182 call RunDbgCmd(buf, ':breakadd func 1 FuncComment')
1183 call RunDbgCmd(buf, ':call FuncComment()', ['function FuncComment', 'line 2: echo "first" .. "one"'])
1184 call RunDbgCmd(buf, ':breakadd func 3 FuncComment')
1185 call RunDbgCmd(buf, 'cont', ['function FuncComment', 'line 5: echo "second"'])
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001186 call RunDbgCmd(buf, 'cont')
1187
1188 call RunDbgCmd(buf, ':breakadd func 2 FuncForLoop')
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001189 call RunDbgCmd(buf, ':call FuncForLoop()', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]'])
1190 call RunDbgCmd(buf, 'step', ['line 2: for i in [11, 22, 33]'])
Bram Moolenaar31e21762021-07-10 20:43:59 +02001191 call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 3: eval i + 2'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001192 call RunDbgCmd(buf, 'echo i', ['11'])
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001193 call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 4: endfor'])
1194 call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001195 call RunDbgCmd(buf, 'next', ['line 3: eval i + 2'])
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001196 call RunDbgCmd(buf, 'echo i', ['22'])
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001197
Bram Moolenaar303215d2021-07-07 20:10:43 +02001198 call RunDbgCmd(buf, 'breakdel *')
1199 call RunDbgCmd(buf, 'cont')
1200
1201 call RunDbgCmd(buf, ':breakadd func FuncWithSplitLine')
Bram Moolenaar31e21762021-07-10 20:43:59 +02001202 call RunDbgCmd(buf, ':call FuncWithSplitLine()', ['function FuncWithSplitLine', 'line 1: eval 1 + 2 | eval 2 + 3'])
Bram Moolenaar303215d2021-07-07 20:10:43 +02001203
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001204 call RunDbgCmd(buf, 'cont')
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001205 call StopVimInTerminal(buf)
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001206endfunc
1207
Bram Moolenaar17d868b2021-06-27 16:29:53 +02001208func Test_debug_def_function_with_lambda()
1209 CheckCWD
1210 let lines =<< trim END
1211 vim9script
1212 def g:Func()
1213 var s = 'a'
1214 ['b']->map((_, v) => s)
1215 echo "done"
1216 enddef
1217 breakadd func 2 g:Func
1218 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001219 call writefile(lines, 'XtestLambda.vim', 'D')
Bram Moolenaar17d868b2021-06-27 16:29:53 +02001220
1221 let buf = RunVimInTerminal('-S XtestLambda.vim', {})
1222
1223 call RunDbgCmd(buf,
1224 \ ':call g:Func()',
1225 \ ['function Func', 'line 2: [''b'']->map((_, v) => s)'])
1226 call RunDbgCmd(buf,
1227 \ 'next',
1228 \ ['function Func', 'line 3: echo "done"'])
1229
1230 call RunDbgCmd(buf, 'cont')
1231 call StopVimInTerminal(buf)
Bram Moolenaar17d868b2021-06-27 16:29:53 +02001232endfunc
1233
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001234func Test_debug_backtrace_level()
1235 CheckCWD
1236 let lines =<< trim END
1237 let s:file1_var = 'file1'
1238 let g:global_var = 'global'
1239
1240 func s:File1Func( arg )
1241 let s:file1_var .= a:arg
1242 let local_var = s:file1_var .. ' test1'
1243 let g:global_var .= local_var
1244 source Xtest2.vim
1245 endfunc
1246
1247 call s:File1Func( 'arg1' )
1248 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001249 call writefile(lines, 'Xtest1.vim', 'D')
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001250
1251 let lines =<< trim END
1252 let s:file2_var = 'file2'
1253
1254 func s:File2Func( arg )
1255 let s:file2_var .= a:arg
1256 let local_var = s:file2_var .. ' test2'
1257 let g:global_var .= local_var
1258 endfunc
1259
1260 call s:File2Func( 'arg2' )
1261 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001262 call writefile(lines, 'Xtest2.vim', 'D')
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001263
1264 let file1 = getcwd() .. '/Xtest1.vim'
1265 let file2 = getcwd() .. '/Xtest2.vim'
1266
1267 " set a breakpoint and source file1.vim
1268 let buf = RunVimInTerminal(
1269 \ '-c "breakadd file 1 Xtest1.vim" -S Xtest1.vim',
Bram Moolenaar18dc3552020-11-22 14:24:00 +01001270 \ #{wait_for_ruler: 0})
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001271
1272 call CheckDbgOutput(buf, [
1273 \ 'Breakpoint in "' .. file1 .. '" line 1',
1274 \ 'Entering Debug mode. Type "cont" to continue.',
1275 \ 'command line..script ' .. file1,
1276 \ 'line 1: let s:file1_var = ''file1'''
Bram Moolenaar18dc3552020-11-22 14:24:00 +01001277 \ ], #{msec: 5000})
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001278
Bram Moolenaar8e7d6222020-12-18 19:49:56 +01001279 " step through the initial declarations
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001280 call RunDbgCmd(buf, 'step', [ 'line 2: let g:global_var = ''global''' ] )
1281 call RunDbgCmd(buf, 'step', [ 'line 4: func s:File1Func( arg )' ] )
1282 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1283 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1284 call RunDbgCmd(buf, 'echo global_var', [ 'global' ] )
1285
1286 " step in to the first function
1287 call RunDbgCmd(buf, 'step', [ 'line 11: call s:File1Func( ''arg1'' )' ] )
1288 call RunDbgCmd(buf, 'step', [ 'line 1: let s:file1_var .= a:arg' ] )
1289 call RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] )
1290 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1291 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1292 call RunDbgCmd(buf,
1293 \'echo global_var',
1294 \[ 'E121: Undefined variable: global_var' ] )
1295 call RunDbgCmd(buf,
1296 \'echo local_var',
1297 \[ 'E121: Undefined variable: local_var' ] )
1298 call RunDbgCmd(buf,
1299 \'echo l:local_var',
1300 \[ 'E121: Undefined variable: l:local_var' ] )
1301
1302 " backtrace up
1303 call RunDbgCmd(buf, 'backtrace', [
1304 \ '\V>backtrace',
1305 \ '\V 2 command line',
1306 \ '\V 1 script ' .. file1 .. '[11]',
1307 \ '\V->0 function <SNR>\.\*_File1Func',
1308 \ '\Vline 1: let s:file1_var .= a:arg',
1309 \ ],
1310 \ #{ match: 'pattern' } )
1311 call RunDbgCmd(buf, 'up', [ '>up' ] )
1312
1313 call RunDbgCmd(buf, 'backtrace', [
1314 \ '\V>backtrace',
1315 \ '\V 2 command line',
1316 \ '\V->1 script ' .. file1 .. '[11]',
1317 \ '\V 0 function <SNR>\.\*_File1Func',
1318 \ '\Vline 1: let s:file1_var .= a:arg',
1319 \ ],
1320 \ #{ match: 'pattern' } )
1321
1322 " Expression evaluation in the script frame (not the function frame)
Dominique Pelle923dce22021-11-21 11:36:04 +00001323 " FIXME: Unexpected in this scope (a: should not be visible)
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001324 call RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] )
1325 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1326 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1327 " FIXME: Unexpected in this scope (global should be found)
1328 call RunDbgCmd(buf,
1329 \'echo global_var',
1330 \[ 'E121: Undefined variable: global_var' ] )
1331 call RunDbgCmd(buf,
1332 \'echo local_var',
1333 \[ 'E121: Undefined variable: local_var' ] )
1334 call RunDbgCmd(buf,
1335 \'echo l:local_var',
1336 \[ 'E121: Undefined variable: l:local_var' ] )
1337
1338
1339 " step while backtraced jumps to the latest frame
1340 call RunDbgCmd(buf, 'step', [
1341 \ 'line 2: let local_var = s:file1_var .. '' test1''' ] )
1342 call RunDbgCmd(buf, 'backtrace', [
1343 \ '\V>backtrace',
1344 \ '\V 2 command line',
1345 \ '\V 1 script ' .. file1 .. '[11]',
1346 \ '\V->0 function <SNR>\.\*_File1Func',
1347 \ '\Vline 2: let local_var = s:file1_var .. '' test1''',
1348 \ ],
1349 \ #{ match: 'pattern' } )
1350
1351 call RunDbgCmd(buf, 'step', [ 'line 3: let g:global_var .= local_var' ] )
1352 call RunDbgCmd(buf, 'echo local_var', [ 'file1arg1 test1' ] )
1353 call RunDbgCmd(buf, 'echo l:local_var', [ 'file1arg1 test1' ] )
1354
1355 call RunDbgCmd(buf, 'step', [ 'line 4: source Xtest2.vim' ] )
1356 call RunDbgCmd(buf, 'step', [ 'line 1: let s:file2_var = ''file2''' ] )
1357 call RunDbgCmd(buf, 'backtrace', [
1358 \ '\V>backtrace',
1359 \ '\V 3 command line',
1360 \ '\V 2 script ' .. file1 .. '[11]',
1361 \ '\V 1 function <SNR>\.\*_File1Func[4]',
1362 \ '\V->0 script ' .. file2,
1363 \ '\Vline 1: let s:file2_var = ''file2''',
1364 \ ],
1365 \ #{ match: 'pattern' } )
1366
1367 " Expression evaluation in the script frame file2 (not the function frame)
1368 call RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] )
1369 call RunDbgCmd(buf,
1370 \ 'echo s:file1_var',
1371 \ [ 'E121: Undefined variable: s:file1_var' ] )
1372 call RunDbgCmd(buf, 'echo g:global_var', [ 'globalfile1arg1 test1' ] )
1373 call RunDbgCmd(buf, 'echo global_var', [ 'globalfile1arg1 test1' ] )
1374 call RunDbgCmd(buf,
1375 \'echo local_var',
1376 \[ 'E121: Undefined variable: local_var' ] )
1377 call RunDbgCmd(buf,
1378 \'echo l:local_var',
1379 \[ 'E121: Undefined variable: l:local_var' ] )
1380 call RunDbgCmd(buf,
1381 \ 'echo s:file2_var',
1382 \ [ 'E121: Undefined variable: s:file2_var' ] )
1383
1384 call RunDbgCmd(buf, 'step', [ 'line 3: func s:File2Func( arg )' ] )
1385 call RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] )
1386
1387 " Up the stack to the other script context
1388 call RunDbgCmd(buf, 'up')
1389 call RunDbgCmd(buf, 'backtrace', [
1390 \ '\V>backtrace',
1391 \ '\V 3 command line',
1392 \ '\V 2 script ' .. file1 .. '[11]',
1393 \ '\V->1 function <SNR>\.\*_File1Func[4]',
1394 \ '\V 0 script ' .. file2,
1395 \ '\Vline 3: func s:File2Func( arg )',
1396 \ ],
1397 \ #{ match: 'pattern' } )
1398 " FIXME: Unexpected. Should see the a: and l: dicts from File1Func
1399 call RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] )
1400 call RunDbgCmd(buf,
1401 \ 'echo l:local_var',
1402 \ [ 'E121: Undefined variable: l:local_var' ] )
1403
1404 call RunDbgCmd(buf, 'up')
1405 call RunDbgCmd(buf, 'backtrace', [
1406 \ '\V>backtrace',
1407 \ '\V 3 command line',
1408 \ '\V->2 script ' .. file1 .. '[11]',
1409 \ '\V 1 function <SNR>\.\*_File1Func[4]',
1410 \ '\V 0 script ' .. file2,
1411 \ '\Vline 3: func s:File2Func( arg )',
1412 \ ],
1413 \ #{ match: 'pattern' } )
1414
1415 " FIXME: Unexpected (wrong script vars are used)
1416 call RunDbgCmd(buf,
1417 \ 'echo s:file1_var',
1418 \ [ 'E121: Undefined variable: s:file1_var' ] )
1419 call RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] )
1420
Bram Moolenaare99d4222021-06-13 14:01:26 +02001421 call RunDbgCmd(buf, 'cont')
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001422 call StopVimInTerminal(buf)
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001423endfunc
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001424
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001425" Test for setting a breakpoint on a :endif where the :if condition is false
1426" and then quit the script. This should generate an interrupt.
1427func Test_breakpt_endif_intr()
1428 func F()
1429 let g:Xpath ..= 'a'
1430 if v:false
1431 let g:Xpath ..= 'b'
1432 endif
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
1453" Test for setting a breakpoint on a :else where the :if condition is false
1454" and then quit the script. This should generate an interrupt.
1455func Test_breakpt_else_intr()
1456 func F()
1457 let g:Xpath ..= 'a'
1458 if v:false
1459 let g:Xpath ..= 'b'
1460 else
1461 invalid_command
1462 endif
1463 invalid_command
1464 endfunc
1465
1466 let g:Xpath = ''
1467 breakadd func 4 F
1468 try
1469 let caught_intr = 0
1470 debuggreedy
1471 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001472 catch /^Vim:Interrupt$/
1473 call assert_match('\.F, line 4', v:throwpoint)
1474 let caught_intr = 1
1475 endtry
1476 0debuggreedy
1477 call assert_equal(1, caught_intr)
1478 call assert_equal('a', g:Xpath)
1479 breakdel *
1480 delfunc F
1481endfunc
1482
1483" Test for setting a breakpoint on a :endwhile where the :while condition is
1484" false and then quit the script. This should generate an interrupt.
1485func Test_breakpt_endwhile_intr()
1486 func F()
1487 let g:Xpath ..= 'a'
1488 while v:false
1489 let g:Xpath ..= 'b'
1490 endwhile
1491 invalid_command
1492 endfunc
1493
1494 let g:Xpath = ''
1495 breakadd func 4 F
1496 try
1497 let caught_intr = 0
1498 debuggreedy
1499 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001500 catch /^Vim:Interrupt$/
1501 call assert_match('\.F, line 4', v:throwpoint)
1502 let caught_intr = 1
1503 endtry
1504 0debuggreedy
1505 call assert_equal(1, caught_intr)
1506 call assert_equal('a', g:Xpath)
1507 breakdel *
1508 delfunc F
1509endfunc
1510
Bram Moolenaar16c62322020-08-13 19:20:04 +02001511" Test for setting a breakpoint on a script local function
1512func Test_breakpt_scriptlocal_func()
1513 let g:Xpath = ''
1514 func s:G()
1515 let g:Xpath ..= 'a'
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001516 endfunc
1517
Bram Moolenaar16c62322020-08-13 19:20:04 +02001518 let funcname = expand("<SID>") .. "G"
1519 exe "breakadd func 1 " .. funcname
1520 debuggreedy
1521 redir => output
1522 call feedkeys(":call " .. funcname .. "()\<CR>c\<CR>", "xt")
1523 redir END
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001524 0debuggreedy
Bram Moolenaar16c62322020-08-13 19:20:04 +02001525 call assert_match('Breakpoint in "' .. funcname .. '" line 1', output)
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001526 call assert_equal('a', g:Xpath)
1527 breakdel *
Bram Moolenaar16c62322020-08-13 19:20:04 +02001528 exe "delfunc " .. funcname
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001529endfunc
1530
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001531" vim: shiftwidth=2 sts=2 expandtab