blob: 4261bb375a9493667e564b0d2e68ab7e61466dca [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 Moolenaarbf630112023-05-19 21:41:02 +010023def s:CheckDbgOutput(buf: number, lines: list<string>, options = {})
24 # Verify the expected output
25 var lnum = 20 - len(lines)
26 var msec = get(options, 'msec', 1000)
27 for l in lines
28 if get(options, 'match', 'equal') ==# 'pattern'
29 g:WaitForAssert(() => assert_match(l, term_getline(buf, lnum)), msec)
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +020030 else
Bram Moolenaarbf630112023-05-19 21:41:02 +010031 g:WaitForAssert(() => assert_equal(l, term_getline(buf, lnum)), msec)
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +020032 endif
Bram Moolenaarbf630112023-05-19 21:41:02 +010033 lnum += 1
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +020034 endfor
Bram Moolenaarbf630112023-05-19 21:41:02 +010035enddef
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +020036
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.
Bram Moolenaarbf630112023-05-19 21:41:02 +010039def s:RunDbgCmd(buf: number, cmd: string, ...extra: list<any>)
40 term_sendkeys(buf, cmd .. "\r")
41 g:TermWait(buf)
Bram Moolenaar113bf062019-04-17 16:54:05 +020042
Bram Moolenaarbf630112023-05-19 21:41:02 +010043 if len(extra) > 0
44 var options = {match: 'equal'}
45 if len(extra) > 1
46 extend(options, extra[1])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +020047 endif
Bram Moolenaarbf630112023-05-19 21:41:02 +010048 s:CheckDbgOutput(buf, extra[0], options)
Bram Moolenaar113bf062019-04-17 16:54:05 +020049 endif
Bram Moolenaarbf630112023-05-19 21:41:02 +010050enddef
Bram Moolenaar113bf062019-04-17 16:54:05 +020051
52" Debugger tests
Bram Moolenaarbf630112023-05-19 21:41:02 +010053def Test_Debugger()
54 # Create a Vim script with some functions
55 var lines =<< trim END
Bram Moolenaare7eb9272019-06-24 00:58:07 +020056 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 Moolenaarbf630112023-05-19 21:41:02 +010084 writefile(lines, 'XtestDebug.vim', 'D')
Bram Moolenaar113bf062019-04-17 16:54:05 +020085
Bram Moolenaarbf630112023-05-19 21:41:02 +010086 # Start Vim in a terminal
87 var buf = g:RunVimInTerminal('-S XtestDebug.vim', {})
Bram Moolenaar113bf062019-04-17 16:54:05 +020088
Bram Moolenaarbf630112023-05-19 21:41:02 +010089 # Start the Vim debugger
90 s:RunDbgCmd(buf, ':debug echo Foo()', ['cmd: echo Foo()'])
Bram Moolenaar113bf062019-04-17 16:54:05 +020091
Bram Moolenaarbf630112023-05-19 21:41:02 +010092 # Create a few stack frames by stepping through functions
93 s:RunDbgCmd(buf, 'step', ['line 1: let var1 = 1'])
94 s:RunDbgCmd(buf, 'step', ['line 2: let var2 = Bar(var1) + 9'])
95 s:RunDbgCmd(buf, 'step', ['line 1: let var1 = 2 + a:var'])
96 s:RunDbgCmd(buf, 'step', ['line 2: let var2 = Bazz(var1) + 4'])
97 s:RunDbgCmd(buf, 'step', ['line 1: try'])
98 s:RunDbgCmd(buf, 'step', ['line 2: let var1 = 3 + a:var'])
99 s:RunDbgCmd(buf, 'step', ['line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200100
Bram Moolenaarbf630112023-05-19 21:41:02 +0100101 # check backtrace
102 s:RunDbgCmd(buf, 'backtrace', [
103 ' 2 function Foo[2]',
104 ' 1 Bar[2]',
105 '->0 Bazz',
106 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200107
Bram Moolenaarbf630112023-05-19 21:41:02 +0100108 # Check variables in different stack frames
109 s:RunDbgCmd(buf, 'echo var1', ['6'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200110
Bram Moolenaarbf630112023-05-19 21:41:02 +0100111 s:RunDbgCmd(buf, 'up')
112 s:RunDbgCmd(buf, 'back', [
113 ' 2 function Foo[2]',
114 '->1 Bar[2]',
115 ' 0 Bazz',
116 'line 3: let var3 = "another var"'])
117 s:RunDbgCmd(buf, 'echo var1', ['3'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200118
Bram Moolenaarbf630112023-05-19 21:41:02 +0100119 s:RunDbgCmd(buf, 'u')
120 s:RunDbgCmd(buf, 'bt', [
121 '->2 function Foo[2]',
122 ' 1 Bar[2]',
123 ' 0 Bazz',
124 'line 3: let var3 = "another var"'])
125 s:RunDbgCmd(buf, 'echo var1', ['1'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200126
Bram Moolenaarbf630112023-05-19 21:41:02 +0100127 # Undefined variables
128 s:RunDbgCmd(buf, 'step')
129 s:RunDbgCmd(buf, 'frame 2')
130 s:RunDbgCmd(buf, 'echo var3', [
131 'Error detected while processing function Foo[2]..Bar[2]..Bazz:',
132 'line 4:',
133 'E121: Undefined variable: var3'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200134
Bram Moolenaarbf630112023-05-19 21:41:02 +0100135 # var3 is defined in this level with some other value
136 s:RunDbgCmd(buf, 'fr 0')
137 s:RunDbgCmd(buf, 'echo var3', ['another var'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200138
Bram Moolenaarbf630112023-05-19 21:41:02 +0100139 s:RunDbgCmd(buf, 'step')
140 s:RunDbgCmd(buf, '')
141 s:RunDbgCmd(buf, '')
142 s:RunDbgCmd(buf, '')
143 s:RunDbgCmd(buf, '')
144 s:RunDbgCmd(buf, 'step', [
145 'function Foo[2]..Bar',
146 'line 3: End of function'])
147 s:RunDbgCmd(buf, 'up')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200148
Bram Moolenaarbf630112023-05-19 21:41:02 +0100149 # Undefined var2
150 s:RunDbgCmd(buf, 'echo var2', [
151 'Error detected while processing function Foo[2]..Bar:',
152 'line 3:',
153 'E121: Undefined variable: var2'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200154
Bram Moolenaarbf630112023-05-19 21:41:02 +0100155 # Var2 is defined with 10
156 s:RunDbgCmd(buf, 'down')
157 s:RunDbgCmd(buf, 'echo var2', ['10'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200158
Bram Moolenaarbf630112023-05-19 21:41:02 +0100159 # Backtrace movements
160 s:RunDbgCmd(buf, 'b', [
161 ' 1 function Foo[2]',
162 '->0 Bar',
163 'line 3: End of function'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200164
Bram Moolenaarbf630112023-05-19 21:41:02 +0100165 # next command cannot go down, we are on bottom
166 s:RunDbgCmd(buf, 'down', ['frame is zero'])
167 s:RunDbgCmd(buf, 'up')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200168
Bram Moolenaarbf630112023-05-19 21:41:02 +0100169 # next command cannot go up, we are on top
170 s:RunDbgCmd(buf, 'up', ['frame at highest level: 1'])
171 s:RunDbgCmd(buf, 'where', [
172 '->1 function Foo[2]',
173 ' 0 Bar',
174 'line 3: End of function'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200175
Bram Moolenaarbf630112023-05-19 21:41:02 +0100176 # fil is not frame or finish, it is file
177 s:RunDbgCmd(buf, 'fil', ['"[No Name]" --No lines in buffer--'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200178
Bram Moolenaarbf630112023-05-19 21:41:02 +0100179 # relative backtrace movement
180 s:RunDbgCmd(buf, 'fr -1')
181 s:RunDbgCmd(buf, 'frame', [
182 ' 1 function Foo[2]',
183 '->0 Bar',
184 'line 3: End of function'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200185
Bram Moolenaarbf630112023-05-19 21:41:02 +0100186 s:RunDbgCmd(buf, 'fr +1')
187 s:RunDbgCmd(buf, 'fram', [
188 '->1 function Foo[2]',
189 ' 0 Bar',
190 'line 3: End of function'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200191
Bram Moolenaarbf630112023-05-19 21:41:02 +0100192 # go beyond limits does not crash
193 s:RunDbgCmd(buf, 'fr 100', ['frame at highest level: 1'])
194 s:RunDbgCmd(buf, 'fra', [
195 '->1 function Foo[2]',
196 ' 0 Bar',
197 'line 3: End of function'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200198
Bram Moolenaarbf630112023-05-19 21:41:02 +0100199 s:RunDbgCmd(buf, 'frame -40', ['frame is zero'])
200 s:RunDbgCmd(buf, 'fram', [
201 ' 1 function Foo[2]',
202 '->0 Bar',
203 'line 3: End of function'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200204
Bram Moolenaarbf630112023-05-19 21:41:02 +0100205 # final result 19
206 s:RunDbgCmd(buf, 'cont', ['19'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200207
Bram Moolenaarbf630112023-05-19 21:41:02 +0100208 # breakpoints tests
Bram Moolenaar113bf062019-04-17 16:54:05 +0200209
Bram Moolenaarbf630112023-05-19 21:41:02 +0100210 # Start a debug session, so that reading the last line from the terminal
211 # works properly.
212 s:RunDbgCmd(buf, ':debug echo Foo()', ['cmd: echo Foo()'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200213
Bram Moolenaarbf630112023-05-19 21:41:02 +0100214 # No breakpoints
215 s:RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200216
Bram Moolenaarbf630112023-05-19 21:41:02 +0100217 # Place some breakpoints
218 s:RunDbgCmd(buf, 'breaka func Bar')
219 s:RunDbgCmd(buf, 'breaklis', [' 1 func Bar line 1'])
220 s:RunDbgCmd(buf, 'breakadd func 3 Bazz')
221 s:RunDbgCmd(buf, 'breaklist', [' 1 func Bar line 1',
222 ' 2 func Bazz line 3'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200223
Bram Moolenaarbf630112023-05-19 21:41:02 +0100224 # Check whether the breakpoints are hit
225 s:RunDbgCmd(buf, 'cont', [
226 'Breakpoint in "Bar" line 1',
227 'function Foo[2]..Bar',
228 'line 1: let var1 = 2 + a:var'])
229 s:RunDbgCmd(buf, 'cont', [
230 'Breakpoint in "Bazz" line 3',
231 'function Foo[2]..Bar[2]..Bazz',
232 'line 3: let var3 = "another var"'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200233
Bram Moolenaarbf630112023-05-19 21:41:02 +0100234 # Delete the breakpoints
235 s:RunDbgCmd(buf, 'breakd 1')
236 s:RunDbgCmd(buf, 'breakli', [' 2 func Bazz line 3'])
237 s:RunDbgCmd(buf, 'breakdel func 3 Bazz')
238 s:RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200239
Bram Moolenaarbf630112023-05-19 21:41:02 +0100240 s:RunDbgCmd(buf, 'cont')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200241
Bram Moolenaarbf630112023-05-19 21:41:02 +0100242 # Make sure the breakpoints are removed
243 s:RunDbgCmd(buf, ':echo Foo()', ['19'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200244
Bram Moolenaarbf630112023-05-19 21:41:02 +0100245 # Delete a non-existing breakpoint
246 s:RunDbgCmd(buf, ':breakdel 2', ['E161: Breakpoint not found: 2'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200247
Bram Moolenaarbf630112023-05-19 21:41:02 +0100248 # Expression breakpoint
249 s:RunDbgCmd(buf, ':breakadd func 2 Bazz')
250 s: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 s:RunDbgCmd(buf, 'step')
255 s:RunDbgCmd(buf, 'step')
256 s:RunDbgCmd(buf, 'breaka expr var3')
257 s:RunDbgCmd(buf, 'breakl', [' 3 func Bazz line 2',
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200258 \ ' 4 expr var3'])
Bram Moolenaarbf630112023-05-19 21:41:02 +0100259 s:RunDbgCmd(buf, 'cont', ['Breakpoint in "Bazz" line 5',
260 'Oldval = "''another var''"',
261 'Newval = "''value2''"',
262 'function Bazz',
263 'line 5: catch'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200264
Bram Moolenaarbf630112023-05-19 21:41:02 +0100265 s:RunDbgCmd(buf, 'breakdel *')
266 s:RunDbgCmd(buf, 'breakl', ['No breakpoints defined'])
Bram Moolenaar113bf062019-04-17 16:54:05 +0200267
Bram Moolenaarbf630112023-05-19 21:41:02 +0100268 # Check for error cases
269 s:RunDbgCmd(buf, 'breakadd abcd', [
270 'Error detected while processing function Bazz:',
271 'line 5:',
272 'E475: Invalid argument: abcd'])
273 s:RunDbgCmd(buf, 'breakadd func', ['E475: Invalid argument: func'])
274 s:RunDbgCmd(buf, 'breakadd func 2', ['E475: Invalid argument: func 2'])
275 s:RunDbgCmd(buf, 'breaka func a()', ['E475: Invalid argument: func a()'])
276 s:RunDbgCmd(buf, 'breakd abcd', ['E475: Invalid argument: abcd'])
277 s:RunDbgCmd(buf, 'breakd func', ['E475: Invalid argument: func'])
278 s:RunDbgCmd(buf, 'breakd func a()', ['E475: Invalid argument: func a()'])
279 s:RunDbgCmd(buf, 'breakd func a', ['E161: Breakpoint not found: func a'])
280 s:RunDbgCmd(buf, 'breakd expr', ['E475: Invalid argument: expr'])
281 s:RunDbgCmd(buf, 'breakd expr x', ['E161: Breakpoint not found: expr x'])
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200282
Bram Moolenaarbf630112023-05-19 21:41:02 +0100283 # finish the current function
284 s:RunDbgCmd(buf, 'finish', [
285 'function Bazz',
286 'line 8: End of function'])
287 s:RunDbgCmd(buf, 'cont')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200288
Bram Moolenaarbf630112023-05-19 21:41:02 +0100289 # Test for :next
290 s:RunDbgCmd(buf, ':debug echo Bar(1)')
291 s:RunDbgCmd(buf, 'step')
292 s:RunDbgCmd(buf, 'next')
293 s:RunDbgCmd(buf, '', [
294 'function Bar',
295 'line 3: return var2'])
296 s:RunDbgCmd(buf, 'c')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200297
Bram Moolenaarbf630112023-05-19 21:41:02 +0100298 # Test for :interrupt
299 s:RunDbgCmd(buf, ':debug echo Bazz(1)')
300 s:RunDbgCmd(buf, 'step')
301 s:RunDbgCmd(buf, 'step')
302 s:RunDbgCmd(buf, 'interrupt', [
303 'Exception thrown: Vim:Interrupt',
304 'function Bazz',
305 'line 5: catch'])
306 s:RunDbgCmd(buf, 'c')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200307
Bram Moolenaarbf630112023-05-19 21:41:02 +0100308 # Test showing local variable in :def function
309 s:RunDbgCmd(buf, ':breakadd func 2 Vim9Func')
310 s:RunDbgCmd(buf, ':call Vim9Func()', ['line 2: for _ in [1, 2]'])
311 s:RunDbgCmd(buf, 'next', ['line 2: for _ in [1, 2]'])
312 s:RunDbgCmd(buf, 'echo cmd', ['confirm'])
313 s:RunDbgCmd(buf, 'breakdel *')
314 s:RunDbgCmd(buf, 'cont')
Bram Moolenaare406ff82022-03-10 20:47:43 +0000315
Bram Moolenaarbf630112023-05-19 21:41:02 +0100316 # Test for :quit
317 s:RunDbgCmd(buf, ':debug echo Foo()')
318 s:RunDbgCmd(buf, 'breakdel *')
319 s:RunDbgCmd(buf, 'breakadd func 3 Foo')
320 s:RunDbgCmd(buf, 'breakadd func 3 Bazz')
321 s:RunDbgCmd(buf, 'cont', [
322 'Breakpoint in "Bazz" line 3',
323 'function Foo[2]..Bar[2]..Bazz',
324 'line 3: let var3 = "another var"'])
325 s:RunDbgCmd(buf, 'quit', [
326 'Breakpoint in "Foo" line 3',
327 'function Foo',
328 'line 3: return var2'])
329 s:RunDbgCmd(buf, 'breakdel *')
330 s:RunDbgCmd(buf, 'quit')
331 s:RunDbgCmd(buf, 'enew! | only!')
Bram Moolenaar0fdd9432019-04-20 22:28:48 +0200332
Bram Moolenaarbf630112023-05-19 21:41:02 +0100333 g:StopVimInTerminal(buf)
334enddef
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', {})
Bram Moolenaarbf630112023-05-19 21:41:02 +0100350 call s:RunDbgCmd(buf, ':breakadd file 2 XdebugBreakadd.vim')
351 call s:RunDbgCmd(buf, ':4 | breakadd here')
352 call s:RunDbgCmd(buf, ':source XdebugBreakadd.vim', ['line 2: let var2 = 20'])
353 call s:RunDbgCmd(buf, 'cont', ['line 4: let var4 = 40'])
354 call s:RunDbgCmd(buf, 'cont')
Bram Moolenaar113bf062019-04-17 16:54:05 +0200355
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', {})
Bram Moolenaarbf630112023-05-19 21:41:02 +0100375 call s:RunDbgCmd(buf, ':let g:Xtest_var = 10')
376 call s:RunDbgCmd(buf, ':breakadd expr g:Xtest_var')
377 call s: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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100384 call s:RunDbgCmd(buf, ':source %', expected)
385 call s: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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100392 call s:RunDbgCmd(buf, ':source %', expected)
Yegappan Lakshmanan885de442022-04-23 10:51:14 +0100393
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 Moolenaarbf630112023-05-19 21:41:02 +0100414 s:RunDbgCmd(buf, ':function g:EarlyFunc',
Bram Moolenaar072f1c62021-09-08 20:40:34 +0200415 ['function EarlyFunc()', 'endfunction'], {match: 'pattern'})
Bram Moolenaarbf630112023-05-19 21:41:02 +0100416 s: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 Moolenaarbf630112023-05-19 21:41:02 +0100438 s: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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100477 call s:RunDbgCmd(buf,
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200478 \ ':debug call GlobalFunction()',
479 \ ['cmd: call GlobalFunction()'])
Bram Moolenaarbf630112023-05-19 21:41:02 +0100480 call s:RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200481
Bram Moolenaarbf630112023-05-19 21:41:02 +0100482 call s:RunDbgCmd(buf, 'backtrace', ['>backtrace',
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200483 \ '->0 function GlobalFunction',
484 \ 'line 1: call CallAFunction()'])
485
Bram Moolenaarbf630112023-05-19 21:41:02 +0100486 call s:RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()'])
487 call s:RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200488
Bram Moolenaarbf630112023-05-19 21:41:02 +0100489 call s:RunDbgCmd(buf, 'backtrace', ['>backtrace',
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200490 \ ' 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.
Bram Moolenaarbf630112023-05-19 21:41:02 +0100497 call s:RunDbgCmd(buf, 'step', ['line 1: func DoAThing()'])
498 call s:RunDbgCmd(buf, 'backtrace', [
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200499 \ '>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 Moolenaarbf630112023-05-19 21:41:02 +0100506 call s:RunDbgCmd( buf, 'up' )
507 call s:RunDbgCmd( buf, 'backtrace', [
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200508 \ '>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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100515 call s:RunDbgCmd( buf, 'up' )
516 call s:RunDbgCmd( buf, 'backtrace', [
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200517 \ '>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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100524 call s:RunDbgCmd( buf, 'up' )
525 call s:RunDbgCmd( buf, 'backtrace', [
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200526 \ '>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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100533 call s:RunDbgCmd( buf, 'up', [ 'frame at highest level: 3' ] )
534 call s:RunDbgCmd( buf, 'backtrace', [
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200535 \ '>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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100542 call s:RunDbgCmd( buf, 'down' )
543 call s:RunDbgCmd( buf, 'backtrace', [
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200544 \ '>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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100551 call s:RunDbgCmd( buf, 'down' )
552 call s:RunDbgCmd( buf, 'backtrace', [
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200553 \ '>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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100560 call s:RunDbgCmd( buf, 'down' )
561 call s:RunDbgCmd( buf, 'backtrace', [
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200562 \ '>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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100569 call s:RunDbgCmd( buf, 'down', [ 'frame is zero' ] )
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +0200570
Dominique Pelle923dce22021-11-21 11:36:04 +0000571 " step until we have another meaningful trace
Bram Moolenaarbf630112023-05-19 21:41:02 +0100572 call s:RunDbgCmd(buf, 'step', ['line 5: func File2Function()'])
573 call s:RunDbgCmd(buf, 'step', ['line 9: call File2Function()'])
574 call s:RunDbgCmd(buf, 'backtrace', [
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200575 \ '>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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100582 call s:RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
583 call s:RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"'])
584 call s:RunDbgCmd(buf, 'backtrace', [
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200585 \ '>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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100595 call s:RunDbgCmd(buf, 'step', ['line 1: End of function'])
596 call s:RunDbgCmd(buf, 'step', ['line 1: End of function'])
597 call s:RunDbgCmd(buf, 'step', ['line 10: End of sourced file'])
598 call s:RunDbgCmd(buf, 'step', ['line 1: End of function'])
599 call s:RunDbgCmd(buf, 'step', ['line 2: call File2Function()'])
600 call s:RunDbgCmd(buf, 'backtrace', [
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200601 \ '>backtrace',
602 \ ' 1 function GlobalFunction[1]',
603 \ '->0 CallAFunction',
604 \ 'line 2: call File2Function()'])
605
Bram Moolenaarbf630112023-05-19 21:41:02 +0100606 call s:RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
607 call s:RunDbgCmd(buf, 'backtrace', [
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200608 \ '>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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100652 call s:RunDbgCmd(buf,
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200653 \ ':debug doautocmd User TestGlobalFunction',
654 \ ['cmd: doautocmd User TestGlobalFunction'])
Bram Moolenaarbf630112023-05-19 21:41:02 +0100655 call s:RunDbgCmd(buf, 'step', ['cmd: call GlobalFunction() | echo "Done"'])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200656
Dominique Pelle923dce22021-11-21 11:36:04 +0000657 " At this point the only thing in the stack is the autocommand
Bram Moolenaarbf630112023-05-19 21:41:02 +0100658 call s:RunDbgCmd(buf, 'backtrace', [
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200659 \ '>backtrace',
660 \ '->0 User Autocommands for "TestGlobalFunction"',
661 \ 'cmd: call GlobalFunction() | echo "Done"'])
662
663 " And now we're back into the call stack
Bram Moolenaarbf630112023-05-19 21:41:02 +0100664 call s:RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
665 call s:RunDbgCmd(buf, 'backtrace', [
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200666 \ '>backtrace',
667 \ ' 1 User Autocommands for "TestGlobalFunction"',
668 \ '->0 function GlobalFunction',
669 \ 'line 1: call CallAFunction()'])
670
Bram Moolenaarbf630112023-05-19 21:41:02 +0100671 call s:RunDbgCmd(buf, 'step', ['line 1: call SourceAnotherFile()'])
672 call s:RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200673
Bram Moolenaarbf630112023-05-19 21:41:02 +0100674 call s:RunDbgCmd(buf, 'backtrace', [
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200675 \ '>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.
Bram Moolenaarbf630112023-05-19 21:41:02 +0100684 call s:RunDbgCmd(buf, 'step', ['line 1: func DoAThing()'])
685 call s:RunDbgCmd(buf, 'backtrace', [
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200686 \ '>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 Moolenaarbf630112023-05-19 21:41:02 +0100694 call s:RunDbgCmd( buf, 'up' )
695 call s:RunDbgCmd( buf, 'backtrace', [
Bram Moolenaarc63b72b2020-08-22 16:04:52 +0200696 \ '>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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100704 call s:RunDbgCmd( buf, 'up' )
705 call s:RunDbgCmd( buf, 'backtrace', [
Bram Moolenaarc63b72b2020-08-22 16:04:52 +0200706 \ '>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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100714 call s:RunDbgCmd( buf, 'up' )
715 call s:RunDbgCmd( buf, 'backtrace', [
Bram Moolenaarc63b72b2020-08-22 16:04:52 +0200716 \ '>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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100724 call s:RunDbgCmd( buf, 'up' )
725 call s:RunDbgCmd( buf, 'backtrace', [
Bram Moolenaarc63b72b2020-08-22 16:04:52 +0200726 \ '>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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100734 call s:RunDbgCmd( buf, 'up', [ 'frame at highest level: 4' ] )
735 call s:RunDbgCmd( buf, 'backtrace', [
Bram Moolenaarc63b72b2020-08-22 16:04:52 +0200736 \ '>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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100744 call s:RunDbgCmd( buf, 'down' )
745 call s:RunDbgCmd( buf, 'backtrace', [
Bram Moolenaarc63b72b2020-08-22 16:04:52 +0200746 \ '>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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100755 call s:RunDbgCmd( buf, 'down' )
756 call s:RunDbgCmd( buf, 'backtrace', [
Bram Moolenaarc63b72b2020-08-22 16:04:52 +0200757 \ '>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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100765 call s:RunDbgCmd( buf, 'down' )
766 call s:RunDbgCmd( buf, 'backtrace', [
Bram Moolenaarc63b72b2020-08-22 16:04:52 +0200767 \ '>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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100775 call s:RunDbgCmd( buf, 'down' )
776 call s:RunDbgCmd( buf, 'backtrace', [
Bram Moolenaarc63b72b2020-08-22 16:04:52 +0200777 \ '>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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100785 call s:RunDbgCmd( buf, 'down', [ 'frame is zero' ] )
Bram Moolenaarc63b72b2020-08-22 16:04:52 +0200786
Dominique Pelle923dce22021-11-21 11:36:04 +0000787 " step until we have another meaningful trace
Bram Moolenaarbf630112023-05-19 21:41:02 +0100788 call s:RunDbgCmd(buf, 'step', ['line 5: func File2Function()'])
789 call s:RunDbgCmd(buf, 'step', ['line 9: call File2Function()'])
790 call s:RunDbgCmd(buf, 'backtrace', [
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200791 \ '>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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100799 call s:RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
800 call s:RunDbgCmd(buf, 'step', ['line 1: echo "DoAThing"'])
801 call s:RunDbgCmd(buf, 'backtrace', [
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200802 \ '>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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100813 call s:RunDbgCmd(buf, 'step', ['line 1: End of function'])
814 call s:RunDbgCmd(buf, 'step', ['line 1: End of function'])
815 call s:RunDbgCmd(buf, 'step', ['line 10: End of sourced file'])
816 call s:RunDbgCmd(buf, 'step', ['line 1: End of function'])
817 call s:RunDbgCmd(buf, 'step', ['line 2: call File2Function()'])
818 call s:RunDbgCmd(buf, 'backtrace', [
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200819 \ '>backtrace',
820 \ ' 2 User Autocommands for "TestGlobalFunction"',
821 \ ' 1 function GlobalFunction[1]',
822 \ '->0 CallAFunction',
823 \ 'line 2: call File2Function()'])
824
Bram Moolenaarbf630112023-05-19 21:41:02 +0100825 call s:RunDbgCmd(buf, 'step', ['line 1: call DoAThing()'])
826 call s:RunDbgCmd(buf, 'backtrace', [
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200827 \ '>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")
Bram Moolenaarbf630112023-05-19 21:41:02 +0100837 call s:RunDbgCmd(buf, 'finish', ['line 1: End of function'])
838 call s:RunDbgCmd(buf, 'backtrace', [
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200839 \ '>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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100846 call s:RunDbgCmd(buf, 'finish', ['line 2: End of function'])
847 call s:RunDbgCmd(buf, 'backtrace', [
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200848 \ '>backtrace',
849 \ ' 2 User Autocommands for "TestGlobalFunction"',
850 \ ' 1 function GlobalFunction[1]',
851 \ '->0 CallAFunction',
852 \ 'line 2: End of function'])
853
Bram Moolenaarbf630112023-05-19 21:41:02 +0100854 call s:RunDbgCmd(buf, 'finish', ['line 1: End of function'])
855 call s:RunDbgCmd(buf, 'backtrace', [
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200856 \ '>backtrace',
857 \ ' 1 User Autocommands for "TestGlobalFunction"',
858 \ '->0 function GlobalFunction',
859 \ 'line 1: End of function'])
860
Bram Moolenaarbf630112023-05-19 21:41:02 +0100861 call s:RunDbgCmd(buf, 'step', ['cmd: echo "Done"'])
862 call s:RunDbgCmd(buf, 'backtrace', [
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200863 \ '>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 Moolenaarbf630112023-05-19 21:41:02 +0100909 call s: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 Moolenaarbf630112023-05-19 21:41:02 +0100913 call s:RunDbgCmd(buf, 'backtrace', [
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200914 \ '>backtrace',
915 \ '->0 command line',
916 \ 'cmd: call GlobalFunction()'])
917
918 " And now we're back into the call stack
Bram Moolenaarbf630112023-05-19 21:41:02 +0100919 call s:RunDbgCmd(buf, 'step', ['line 1: call CallAFunction()'])
920 call s:RunDbgCmd(buf, 'backtrace', [
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200921 \ '>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
Bram Moolenaarbf630112023-05-19 21:41:02 +0100973 call s:RunDbgCmd(buf,
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200974 \ ':debug call GlobalFunction()',
975 \ ['cmd: call GlobalFunction()'])
976
Bram Moolenaarbf630112023-05-19 21:41:02 +0100977 call s:RunDbgCmd(buf, 'step', ['line 1: var some = "some var"'])
978 call s:RunDbgCmd(buf, 'step', ['line 2: CallAFunction()'])
979 call s:RunDbgCmd(buf, 'echo some', ['some var'])
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200980
Bram Moolenaarbf630112023-05-19 21:41:02 +0100981 call s:RunDbgCmd(buf, 'backtrace', [
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200982 \ '\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 Moolenaarbf630112023-05-19 21:41:02 +0100988 call s:RunDbgCmd(buf, 'step', ['line 1: SourceAnotherFile()'])
989 call s: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 Moolenaarbf630112023-05-19 21:41:02 +0100992 call s:RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
993 call s:RunDbgCmd(buf, 'step', ['line 1: vim9script'])
994 call s:RunDbgCmd(buf, 'step', ['line 3: def DoAThing(): number'])
995 call s:RunDbgCmd(buf, 'step', ['line 9: export def File2Function()'])
996 call s:RunDbgCmd(buf, 'step', ['line 13: defcompile'])
997 call s:RunDbgCmd(buf, 'step', ['line 14: File2Function()'])
998 call s:RunDbgCmd(buf, 'backtrace', [
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +0200999 \ '\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 Moolenaarbf630112023-05-19 21:41:02 +01001008 call s:RunDbgCmd(buf, 'next', ['line 15: End of sourced file'])
1009 call s:RunDbgCmd(buf, 'backtrace', [
Bram Moolenaar6ca6ca42020-07-27 19:47:07 +02001010 \ '\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
Bram Moolenaarbf630112023-05-19 21:41:02 +01001035 call s:RunDbgCmd(buf, ':breakadd expr g:someVar')
1036 call s:RunDbgCmd(buf, ':call g:ChangeVar()', ['Oldval = "''foo''"', 'Newval = "''bar''"', 'function ChangeVar', 'line 2: echo "changed"'])
Bram Moolenaar26a44842021-09-02 18:49:06 +02001037
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
Bram Moolenaarbf630112023-05-19 21:41:02 +01001071 call s:RunDbgCmd(buf,':call SomeFunc()', ['line 2: echo "and"'])
1072 call s:RunDbgCmd(buf,'next', ['line 3: echo "there"'])
1073 call s:RunDbgCmd(buf,'next', ['line 4: breakadd func 2 LocalFunc'])
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001074
1075 " continue, next breakpoint is in LocalFunc()
Bram Moolenaarbf630112023-05-19 21:41:02 +01001076 call s:RunDbgCmd(buf,'cont', ['line 2: echo "second"'])
Bram Moolenaar2ac4b252021-06-20 20:09:42 +02001077
1078 " continue, next breakpoint is in LegacyFunc()
Bram Moolenaarbf630112023-05-19 21:41:02 +01001079 call s:RunDbgCmd(buf,'cont', ['line 1: echo "legone"'])
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001080
Bram Moolenaarbf630112023-05-19 21:41:02 +01001081 call s:RunDbgCmd(buf, 'cont')
Bram Moolenaar4f8f5422021-06-20 19:28:14 +02001082
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
Bram Moolenaarbf630112023-05-19 21:41:02 +01001143 call s:RunDbgCmd(buf,
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001144 \ ':debug call Func()',
1145 \ ['cmd: call Func()'])
Bram Moolenaarbf630112023-05-19 21:41:02 +01001146 call s:RunDbgCmd(buf, 'next', ['result: 3'])
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001147 call term_sendkeys(buf, "\r")
Bram Moolenaarbf630112023-05-19 21:41:02 +01001148 call s:RunDbgCmd(buf, 'cont')
Bram Moolenaar968a5b62021-06-15 19:32:40 +02001149
Bram Moolenaarbf630112023-05-19 21:41:02 +01001150 call s:RunDbgCmd(buf,
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001151 \ ':debug call FuncWithArgs("asdf", 42, 1, 2, 3)',
1152 \ ['cmd: call FuncWithArgs("asdf", 42, 1, 2, 3)'])
Bram Moolenaarbf630112023-05-19 21:41:02 +01001153 call s:RunDbgCmd(buf, 'step', ['line 1: echo text .. nr'])
1154 call s:RunDbgCmd(buf, 'echo text', ['asdf'])
1155 call s:RunDbgCmd(buf, 'echo nr', ['42'])
1156 call s:RunDbgCmd(buf, 'echo items', ['[1, 2, 3]'])
1157 call s:RunDbgCmd(buf, 'step', ['asdf42', 'function FuncWithArgs', 'line 2: for it in items'])
1158 call s:RunDbgCmd(buf, 'step', ['function FuncWithArgs', 'line 2: for it in items'])
1159 call s:RunDbgCmd(buf, 'echo it', ['0'])
1160 call s:RunDbgCmd(buf, 'step', ['line 3: echo it'])
1161 call s:RunDbgCmd(buf, 'echo it', ['1'])
1162 call s:RunDbgCmd(buf, 'step', ['1', 'function FuncWithArgs', 'line 4: endfor'])
1163 call s:RunDbgCmd(buf, 'step', ['line 2: for it in items'])
1164 call s:RunDbgCmd(buf, 'echo it', ['1'])
1165 call s:RunDbgCmd(buf, 'step', ['line 3: echo it'])
1166 call s:RunDbgCmd(buf, 'step', ['2', 'function FuncWithArgs', 'line 4: endfor'])
1167 call s:RunDbgCmd(buf, 'step', ['line 2: for it in items'])
1168 call s:RunDbgCmd(buf, 'echo it', ['2'])
1169 call s:RunDbgCmd(buf, 'step', ['line 3: echo it'])
1170 call s:RunDbgCmd(buf, 'step', ['3', 'function FuncWithArgs', 'line 4: endfor'])
1171 call s:RunDbgCmd(buf, 'step', ['line 2: for it in items'])
1172 call s:RunDbgCmd(buf, 'step', ['line 5: echo "done"'])
1173 call s:RunDbgCmd(buf, 'cont')
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001174
Bram Moolenaarbf630112023-05-19 21:41:02 +01001175 call s:RunDbgCmd(buf,
Bram Moolenaar4cea5362021-06-16 22:24:40 +02001176 \ ':debug call FuncWithDict()',
1177 \ ['cmd: call FuncWithDict()'])
Bram Moolenaarbf630112023-05-19 21:41:02 +01001178 call s:RunDbgCmd(buf, 'step', ['line 1: var d = { a: 1, b: 2, }'])
1179 call s:RunDbgCmd(buf, 'step', ['line 6: def Inner()'])
1180 call s:RunDbgCmd(buf, 'cont')
Bram Moolenaar8cec9272021-06-23 20:20:53 +02001181
Bram Moolenaarbf630112023-05-19 21:41:02 +01001182 call s:RunDbgCmd(buf, ':breakadd func 1 FuncComment')
1183 call s:RunDbgCmd(buf, ':call FuncComment()', ['function FuncComment', 'line 2: echo "first" .. "one"'])
1184 call s:RunDbgCmd(buf, ':breakadd func 3 FuncComment')
1185 call s:RunDbgCmd(buf, 'cont', ['function FuncComment', 'line 5: echo "second"'])
1186 call s:RunDbgCmd(buf, 'cont')
Bram Moolenaar6fc01612021-07-03 13:36:31 +02001187
Bram Moolenaarbf630112023-05-19 21:41:02 +01001188 call s:RunDbgCmd(buf, ':breakadd func 2 FuncForLoop')
1189 call s:RunDbgCmd(buf, ':call FuncForLoop()', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]'])
1190 call s:RunDbgCmd(buf, 'step', ['line 2: for i in [11, 22, 33]'])
1191 call s:RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 3: eval i + 2'])
1192 call s:RunDbgCmd(buf, 'echo i', ['11'])
1193 call s:RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 4: endfor'])
1194 call s:RunDbgCmd(buf, 'next', ['function FuncForLoop', 'line 2: for i in [11, 22, 33]'])
1195 call s:RunDbgCmd(buf, 'next', ['line 3: eval i + 2'])
1196 call s:RunDbgCmd(buf, 'echo i', ['22'])
Bram Moolenaar6bc30b02021-06-16 19:19:55 +02001197
Bram Moolenaarbf630112023-05-19 21:41:02 +01001198 call s:RunDbgCmd(buf, 'breakdel *')
1199 call s:RunDbgCmd(buf, 'cont')
Bram Moolenaar303215d2021-07-07 20:10:43 +02001200
Bram Moolenaarbf630112023-05-19 21:41:02 +01001201 call s:RunDbgCmd(buf, ':breakadd func FuncWithSplitLine')
1202 call s:RunDbgCmd(buf, ':call FuncWithSplitLine()', ['function FuncWithSplitLine', 'line 1: eval 1 + 2 | eval 2 + 3'])
Bram Moolenaar303215d2021-07-07 20:10:43 +02001203
Bram Moolenaarbf630112023-05-19 21:41:02 +01001204 call s: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
Bram Moolenaarbf630112023-05-19 21:41:02 +01001223 call s:RunDbgCmd(buf,
Bram Moolenaar17d868b2021-06-27 16:29:53 +02001224 \ ':call g:Func()',
1225 \ ['function Func', 'line 2: [''b'']->map((_, v) => s)'])
Bram Moolenaarbf630112023-05-19 21:41:02 +01001226 call s:RunDbgCmd(buf,
Bram Moolenaar17d868b2021-06-27 16:29:53 +02001227 \ 'next',
1228 \ ['function Func', 'line 3: echo "done"'])
1229
Bram Moolenaarbf630112023-05-19 21:41:02 +01001230 call s:RunDbgCmd(buf, 'cont')
Bram Moolenaar17d868b2021-06-27 16:29:53 +02001231 call StopVimInTerminal(buf)
Bram Moolenaar17d868b2021-06-27 16:29:53 +02001232endfunc
1233
Bram Moolenaarbf630112023-05-19 21:41:02 +01001234def Test_debug_backtrace_level()
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001235 CheckCWD
Bram Moolenaarbf630112023-05-19 21:41:02 +01001236 var lines =<< trim END
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001237 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 Moolenaarbf630112023-05-19 21:41:02 +01001249 writefile(lines, 'Xtest1.vim', 'D')
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001250
Bram Moolenaarbf630112023-05-19 21:41:02 +01001251 lines =<< trim END
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001252 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 Moolenaarbf630112023-05-19 21:41:02 +01001262 writefile(lines, 'Xtest2.vim', 'D')
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001263
Bram Moolenaarbf630112023-05-19 21:41:02 +01001264 var file1 = getcwd() .. '/Xtest1.vim'
1265 var file2 = getcwd() .. '/Xtest2.vim'
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001266
Bram Moolenaarbf630112023-05-19 21:41:02 +01001267 # set a breakpoint and source file1.vim
1268 var buf = g:RunVimInTerminal(
1269 '-c "breakadd file 1 Xtest1.vim" -S Xtest1.vim',
1270 {wait_for_ruler: 0})
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001271
Bram Moolenaarbf630112023-05-19 21:41:02 +01001272 s: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'''
1277 ], {msec: 5000})
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001278
Bram Moolenaarbf630112023-05-19 21:41:02 +01001279 # step through the initial declarations
1280 s:RunDbgCmd(buf, 'step', [ 'line 2: let g:global_var = ''global''' ] )
1281 s:RunDbgCmd(buf, 'step', [ 'line 4: func s:File1Func( arg )' ] )
1282 s:RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1283 s:RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1284 s:RunDbgCmd(buf, 'echo global_var', [ 'global' ] )
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001285
Bram Moolenaarbf630112023-05-19 21:41:02 +01001286 # step in to the first function
1287 s:RunDbgCmd(buf, 'step', [ 'line 11: call s:File1Func( ''arg1'' )' ] )
1288 s:RunDbgCmd(buf, 'step', [ 'line 1: let s:file1_var .= a:arg' ] )
1289 s:RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] )
1290 s:RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1291 s:RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1292 s:RunDbgCmd(buf,
1293 'echo global_var',
1294 [ 'E121: Undefined variable: global_var' ] )
1295 s:RunDbgCmd(buf,
1296 'echo local_var',
1297 [ 'E121: Undefined variable: local_var' ] )
1298 s:RunDbgCmd(buf,
1299 'echo l:local_var',
1300 [ 'E121: Undefined variable: l:local_var' ] )
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001301
Bram Moolenaarbf630112023-05-19 21:41:02 +01001302 # backtrace up
1303 s: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 s:RunDbgCmd(buf, 'up', [ '>up' ] )
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001312
Bram Moolenaarbf630112023-05-19 21:41:02 +01001313 s: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' } )
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001321
Bram Moolenaarbf630112023-05-19 21:41:02 +01001322 # Expression evaluation in the script frame (not the function frame)
1323 # FIXME: Unexpected in this scope (a: should not be visible)
1324 s:RunDbgCmd(buf, 'echo a:arg', [ 'arg1' ] )
1325 s:RunDbgCmd(buf, 'echo s:file1_var', [ 'file1' ] )
1326 s:RunDbgCmd(buf, 'echo g:global_var', [ 'global' ] )
1327 # FIXME: Unexpected in this scope (global should be found)
1328 s:RunDbgCmd(buf,
1329 'echo global_var',
1330 [ 'E121: Undefined variable: global_var' ] )
1331 s:RunDbgCmd(buf,
1332 'echo local_var',
1333 [ 'E121: Undefined variable: local_var' ] )
1334 s:RunDbgCmd(buf,
1335 'echo l:local_var',
1336 [ 'E121: Undefined variable: l:local_var' ] )
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001337
1338
Bram Moolenaarbf630112023-05-19 21:41:02 +01001339 # step while backtraced jumps to the latest frame
1340 s:RunDbgCmd(buf, 'step', [
1341 'line 2: let local_var = s:file1_var .. '' test1''' ] )
1342 s: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' } )
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001350
Bram Moolenaarbf630112023-05-19 21:41:02 +01001351 s:RunDbgCmd(buf, 'step', [ 'line 3: let g:global_var .= local_var' ] )
1352 s:RunDbgCmd(buf, 'echo local_var', [ 'file1arg1 test1' ] )
1353 s:RunDbgCmd(buf, 'echo l:local_var', [ 'file1arg1 test1' ] )
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001354
Bram Moolenaarbf630112023-05-19 21:41:02 +01001355 s:RunDbgCmd(buf, 'step', [ 'line 4: source Xtest2.vim' ] )
1356 s:RunDbgCmd(buf, 'step', [ 'line 1: let s:file2_var = ''file2''' ] )
1357 s: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' } )
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001366
Bram Moolenaarbf630112023-05-19 21:41:02 +01001367 # Expression evaluation in the script frame file2 (not the function frame)
1368 s:RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] )
1369 s:RunDbgCmd(buf,
1370 'echo s:file1_var',
1371 [ 'E121: Undefined variable: s:file1_var' ] )
1372 s:RunDbgCmd(buf, 'echo g:global_var', [ 'globalfile1arg1 test1' ] )
1373 s:RunDbgCmd(buf, 'echo global_var', [ 'globalfile1arg1 test1' ] )
1374 s:RunDbgCmd(buf,
1375 'echo local_var',
1376 [ 'E121: Undefined variable: local_var' ] )
1377 s:RunDbgCmd(buf,
1378 'echo l:local_var',
1379 [ 'E121: Undefined variable: l:local_var' ] )
1380 s:RunDbgCmd(buf,
1381 'echo s:file2_var',
1382 [ 'E121: Undefined variable: s:file2_var' ] )
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001383
Bram Moolenaarbf630112023-05-19 21:41:02 +01001384 s:RunDbgCmd(buf, 'step', [ 'line 3: func s:File2Func( arg )' ] )
1385 s:RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] )
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001386
Bram Moolenaarbf630112023-05-19 21:41:02 +01001387 # Up the stack to the other script context
1388 s:RunDbgCmd(buf, 'up')
1389 s: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 s:RunDbgCmd(buf, 'echo a:arg', [ 'E121: Undefined variable: a:arg' ] )
1400 s:RunDbgCmd(buf,
1401 'echo l:local_var',
1402 [ 'E121: Undefined variable: l:local_var' ] )
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001403
Bram Moolenaarbf630112023-05-19 21:41:02 +01001404 s:RunDbgCmd(buf, 'up')
1405 s: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' } )
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001414
Bram Moolenaarbf630112023-05-19 21:41:02 +01001415 # FIXME: Unexpected (wrong script vars are used)
1416 s:RunDbgCmd(buf,
1417 'echo s:file1_var',
1418 [ 'E121: Undefined variable: s:file1_var' ] )
1419 s:RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] )
Bram Moolenaarb7f4fa52020-08-08 14:41:52 +02001420
Bram Moolenaarbf630112023-05-19 21:41:02 +01001421 s:RunDbgCmd(buf, 'cont')
1422 g:StopVimInTerminal(buf)
1423enddef
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