blob: 61cd5c98bd4ee3428b454bd0c041cc7b7d8aea95 [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()'])
996 call RunDbgCmd(buf, 'step', ['line 9: def File2Function()'])
997 call RunDbgCmd(buf, 'step', ['line 13: defcompile'])
998 call RunDbgCmd(buf, 'step', ['line 14: File2Function()'])
999 call RunDbgCmd(buf, 'backtrace', [
1000 \ '\V>backtrace',
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +02001001 \ '\V 3 function GlobalFunction[2]',
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +02001002 \ '\V 2 <SNR>\.\*_CallAFunction[1]',
1003 \ '\V 1 <SNR>\.\*_SourceAnotherFile[1]',
1004 \ '\V->0 script ' .. getcwd() .. '/Xtest2.vim',
1005 \ '\Vline 14: File2Function()'],
1006 \ #{match: 'pattern'})
1007
1008 " Don't step into compiled functions...
Bram Moolenaare99d4222021-06-13 14:01:26 +02001009 call RunDbgCmd(buf, 'next', ['line 15: End of sourced file'])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +02001010 call RunDbgCmd(buf, 'backtrace', [
1011 \ '\V>backtrace',
Bram Moolenaarb69c6fb2021-06-14 20:40:37 +02001012 \ '\V 3 function GlobalFunction[2]',
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +02001013 \ '\V 2 <SNR>\.\*_CallAFunction[1]',
1014 \ '\V 1 <SNR>\.\*_SourceAnotherFile[1]',
1015 \ '\V->0 script ' .. getcwd() .. '/Xtest2.vim',
1016 \ '\Vline 15: End of sourced file'],
1017 \ #{match: 'pattern'})
1018
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +02001019 call StopVimInTerminal(buf)
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +02001020endfunc
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001021
Bram Moolenaar26a44842021-09-02 18:49:06 +02001022func Test_DefFunction_expr()
1023 CheckCWD
1024 let file3 =<< trim END
1025 vim9script
1026 g:someVar = "foo"
1027 def g:ChangeVar()
1028 g:someVar = "bar"
1029 echo "changed"
1030 enddef
1031 defcompile
1032 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001033 call writefile(file3, 'Xtest3.vim', 'D')
Bram Moolenaar26a44842021-09-02 18:49:06 +02001034 let buf = RunVimInTerminal('-S Xtest3.vim', {})
1035
1036 call RunDbgCmd(buf, ':breakadd expr g:someVar')
1037 call RunDbgCmd(buf, ':call g:ChangeVar()', ['Oldval = "''foo''"', 'Newval = "''bar''"', 'function ChangeVar', 'line 2: echo "changed"'])
1038
1039 call StopVimInTerminal(buf)
Bram Moolenaar26a44842021-09-02 18:49:06 +02001040endfunc
1041
Bram Moolenaar17d868b2021-06-27 16:29:53 +02001042func Test_debug_def_and_legacy_function()
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001043 CheckCWD
1044 let file =<< trim END
1045 vim9script
1046 def g:SomeFunc()
1047 echo "here"
1048 echo "and"
1049 echo "there"
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001050 breakadd func 2 LocalFunc
1051 LocalFunc()
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001052 enddef
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001053
1054 def LocalFunc()
1055 echo "first"
1056 echo "second"
Bram Moolenaar8cec9272021-06-23 20:20:53 +02001057 breakadd func LegacyFunc
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001058 LegacyFunc()
1059 enddef
1060
1061 func LegacyFunc()
1062 echo "legone"
1063 echo "legtwo"
1064 endfunc
1065
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001066 breakadd func 2 g:SomeFunc
1067 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001068 call writefile(file, 'XtestDebug.vim', 'D')
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001069
1070 let buf = RunVimInTerminal('-S XtestDebug.vim', {})
1071
1072 call RunDbgCmd(buf,':call SomeFunc()', ['line 2: echo "and"'])
1073 call RunDbgCmd(buf,'next', ['line 3: echo "there"'])
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001074 call RunDbgCmd(buf,'next', ['line 4: breakadd func 2 LocalFunc'])
1075
1076 " continue, next breakpoint is in LocalFunc()
1077 call RunDbgCmd(buf,'cont', ['line 2: echo "second"'])
1078
1079 " continue, next breakpoint is in LegacyFunc()
1080 call RunDbgCmd(buf,'cont', ['line 1: echo "legone"'])
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001081
1082 call RunDbgCmd(buf, 'cont')
1083
1084 call StopVimInTerminal(buf)
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001085endfunc
1086
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001087func Test_debug_def_function()
1088 CheckCWD
1089 let file =<< trim END
1090 vim9script
1091 def g:Func()
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001092 var n: number
1093 def Closure(): number
1094 return n + 3
1095 enddef
1096 n += Closure()
1097 echo 'result: ' .. n
1098 enddef
1099
1100 def g:FuncWithArgs(text: string, nr: number, ...items: list<number>)
1101 echo text .. nr
1102 for it in items
1103 echo it
1104 endfor
1105 echo "done"
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001106 enddef
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001107
1108 def g:FuncWithDict()
1109 var d = {
1110 a: 1,
1111 b: 2,
1112 }
Bram Moolenaar59b50c32021-06-17 22:27:48 +02001113 # comment
1114 def Inner()
Bram Moolenaar31e21762021-07-10 20:43:59 +02001115 eval 1 + 2
Bram Moolenaar59b50c32021-06-17 22:27:48 +02001116 enddef
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001117 enddef
Bram Moolenaar303215d2021-07-07 20:10:43 +02001118
Bram Moolenaar8cec9272021-06-23 20:20:53 +02001119 def g:FuncComment()
1120 # comment
1121 echo "first"
1122 .. "one"
1123 # comment
1124 echo "second"
1125 enddef
Bram Moolenaar303215d2021-07-07 20:10:43 +02001126
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001127 def g:FuncForLoop()
Bram Moolenaar31e21762021-07-10 20:43:59 +02001128 eval 1 + 2
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001129 for i in [11, 22, 33]
Bram Moolenaar31e21762021-07-10 20:43:59 +02001130 eval i + 2
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001131 endfor
1132 echo "done"
1133 enddef
Bram Moolenaar303215d2021-07-07 20:10:43 +02001134
1135 def g:FuncWithSplitLine()
Bram Moolenaar31e21762021-07-10 20:43:59 +02001136 eval 1 + 2
1137 | eval 2 + 3
Bram Moolenaar303215d2021-07-07 20:10:43 +02001138 enddef
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001139 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001140 call writefile(file, 'Xtest.vim', 'D')
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001141
1142 let buf = RunVimInTerminal('-S Xtest.vim', {})
1143
1144 call RunDbgCmd(buf,
1145 \ ':debug call Func()',
1146 \ ['cmd: call Func()'])
1147 call RunDbgCmd(buf, 'next', ['result: 3'])
1148 call term_sendkeys(buf, "\r")
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001149 call RunDbgCmd(buf, 'cont')
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001150
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001151 call RunDbgCmd(buf,
1152 \ ':debug call FuncWithArgs("asdf", 42, 1, 2, 3)',
1153 \ ['cmd: call FuncWithArgs("asdf", 42, 1, 2, 3)'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001154 call RunDbgCmd(buf, 'step', ['line 1: echo text .. nr'])
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001155 call RunDbgCmd(buf, 'echo text', ['asdf'])
1156 call RunDbgCmd(buf, 'echo nr', ['42'])
1157 call RunDbgCmd(buf, 'echo items', ['[1, 2, 3]'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001158 call RunDbgCmd(buf, 'step', ['asdf42', 'function FuncWithArgs', 'line 2: for it in items'])
1159 call RunDbgCmd(buf, 'step', ['function FuncWithArgs', 'line 2: for it in items'])
1160 call RunDbgCmd(buf, 'echo it', ['0'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001161 call RunDbgCmd(buf, 'step', ['line 3: echo it'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001162 call RunDbgCmd(buf, 'echo it', ['1'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001163 call RunDbgCmd(buf, 'step', ['1', 'function FuncWithArgs', 'line 4: endfor'])
1164 call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001165 call RunDbgCmd(buf, 'echo it', ['1'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001166 call RunDbgCmd(buf, 'step', ['line 3: echo it'])
1167 call RunDbgCmd(buf, 'step', ['2', 'function FuncWithArgs', 'line 4: endfor'])
1168 call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001169 call RunDbgCmd(buf, 'echo it', ['2'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001170 call RunDbgCmd(buf, 'step', ['line 3: echo it'])
1171 call RunDbgCmd(buf, 'step', ['3', 'function FuncWithArgs', 'line 4: endfor'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001172 call RunDbgCmd(buf, 'step', ['line 2: for it in items'])
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001173 call RunDbgCmd(buf, 'step', ['line 5: echo "done"'])
1174 call RunDbgCmd(buf, 'cont')
1175
1176 call RunDbgCmd(buf,
1177 \ ':debug call FuncWithDict()',
1178 \ ['cmd: call FuncWithDict()'])
1179 call RunDbgCmd(buf, 'step', ['line 1: var d = { a: 1, b: 2, }'])
Bram Moolenaar59b50c32021-06-17 22:27:48 +02001180 call RunDbgCmd(buf, 'step', ['line 6: def Inner()'])
Bram Moolenaar8cec9272021-06-23 20:20:53 +02001181 call RunDbgCmd(buf, 'cont')
1182
1183 call RunDbgCmd(buf, ':breakadd func 1 FuncComment')
1184 call RunDbgCmd(buf, ':call FuncComment()', ['function FuncComment', 'line 2: echo "first" .. "one"'])
1185 call RunDbgCmd(buf, ':breakadd func 3 FuncComment')
1186 call RunDbgCmd(buf, 'cont', ['function FuncComment', 'line 5: echo "second"'])
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001187 call RunDbgCmd(buf, 'cont')
1188
1189 call RunDbgCmd(buf, ':breakadd func 2 FuncForLoop')
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001190 call RunDbgCmd(buf, ':call FuncForLoop()', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]'])
1191 call RunDbgCmd(buf, 'step', ['line 2: for i in [11, 22, 33]'])
Bram Moolenaar31e21762021-07-10 20:43:59 +02001192 call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 3: eval i + 2'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001193 call RunDbgCmd(buf, 'echo i', ['11'])
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001194 call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 4: endfor'])
1195 call RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]'])
Bram Moolenaar3d0da092022-01-02 17:28:57 +00001196 call RunDbgCmd(buf, 'next', ['line 3: eval i + 2'])
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001197 call RunDbgCmd(buf, 'echo i', ['22'])
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001198
Bram Moolenaar303215d2021-07-07 20:10:43 +02001199 call RunDbgCmd(buf, 'breakdel *')
1200 call RunDbgCmd(buf, 'cont')
1201
1202 call RunDbgCmd(buf, ':breakadd func FuncWithSplitLine')
Bram Moolenaar31e21762021-07-10 20:43:59 +02001203 call RunDbgCmd(buf, ':call FuncWithSplitLine()', ['function FuncWithSplitLine', 'line 1: eval 1 + 2 | eval 2 + 3'])
Bram Moolenaar303215d2021-07-07 20:10:43 +02001204
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001205 call RunDbgCmd(buf, 'cont')
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001206 call StopVimInTerminal(buf)
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001207endfunc
1208
Bram Moolenaar17d868b2021-06-27 16:29:53 +02001209func Test_debug_def_function_with_lambda()
1210 CheckCWD
1211 let lines =<< trim END
1212 vim9script
1213 def g:Func()
1214 var s = 'a'
1215 ['b']->map((_, v) => s)
1216 echo "done"
1217 enddef
1218 breakadd func 2 g:Func
1219 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001220 call writefile(lines, 'XtestLambda.vim', 'D')
Bram Moolenaar17d868b2021-06-27 16:29:53 +02001221
1222 let buf = RunVimInTerminal('-S XtestLambda.vim', {})
1223
1224 call RunDbgCmd(buf,
1225 \ ':call g:Func()',
1226 \ ['function Func', 'line 2: [''b'']->map((_, v) => s)'])
1227 call RunDbgCmd(buf,
1228 \ 'next',
1229 \ ['function Func', 'line 3: echo "done"'])
1230
1231 call RunDbgCmd(buf, 'cont')
1232 call StopVimInTerminal(buf)
Bram Moolenaar17d868b2021-06-27 16:29:53 +02001233endfunc
1234
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001235func Test_debug_backtrace_level()
1236 CheckCWD
1237 let lines =<< trim END
1238 let s:file1_var = 'file1'
1239 let g:global_var = 'global'
1240
1241 func s:File1Func( arg )
1242 let s:file1_var .= a:arg
1243 let local_var = s:file1_var .. ' test1'
1244 let g:global_var .= local_var
1245 source Xtest2.vim
1246 endfunc
1247
1248 call s:File1Func( 'arg1' )
1249 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001250 call writefile(lines, 'Xtest1.vim', 'D')
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001251
1252 let lines =<< trim END
1253 let s:file2_var = 'file2'
1254
1255 func s:File2Func( arg )
1256 let s:file2_var .= a:arg
1257 let local_var = s:file2_var .. ' test2'
1258 let g:global_var .= local_var
1259 endfunc
1260
1261 call s:File2Func( 'arg2' )
1262 END
Bram Moolenaar59173412022-09-20 22:01:33 +01001263 call writefile(lines, 'Xtest2.vim', 'D')
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001264
1265 let file1 = getcwd() .. '/Xtest1.vim'
1266 let file2 = getcwd() .. '/Xtest2.vim'
1267
1268 " set a breakpoint and source file1.vim
1269 let buf = RunVimInTerminal(
1270 \ '-c "breakadd file 1 Xtest1.vim" -S Xtest1.vim',
Bram Moolenaar18dc3552020-11-22 14:24:00 +01001271 \ #{wait_for_ruler: 0})
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001272
1273 call CheckDbgOutput(buf, [
1274 \ 'Breakpoint in "' .. file1 .. '" line 1',
1275 \ 'Entering Debug mode. Type "cont" to continue.',
1276 \ 'command line..script ' .. file1,
1277 \ 'line 1: let s:file1_var = ''file1'''
Bram Moolenaar18dc3552020-11-22 14:24:00 +01001278 \ ], #{msec: 5000})
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001279
Bram Moolenaar8e7d6222020-12-18 19:49:56 +01001280 " step through the initial declarations
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001281 call RunDbgCmd(buf, 'step', [ 'line 2: let g:global_var = ''global''' ] )
1282 call RunDbgCmd(buf, 'step', [ 'line 4: func s:File1Func( arg )' ] )
1283 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1284 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1285 call RunDbgCmd(buf, 'echo global_var', [ 'global' ] )
1286
1287 " step in to the first function
1288 call RunDbgCmd(buf, 'step', [ 'line 11: call s:File1Func( ''arg1'' )' ] )
1289 call RunDbgCmd(buf, 'step', [ 'line 1: let s:file1_var .= a:arg' ] )
1290 call RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] )
1291 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1292 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1293 call RunDbgCmd(buf,
1294 \'echo global_var',
1295 \[ 'E121: Undefined variable: global_var' ] )
1296 call RunDbgCmd(buf,
1297 \'echo local_var',
1298 \[ 'E121: Undefined variable: local_var' ] )
1299 call RunDbgCmd(buf,
1300 \'echo l:local_var',
1301 \[ 'E121: Undefined variable: l:local_var' ] )
1302
1303 " backtrace up
1304 call RunDbgCmd(buf, 'backtrace', [
1305 \ '\V>backtrace',
1306 \ '\V 2 command line',
1307 \ '\V 1 script ' .. file1 .. '[11]',
1308 \ '\V->0 function <SNR>\.\*_File1Func',
1309 \ '\Vline 1: let s:file1_var .= a:arg',
1310 \ ],
1311 \ #{ match: 'pattern' } )
1312 call RunDbgCmd(buf, 'up', [ '>up' ] )
1313
1314 call RunDbgCmd(buf, 'backtrace', [
1315 \ '\V>backtrace',
1316 \ '\V 2 command line',
1317 \ '\V->1 script ' .. file1 .. '[11]',
1318 \ '\V 0 function <SNR>\.\*_File1Func',
1319 \ '\Vline 1: let s:file1_var .= a:arg',
1320 \ ],
1321 \ #{ match: 'pattern' } )
1322
1323 " Expression evaluation in the script frame (not the function frame)
Dominique Pelle923dce22021-11-21 11:36:04 +00001324 " FIXME: Unexpected in this scope (a: should not be visible)
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001325 call RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] )
1326 call RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1327 call RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1328 " FIXME: Unexpected in this scope (global should be found)
1329 call RunDbgCmd(buf,
1330 \'echo global_var',
1331 \[ 'E121: Undefined variable: global_var' ] )
1332 call RunDbgCmd(buf,
1333 \'echo local_var',
1334 \[ 'E121: Undefined variable: local_var' ] )
1335 call RunDbgCmd(buf,
1336 \'echo l:local_var',
1337 \[ 'E121: Undefined variable: l:local_var' ] )
1338
1339
1340 " step while backtraced jumps to the latest frame
1341 call RunDbgCmd(buf, 'step', [
1342 \ 'line 2: let local_var = s:file1_var .. '' test1''' ] )
1343 call RunDbgCmd(buf, 'backtrace', [
1344 \ '\V>backtrace',
1345 \ '\V 2 command line',
1346 \ '\V 1 script ' .. file1 .. '[11]',
1347 \ '\V->0 function <SNR>\.\*_File1Func',
1348 \ '\Vline 2: let local_var = s:file1_var .. '' test1''',
1349 \ ],
1350 \ #{ match: 'pattern' } )
1351
1352 call RunDbgCmd(buf, 'step', [ 'line 3: let g:global_var .= local_var' ] )
1353 call RunDbgCmd(buf, 'echo local_var', [ 'file1arg1 test1' ] )
1354 call RunDbgCmd(buf, 'echo l:local_var', [ 'file1arg1 test1' ] )
1355
1356 call RunDbgCmd(buf, 'step', [ 'line 4: source Xtest2.vim' ] )
1357 call RunDbgCmd(buf, 'step', [ 'line 1: let s:file2_var = ''file2''' ] )
1358 call RunDbgCmd(buf, 'backtrace', [
1359 \ '\V>backtrace',
1360 \ '\V 3 command line',
1361 \ '\V 2 script ' .. file1 .. '[11]',
1362 \ '\V 1 function <SNR>\.\*_File1Func[4]',
1363 \ '\V->0 script ' .. file2,
1364 \ '\Vline 1: let s:file2_var = ''file2''',
1365 \ ],
1366 \ #{ match: 'pattern' } )
1367
1368 " Expression evaluation in the script frame file2 (not the function frame)
1369 call RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] )
1370 call RunDbgCmd(buf,
1371 \ 'echo s:file1_var',
1372 \ [ 'E121: Undefined variable: s:file1_var' ] )
1373 call RunDbgCmd(buf, 'echo g:global_var', [ 'globalfile1arg1 test1' ] )
1374 call RunDbgCmd(buf, 'echo global_var', [ 'globalfile1arg1 test1' ] )
1375 call RunDbgCmd(buf,
1376 \'echo local_var',
1377 \[ 'E121: Undefined variable: local_var' ] )
1378 call RunDbgCmd(buf,
1379 \'echo l:local_var',
1380 \[ 'E121: Undefined variable: l:local_var' ] )
1381 call RunDbgCmd(buf,
1382 \ 'echo s:file2_var',
1383 \ [ 'E121: Undefined variable: s:file2_var' ] )
1384
1385 call RunDbgCmd(buf, 'step', [ 'line 3: func s:File2Func( arg )' ] )
1386 call RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] )
1387
1388 " Up the stack to the other script context
1389 call RunDbgCmd(buf, 'up')
1390 call RunDbgCmd(buf, 'backtrace', [
1391 \ '\V>backtrace',
1392 \ '\V 3 command line',
1393 \ '\V 2 script ' .. file1 .. '[11]',
1394 \ '\V->1 function <SNR>\.\*_File1Func[4]',
1395 \ '\V 0 script ' .. file2,
1396 \ '\Vline 3: func s:File2Func( arg )',
1397 \ ],
1398 \ #{ match: 'pattern' } )
1399 " FIXME: Unexpected. Should see the a: and l: dicts from File1Func
1400 call RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] )
1401 call RunDbgCmd(buf,
1402 \ 'echo l:local_var',
1403 \ [ 'E121: Undefined variable: l:local_var' ] )
1404
1405 call RunDbgCmd(buf, 'up')
1406 call RunDbgCmd(buf, 'backtrace', [
1407 \ '\V>backtrace',
1408 \ '\V 3 command line',
1409 \ '\V->2 script ' .. file1 .. '[11]',
1410 \ '\V 1 function <SNR>\.\*_File1Func[4]',
1411 \ '\V 0 script ' .. file2,
1412 \ '\Vline 3: func s:File2Func( arg )',
1413 \ ],
1414 \ #{ match: 'pattern' } )
1415
1416 " FIXME: Unexpected (wrong script vars are used)
1417 call RunDbgCmd(buf,
1418 \ 'echo s:file1_var',
1419 \ [ 'E121: Undefined variable: s:file1_var' ] )
1420 call RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] )
1421
Bram Moolenaare99d4222021-06-13 14:01:26 +02001422 call RunDbgCmd(buf, 'cont')
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001423 call StopVimInTerminal(buf)
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001424endfunc
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001425
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001426" Test for setting a breakpoint on a :endif where the :if condition is false
1427" and then quit the script. This should generate an interrupt.
1428func Test_breakpt_endif_intr()
1429 func F()
1430 let g:Xpath ..= 'a'
1431 if v:false
1432 let g:Xpath ..= 'b'
1433 endif
1434 invalid_command
1435 endfunc
1436
1437 let g:Xpath = ''
1438 breakadd func 4 F
1439 try
1440 let caught_intr = 0
1441 debuggreedy
1442 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001443 catch /^Vim:Interrupt$/
1444 call assert_match('\.F, line 4', v:throwpoint)
1445 let caught_intr = 1
1446 endtry
1447 0debuggreedy
1448 call assert_equal(1, caught_intr)
1449 call assert_equal('a', g:Xpath)
1450 breakdel *
1451 delfunc F
1452endfunc
1453
1454" Test for setting a breakpoint on a :else where the :if condition is false
1455" and then quit the script. This should generate an interrupt.
1456func Test_breakpt_else_intr()
1457 func F()
1458 let g:Xpath ..= 'a'
1459 if v:false
1460 let g:Xpath ..= 'b'
1461 else
1462 invalid_command
1463 endif
1464 invalid_command
1465 endfunc
1466
1467 let g:Xpath = ''
1468 breakadd func 4 F
1469 try
1470 let caught_intr = 0
1471 debuggreedy
1472 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001473 catch /^Vim:Interrupt$/
1474 call assert_match('\.F, line 4', v:throwpoint)
1475 let caught_intr = 1
1476 endtry
1477 0debuggreedy
1478 call assert_equal(1, caught_intr)
1479 call assert_equal('a', g:Xpath)
1480 breakdel *
1481 delfunc F
1482endfunc
1483
1484" Test for setting a breakpoint on a :endwhile where the :while condition is
1485" false and then quit the script. This should generate an interrupt.
1486func Test_breakpt_endwhile_intr()
1487 func F()
1488 let g:Xpath ..= 'a'
1489 while v:false
1490 let g:Xpath ..= 'b'
1491 endwhile
1492 invalid_command
1493 endfunc
1494
1495 let g:Xpath = ''
1496 breakadd func 4 F
1497 try
1498 let caught_intr = 0
1499 debuggreedy
1500 call feedkeys(":call F()\<CR>quit\<CR>", "xt")
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001501 catch /^Vim:Interrupt$/
1502 call assert_match('\.F, line 4', v:throwpoint)
1503 let caught_intr = 1
1504 endtry
1505 0debuggreedy
1506 call assert_equal(1, caught_intr)
1507 call assert_equal('a', g:Xpath)
1508 breakdel *
1509 delfunc F
1510endfunc
1511
Bram Moolenaar16c62322020-08-13 19:20:04 +02001512" Test for setting a breakpoint on a script local function
1513func Test_breakpt_scriptlocal_func()
1514 let g:Xpath = ''
1515 func s:G()
1516 let g:Xpath ..= 'a'
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001517 endfunc
1518
Bram Moolenaar16c62322020-08-13 19:20:04 +02001519 let funcname = expand("<SID>") .. "G"
1520 exe "breakadd func 1 " .. funcname
1521 debuggreedy
1522 redir => output
1523 call feedkeys(":call " .. funcname .. "()\<CR>c\<CR>", "xt")
1524 redir END
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001525 0debuggreedy
Bram Moolenaar16c62322020-08-13 19:20:04 +02001526 call assert_match('Breakpoint in "' .. funcname .. '" line 1', output)
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001527 call assert_equal('a', g:Xpath)
1528 breakdel *
Bram Moolenaar16c62322020-08-13 19:20:04 +02001529 exe "delfunc " .. funcname
Bram Moolenaar7ac616c2020-08-12 22:22:09 +02001530endfunc
1531
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001532" vim: shiftwidth=2 sts=2 expandtab