comparison runtime/pack/dist/opt/termdebug/plugin/termdebug.vim @ 12833:db9ffed7e1fc v8.0.1293

patch 8.0.1293: setting a breakpoint in the terminal debugger sometimes fails commit https://github.com/vim/vim/commit/60e73f2acc890f07056fa1bea8dbe89d26918b3e Author: Bram Moolenaar <Bram@vim.org> Date: Sun Nov 12 18:02:06 2017 +0100 patch 8.0.1293: setting a breakpoint in the terminal debugger sometimes fails Problem: Setting a breakpoint in the terminal debugger sometimes fails. Solution: Interrupt the program if needed. Set the interface to async.
author Christian Brabandt <cb@256bit.org>
date Sun, 12 Nov 2017 18:15:04 +0100
parents f690da1b3c04
children ebb4f6c93598
comparison
equal deleted inserted replaced
12832:3b4c04beb913 12833:db9ffed7e1fc
18 " In case this gets loaded twice. 18 " In case this gets loaded twice.
19 if exists(':Termdebug') 19 if exists(':Termdebug')
20 finish 20 finish
21 endif 21 endif
22 22
23 " Uncomment this line to write logging in "debuglog".
24 " call ch_logfile('debuglog', 'w')
25
23 " The command that starts debugging, e.g. ":Termdebug vim". 26 " The command that starts debugging, e.g. ":Termdebug vim".
24 " To end type "quit" in the gdb window. 27 " To end type "quit" in the gdb window.
25 command -nargs=* -complete=file Termdebug call s:StartDebug(<q-args>) 28 command -nargs=* -complete=file Termdebug call s:StartDebug(<q-args>)
26 29
27 " Name of the gdb command, defaults to "gdb". 30 " Name of the gdb command, defaults to "gdb".
29 let termdebugger = 'gdb' 32 let termdebugger = 'gdb'
30 endif 33 endif
31 34
32 let s:pc_id = 12 35 let s:pc_id = 12
33 let s:break_id = 13 36 let s:break_id = 13
37 let s:stopped = 1
34 38
35 if &background == 'light' 39 if &background == 'light'
36 hi default debugPC term=reverse ctermbg=lightblue guibg=lightblue 40 hi default debugPC term=reverse ctermbg=lightblue guibg=lightblue
37 else 41 else
38 hi default debugPC term=reverse ctermbg=darkblue guibg=darkblue 42 hi default debugPC term=reverse ctermbg=darkblue guibg=darkblue
81 85
82 " Open a terminal window to run the debugger. 86 " Open a terminal window to run the debugger.
83 " Add -quiet to avoid the intro message causing a hit-enter prompt. 87 " Add -quiet to avoid the intro message causing a hit-enter prompt.
84 let cmd = [g:termdebugger, '-quiet', '-tty', pty, a:cmd] 88 let cmd = [g:termdebugger, '-quiet', '-tty', pty, a:cmd]
85 echomsg 'executing "' . join(cmd) . '"' 89 echomsg 'executing "' . join(cmd) . '"'
86 let gdbbuf = term_start(cmd, { 90 let s:gdbbuf = term_start(cmd, {
87 \ 'exit_cb': function('s:EndDebug'), 91 \ 'exit_cb': function('s:EndDebug'),
88 \ 'term_finish': 'close', 92 \ 'term_finish': 'close',
89 \ }) 93 \ })
90 if gdbbuf == 0 94 if s:gdbbuf == 0
91 echoerr 'Failed to open the gdb terminal window' 95 echoerr 'Failed to open the gdb terminal window'
92 exe 'bwipe! ' . s:ptybuf 96 exe 'bwipe! ' . s:ptybuf
93 exe 'bwipe! ' . s:commbuf 97 exe 'bwipe! ' . s:commbuf
94 return 98 return
95 endif 99 endif
96 let s:gdbwin = win_getid(winnr()) 100 let s:gdbwin = win_getid(winnr())
97 101
98 " Connect gdb to the communication pty, using the GDB/MI interface 102 " Connect gdb to the communication pty, using the GDB/MI interface
99 " If you get an error "undefined command" your GDB is too old. 103 " If you get an error "undefined command" your GDB is too old.
100 call term_sendkeys(gdbbuf, 'new-ui mi ' . commpty . "\r") 104 call term_sendkeys(s:gdbbuf, 'new-ui mi ' . commpty . "\r")
105
106 " Interpret commands while the target is running. This should usualy only be
107 " exec-interrupt, since many commands don't work properly while the target is
108 " running.
109 call s:SendCommand('-gdb-set mi-async on')
101 110
102 " Sign used to highlight the line where the program has stopped. 111 " Sign used to highlight the line where the program has stopped.
103 " There can be only one. 112 " There can be only one.
104 sign define debugPC linehl=debugPC 113 sign define debugPC linehl=debugPC
105 114
168 command Break call s:SetBreakpoint() 177 command Break call s:SetBreakpoint()
169 command Delete call s:DeleteBreakpoint() 178 command Delete call s:DeleteBreakpoint()
170 command Step call s:SendCommand('-exec-step') 179 command Step call s:SendCommand('-exec-step')
171 command Over call s:SendCommand('-exec-next') 180 command Over call s:SendCommand('-exec-next')
172 command Finish call s:SendCommand('-exec-finish') 181 command Finish call s:SendCommand('-exec-finish')
182 command -nargs=* Run call s:Run(<q-args>)
183 command -nargs=* Arguments call s:SendCommand('-exec-arguments ' . <q-args>)
184 command Stop call s:SendCommand('-exec-interrupt')
173 command Continue call s:SendCommand('-exec-continue') 185 command Continue call s:SendCommand('-exec-continue')
174 command -range -nargs=* Evaluate call s:Evaluate(<range>, <q-args>) 186 command -range -nargs=* Evaluate call s:Evaluate(<range>, <q-args>)
175 command Gdb call win_gotoid(s:gdbwin) 187 command Gdb call win_gotoid(s:gdbwin)
176 command Program call win_gotoid(s:ptywin) 188 command Program call win_gotoid(s:ptywin)
177 189
181 if has('menu') 193 if has('menu')
182 nnoremenu WinBar.Step :Step<CR> 194 nnoremenu WinBar.Step :Step<CR>
183 nnoremenu WinBar.Next :Over<CR> 195 nnoremenu WinBar.Next :Over<CR>
184 nnoremenu WinBar.Finish :Finish<CR> 196 nnoremenu WinBar.Finish :Finish<CR>
185 nnoremenu WinBar.Cont :Continue<CR> 197 nnoremenu WinBar.Cont :Continue<CR>
198 nnoremenu WinBar.Stop :Stop<CR>
186 nnoremenu WinBar.Eval :Evaluate<CR> 199 nnoremenu WinBar.Eval :Evaluate<CR>
187 endif 200 endif
188 endfunc 201 endfunc
189 202
190 " Delete installed debugger commands in the current window. 203 " Delete installed debugger commands in the current window.
192 delcommand Break 205 delcommand Break
193 delcommand Delete 206 delcommand Delete
194 delcommand Step 207 delcommand Step
195 delcommand Over 208 delcommand Over
196 delcommand Finish 209 delcommand Finish
210 delcommand Run
211 delcommand Arguments
212 delcommand Stop
197 delcommand Continue 213 delcommand Continue
198 delcommand Evaluate 214 delcommand Evaluate
199 delcommand Gdb 215 delcommand Gdb
200 delcommand Program 216 delcommand Program
201 217
204 if has('menu') 220 if has('menu')
205 aunmenu WinBar.Step 221 aunmenu WinBar.Step
206 aunmenu WinBar.Next 222 aunmenu WinBar.Next
207 aunmenu WinBar.Finish 223 aunmenu WinBar.Finish
208 aunmenu WinBar.Cont 224 aunmenu WinBar.Cont
225 aunmenu WinBar.Stop
209 aunmenu WinBar.Eval 226 aunmenu WinBar.Eval
210 endif 227 endif
211 228
212 exe 'sign unplace ' . s:pc_id 229 exe 'sign unplace ' . s:pc_id
213 for key in keys(s:breakpoints) 230 for key in keys(s:breakpoints)
218 unlet s:breakpoints 235 unlet s:breakpoints
219 endfunc 236 endfunc
220 237
221 " :Break - Set a breakpoint at the cursor position. 238 " :Break - Set a breakpoint at the cursor position.
222 func s:SetBreakpoint() 239 func s:SetBreakpoint()
223 call term_sendkeys(s:commbuf, '-break-insert --source ' 240 " Setting a breakpoint may not work while the program is running.
224 \ . fnameescape(expand('%:p')) . ' --line ' . line('.') . "\r") 241 " Interrupt to make it work.
242 let do_continue = 0
243 if !s:stopped
244 let do_continue = 1
245 call s:SendCommand('-exec-interrupt')
246 sleep 10m
247 endif
248 call s:SendCommand('-break-insert --source '
249 \ . fnameescape(expand('%:p')) . ' --line ' . line('.'))
250 if do_continue
251 call s:SendCommand('-exec-continue')
252 endif
225 endfunc 253 endfunc
226 254
227 " :Delete - Delete a breakpoint at the cursor position. 255 " :Delete - Delete a breakpoint at the cursor position.
228 func s:DeleteBreakpoint() 256 func s:DeleteBreakpoint()
229 let fname = fnameescape(expand('%:p')) 257 let fname = fnameescape(expand('%:p'))
240 endfunc 268 endfunc
241 269
242 " :Next, :Continue, etc - send a command to gdb 270 " :Next, :Continue, etc - send a command to gdb
243 func s:SendCommand(cmd) 271 func s:SendCommand(cmd)
244 call term_sendkeys(s:commbuf, a:cmd . "\r") 272 call term_sendkeys(s:commbuf, a:cmd . "\r")
273 endfunc
274
275 func s:Run(args)
276 if a:args != ''
277 call s:SendCommand('-exec-arguments ' . a:args)
278 endif
279 call s:SendCommand('-exec-run')
245 endfunc 280 endfunc
246 281
247 " :Evaluate - evaluate what is under the cursor 282 " :Evaluate - evaluate what is under the cursor
248 func s:Evaluate(range, arg) 283 func s:Evaluate(range, arg)
249 if a:arg != '' 284 if a:arg != ''
257 call setpos('.', pos) 292 call setpos('.', pos)
258 call setreg('v', reg, regt) 293 call setreg('v', reg, regt)
259 else 294 else
260 let expr = expand('<cexpr>') 295 let expr = expand('<cexpr>')
261 endif 296 endif
262 call term_sendkeys(s:commbuf, '-data-evaluate-expression "' . expr . "\"\r") 297 call s:SendCommand('-data-evaluate-expression "' . expr . '"')
263 let s:evalexpr = expr 298 let s:evalexpr = expr
264 endfunc 299 endfunc
265 300
266 " Handle the result of data-evaluate-expression 301 " Handle the result of data-evaluate-expression
267 func s:HandleEvaluate(msg) 302 func s:HandleEvaluate(msg)
283 318
284 " Handle stopping and running message from gdb. 319 " Handle stopping and running message from gdb.
285 " Will update the sign that shows the current position. 320 " Will update the sign that shows the current position.
286 func s:HandleCursor(msg) 321 func s:HandleCursor(msg)
287 let wid = win_getid(winnr()) 322 let wid = win_getid(winnr())
323
324 if a:msg =~ '^\*stopped'
325 let s:stopped = 1
326 elseif a:msg =~ '^\*running'
327 let s:stopped = 0
328 endif
288 329
289 if win_gotoid(s:startwin) 330 if win_gotoid(s:startwin)
290 let fname = substitute(a:msg, '.*fullname="\([^"]*\)".*', '\1', '') 331 let fname = substitute(a:msg, '.*fullname="\([^"]*\)".*', '\1', '')
291 if a:msg =~ '^\(\*stopped\|=thread-selected\)' && filereadable(fname) 332 if a:msg =~ '^\(\*stopped\|=thread-selected\)' && filereadable(fname)
292 let lnum = substitute(a:msg, '.*line="\([^"]*\)".*', '\1', '') 333 let lnum = substitute(a:msg, '.*line="\([^"]*\)".*', '\1', '')