0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

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.
This commit is contained in:
Bram Moolenaar 2017-11-12 18:02:06 +01:00
parent d327b0c68f
commit 60e73f2acc
3 changed files with 82 additions and 33 deletions

View File

@ -1,4 +1,4 @@
*terminal.txt* For Vim version 8.0. Last change: 2017 Nov 09 *terminal.txt* For Vim version 8.0. Last change: 2017 Nov 12
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@ -449,26 +449,32 @@ Stepping through code ~
Put focus on the gdb window to type commands there. Some common ones are: Put focus on the gdb window to type commands there. Some common ones are:
- CTRL-C interrupt the program - CTRL-C interrupt the program
- next execute the current line and stop at the next line - next execute the current line and stop at the next line
- step execute the current line and stop at the next statement, entering - step execute the current line and stop at the next statement,
functions entering functions
- finish execute until leaving the current function - finish execute until leaving the current function
- where show the stack - where show the stack
- frame N go to the Nth stack frame - frame N go to the Nth stack frame
- continue continue execution - continue continue execution
In the window showing the source code some commands can used to control gdb: In the window showing the source code these commands can used to control gdb:
:Run [args] run the program with [args] or the previous arguments
:Arguments {args} set arguments for the next :Run
:Break set a breakpoint at the current line; a sign will be displayed :Break set a breakpoint at the current line; a sign will be displayed
:Delete delete a breakpoint at the current line :Delete delete a breakpoint at the current line
:Step execute the gdb "step" command :Step execute the gdb "step" command
:Over execute the gdb "next" command (:Next is a Vim command) :Over execute the gdb "next" command (:Next is a Vim command)
:Finish execute the gdb "finish" command :Finish execute the gdb "finish" command
:Continue execute the gdb "continue" command :Continue execute the gdb "continue" command
:Stop interrupt the program
The plugin adds a window toolbar with these entries: The plugin adds a window toolbar with these entries:
Step :Step Step :Step
Next :Over Next :Over
Finish :Finish Finish :Finish
Cont :Continue Cont :Continue
Stop :Stop
Eval :Evaluate Eval :Evaluate
This way you can use the mouse to perform the most common commands. This way you can use the mouse to perform the most common commands.

View File

@ -20,6 +20,9 @@ if exists(':Termdebug')
finish finish
endif endif
" Uncomment this line to write logging in "debuglog".
" call ch_logfile('debuglog', 'w')
" The command that starts debugging, e.g. ":Termdebug vim". " The command that starts debugging, e.g. ":Termdebug vim".
" To end type "quit" in the gdb window. " To end type "quit" in the gdb window.
command -nargs=* -complete=file Termdebug call s:StartDebug(<q-args>) command -nargs=* -complete=file Termdebug call s:StartDebug(<q-args>)
@ -31,6 +34,7 @@ endif
let s:pc_id = 12 let s:pc_id = 12
let s:break_id = 13 let s:break_id = 13
let s:stopped = 1
if &background == 'light' if &background == 'light'
hi default debugPC term=reverse ctermbg=lightblue guibg=lightblue hi default debugPC term=reverse ctermbg=lightblue guibg=lightblue
@ -83,11 +87,11 @@ func s:StartDebug(cmd)
" Add -quiet to avoid the intro message causing a hit-enter prompt. " Add -quiet to avoid the intro message causing a hit-enter prompt.
let cmd = [g:termdebugger, '-quiet', '-tty', pty, a:cmd] let cmd = [g:termdebugger, '-quiet', '-tty', pty, a:cmd]
echomsg 'executing "' . join(cmd) . '"' echomsg 'executing "' . join(cmd) . '"'
let gdbbuf = term_start(cmd, { let s:gdbbuf = term_start(cmd, {
\ 'exit_cb': function('s:EndDebug'), \ 'exit_cb': function('s:EndDebug'),
\ 'term_finish': 'close', \ 'term_finish': 'close',
\ }) \ })
if gdbbuf == 0 if s:gdbbuf == 0
echoerr 'Failed to open the gdb terminal window' echoerr 'Failed to open the gdb terminal window'
exe 'bwipe! ' . s:ptybuf exe 'bwipe! ' . s:ptybuf
exe 'bwipe! ' . s:commbuf exe 'bwipe! ' . s:commbuf
@ -97,7 +101,12 @@ func s:StartDebug(cmd)
" Connect gdb to the communication pty, using the GDB/MI interface " Connect gdb to the communication pty, using the GDB/MI interface
" If you get an error "undefined command" your GDB is too old. " If you get an error "undefined command" your GDB is too old.
call term_sendkeys(gdbbuf, 'new-ui mi ' . commpty . "\r") call term_sendkeys(s:gdbbuf, 'new-ui mi ' . commpty . "\r")
" Interpret commands while the target is running. This should usualy only be
" exec-interrupt, since many commands don't work properly while the target is
" running.
call s:SendCommand('-gdb-set mi-async on')
" Sign used to highlight the line where the program has stopped. " Sign used to highlight the line where the program has stopped.
" There can be only one. " There can be only one.
@ -170,6 +179,9 @@ func s:InstallCommands()
command Step call s:SendCommand('-exec-step') command Step call s:SendCommand('-exec-step')
command Over call s:SendCommand('-exec-next') command Over call s:SendCommand('-exec-next')
command Finish call s:SendCommand('-exec-finish') command Finish call s:SendCommand('-exec-finish')
command -nargs=* Run call s:Run(<q-args>)
command -nargs=* Arguments call s:SendCommand('-exec-arguments ' . <q-args>)
command Stop call s:SendCommand('-exec-interrupt')
command Continue call s:SendCommand('-exec-continue') command Continue call s:SendCommand('-exec-continue')
command -range -nargs=* Evaluate call s:Evaluate(<range>, <q-args>) command -range -nargs=* Evaluate call s:Evaluate(<range>, <q-args>)
command Gdb call win_gotoid(s:gdbwin) command Gdb call win_gotoid(s:gdbwin)
@ -183,6 +195,7 @@ func s:InstallCommands()
nnoremenu WinBar.Next :Over<CR> nnoremenu WinBar.Next :Over<CR>
nnoremenu WinBar.Finish :Finish<CR> nnoremenu WinBar.Finish :Finish<CR>
nnoremenu WinBar.Cont :Continue<CR> nnoremenu WinBar.Cont :Continue<CR>
nnoremenu WinBar.Stop :Stop<CR>
nnoremenu WinBar.Eval :Evaluate<CR> nnoremenu WinBar.Eval :Evaluate<CR>
endif endif
endfunc endfunc
@ -194,6 +207,9 @@ func s:DeleteCommands()
delcommand Step delcommand Step
delcommand Over delcommand Over
delcommand Finish delcommand Finish
delcommand Run
delcommand Arguments
delcommand Stop
delcommand Continue delcommand Continue
delcommand Evaluate delcommand Evaluate
delcommand Gdb delcommand Gdb
@ -206,6 +222,7 @@ func s:DeleteCommands()
aunmenu WinBar.Next aunmenu WinBar.Next
aunmenu WinBar.Finish aunmenu WinBar.Finish
aunmenu WinBar.Cont aunmenu WinBar.Cont
aunmenu WinBar.Stop
aunmenu WinBar.Eval aunmenu WinBar.Eval
endif endif
@ -220,8 +237,19 @@ endfunc
" :Break - Set a breakpoint at the cursor position. " :Break - Set a breakpoint at the cursor position.
func s:SetBreakpoint() func s:SetBreakpoint()
call term_sendkeys(s:commbuf, '-break-insert --source ' " Setting a breakpoint may not work while the program is running.
\ . fnameescape(expand('%:p')) . ' --line ' . line('.') . "\r") " Interrupt to make it work.
let do_continue = 0
if !s:stopped
let do_continue = 1
call s:SendCommand('-exec-interrupt')
sleep 10m
endif
call s:SendCommand('-break-insert --source '
\ . fnameescape(expand('%:p')) . ' --line ' . line('.'))
if do_continue
call s:SendCommand('-exec-continue')
endif
endfunc endfunc
" :Delete - Delete a breakpoint at the cursor position. " :Delete - Delete a breakpoint at the cursor position.
@ -244,6 +272,13 @@ func s:SendCommand(cmd)
call term_sendkeys(s:commbuf, a:cmd . "\r") call term_sendkeys(s:commbuf, a:cmd . "\r")
endfunc endfunc
func s:Run(args)
if a:args != ''
call s:SendCommand('-exec-arguments ' . a:args)
endif
call s:SendCommand('-exec-run')
endfunc
" :Evaluate - evaluate what is under the cursor " :Evaluate - evaluate what is under the cursor
func s:Evaluate(range, arg) func s:Evaluate(range, arg)
if a:arg != '' if a:arg != ''
@ -259,7 +294,7 @@ func s:Evaluate(range, arg)
else else
let expr = expand('<cexpr>') let expr = expand('<cexpr>')
endif endif
call term_sendkeys(s:commbuf, '-data-evaluate-expression "' . expr . "\"\r") call s:SendCommand('-data-evaluate-expression "' . expr . '"')
let s:evalexpr = expr let s:evalexpr = expr
endfunc endfunc
@ -286,6 +321,12 @@ endfunc
func s:HandleCursor(msg) func s:HandleCursor(msg)
let wid = win_getid(winnr()) let wid = win_getid(winnr())
if a:msg =~ '^\*stopped'
let s:stopped = 1
elseif a:msg =~ '^\*running'
let s:stopped = 0
endif
if win_gotoid(s:startwin) if win_gotoid(s:startwin)
let fname = substitute(a:msg, '.*fullname="\([^"]*\)".*', '\1', '') let fname = substitute(a:msg, '.*fullname="\([^"]*\)".*', '\1', '')
if a:msg =~ '^\(\*stopped\|=thread-selected\)' && filereadable(fname) if a:msg =~ '^\(\*stopped\|=thread-selected\)' && filereadable(fname)

View File

@ -761,6 +761,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1293,
/**/ /**/
1292, 1292,
/**/ /**/