Skip to content

Commit b079f0a

Browse files
committed
debug: add :GoDebugAttach
Add :GoDebugAttach to be able to attach to a running process. Closes #1758
1 parent 188884f commit b079f0a

File tree

5 files changed

+75
-43
lines changed

5 files changed

+75
-43
lines changed

autoload/go/debug.vim

+53-33
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ if !exists('s:state')
1313
\ 'functionArgs': {},
1414
\ 'message': [],
1515
\ 'resultHandlers': {},
16+
\ 'kill_on_detach': v:true,
1617
\ }
1718

1819
if go#util#HasDebug('debugger-state')
@@ -252,7 +253,7 @@ function! s:clearState() abort
252253
endfunction
253254

254255
function! s:stop() abort
255-
call s:call_jsonrpc(function('s:noop'), 'RPCServer.Detach', {'kill': v:true})
256+
call s:call_jsonrpc(function('s:noop'), 'RPCServer.Detach', {'kill': s:state['kill_on_detach']})
256257

257258
if has_key(s:state, 'job')
258259
call go#job#Wait(s:state['job'])
@@ -279,8 +280,9 @@ function! go#debug#Stop() abort
279280
for k in map(split(execute('command GoDebug'), "\n")[1:], 'matchstr(v:val, "^\\s*\\zs\\S\\+")')
280281
exe 'delcommand' k
281282
endfor
282-
command! -nargs=* -complete=customlist,go#package#Complete GoDebugStart call go#debug#Start(0, <f-args>)
283-
command! -nargs=* -complete=customlist,go#package#Complete GoDebugTest call go#debug#Start(1, <f-args>)
283+
command! -nargs=* -complete=customlist,go#package#Complete GoDebugStart call go#debug#Start('debug', <f-args>)
284+
command! -nargs=* -complete=customlist,go#package#Complete GoDebugTest call go#debug#Start('test', <f-args>)
285+
command! -nargs=1 GoDebugAttach call go#debug#Start('attach', <f-args>)
284286
command! -nargs=? GoDebugBreakpoint call go#debug#Breakpoint(<f-args>)
285287

286288
" Remove all mappings.
@@ -478,6 +480,7 @@ function! s:start_cb() abort
478480

479481
silent! delcommand GoDebugStart
480482
silent! delcommand GoDebugTest
483+
silent! delcommand GoDebugAttach
481484

482485
command! -nargs=0 GoDebugContinue call go#debug#Stack('continue')
483486
command! -nargs=0 GoDebugStop call go#debug#Stop()
@@ -686,10 +689,9 @@ function! s:handleRPCResult(resp) abort
686689
endtry
687690
endfunction
688691

689-
690692
" Start the debug mode. The first argument is the package name to compile and
691693
" debug, anything else will be passed to the running program.
692-
function! go#debug#Start(is_test, ...) abort
694+
function! go#debug#Start(mode, ...) abort
693695
call go#cmd#autowrite()
694696

695697
if !go#util#has_job()
@@ -702,7 +704,7 @@ function! go#debug#Start(is_test, ...) abort
702704
return s:state['job']
703705
endif
704706

705-
let s:start_args = [a:is_test] + a:000
707+
let s:start_args = [a:mode] + a:000
706708

707709
if go#util#HasDebug('debugger-state')
708710
call go#config#SetDebugDiag(s:state)
@@ -714,33 +716,17 @@ function! go#debug#Start(is_test, ...) abort
714716
endif
715717

716718
try
717-
let l:cmd = [
718-
\ dlv,
719-
\ (a:is_test ? 'test' : 'debug'),
720-
\]
721-
722-
" append the package when it's given.
723-
if len(a:000) > 0
724-
let l:pkgname = a:1
725-
if l:pkgname[0] == '.'
726-
let l:pkgabspath = fnamemodify(l:pkgname, ':p')
727-
728-
let l:cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
729-
let l:dir = getcwd()
730-
execute l:cd fnameescape(expand('%:p:h'))
731-
732-
try
733-
let l:pkgname = go#package#FromPath(l:pkgabspath)
734-
if type(l:pkgname) == type(0)
735-
call go#util#EchoError('could not determine package name')
736-
return
737-
endif
738-
finally
739-
execute l:cd fnameescape(l:dir)
740-
endtry
741-
endif
742719

743-
let l:cmd += [l:pkgname]
720+
let l:cmd = [dlv, a:mode]
721+
722+
let s:state['kill_on_detach'] = v:true
723+
if a:mode is 'debug' || a:mode is 'test'
724+
let l:cmd = extend(l:cmd, s:package(a:000))
725+
elseif a:mode is 'attach'
726+
let l:cmd = add(l:cmd, a:1)
727+
let s:state['kill_on_detach'] = v:false
728+
else
729+
call go#util#EchoError('Unknown dlv command')
744730
endif
745731

746732
let l:cmd += [
@@ -782,7 +768,40 @@ function! go#debug#Start(is_test, ...) abort
782768
return s:state['job']
783769
endfunction
784770

785-
" Translate a reflect kind constant to a human string.
771+
" s:package returns the import path of package name of a :GoDebug(Start|Test)
772+
" call as a list so that the package can be appended to a command list using
773+
" extend(). args is expected to be a (potentially empty_ list. The first
774+
" element in args (if there are any) is expected to be a package path. An
775+
" emnpty list is returned when either args is an empty list or the import path
776+
" cannot be determined.
777+
function! s:package(args)
778+
if len(a:args) == 0
779+
return []
780+
endif
781+
782+
" append the package when it's given.
783+
let l:pkgname = a:args[0]
784+
if l:pkgname[0] == '.'
785+
let l:pkgabspath = fnamemodify(l:pkgname, ':p')
786+
787+
let l:cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
788+
let l:dir = getcwd()
789+
let l:dir = go#util#Chdir(expand('%:p:h'))
790+
try
791+
let l:pkgname = go#package#FromPath(l:pkgabspath)
792+
if type(l:pkgname) == type(0)
793+
call go#util#EchoError('could not determine package name')
794+
return []
795+
endif
796+
finally
797+
call go#util#Chdir(l:dir)
798+
endtry
799+
endif
800+
801+
return [l:pkgname]
802+
endfunction
803+
804+
" Translate a reflect kind constant to a human string.
786805
function! s:reflect_kind(k)
787806
" Kind constants from Go's reflect package.
788807
return [
@@ -1210,6 +1229,7 @@ function! go#debug#Restart() abort
12101229
\ 'functionArgs': {},
12111230
\ 'message': [],
12121231
\ 'resultHandlers': {},
1232+
\ 'kill_on_detach': s:state['kill_on_detach'],
12131233
\ }
12141234

12151235
call call('go#debug#Start', s:start_args)

autoload/go/debug_test.vim

+3-3
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ function! Test_GoDebugStart_Errors() abort
3838
let l:cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
3939
execute l:cd . ' debug/compilerror'
4040

41-
call go#debug#Start(0)
41+
call go#debug#Start('debug')
4242

4343
let l:actual = getqflist()
4444
let l:start = reltime()
@@ -80,9 +80,9 @@ function! s:debug(...) abort
8080
if a:0 == 0
8181
let l:cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
8282
execute l:cd . ' debug/debugmain'
83-
let l:job = go#debug#Start(0)
83+
let l:job = go#debug#Start('debug')
8484
else
85-
let l:job = go#debug#Start(0, a:1)
85+
let l:job = go#debug#Start('debug', a:1)
8686
endif
8787

8888
let l:start = reltime()

autoload/go/util.vim

+1-1
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,7 @@ function! go#util#Chdir(dir) abort
704704
if !exists('*chdir')
705705
let l:olddir = getcwd()
706706
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd '
707-
execute cd . a:dir
707+
execute cd . fnameescape(a:dir)
708708
return l:olddir
709709
endif
710710
return chdir(a:dir)

doc/vim-go.txt

+15-4
Original file line numberDiff line numberDiff line change
@@ -2258,10 +2258,21 @@ the `dlv` process, or |:GoDebugRestart| to recompile the code.
22582258
*go-debug-commands*
22592259
DEBUGGER COMMANDS~
22602260

2261-
Only |:GoDebugStart|, `:GoDebugTest`, and |:GoDebugBreakpoint| are available
2262-
by default. `:GoDebugContinue` becomes available after running `:GoDebugStart`
2263-
or `:GoDebugTest`. The rest of the commands and mappings become available
2264-
after executing `:GoDebugContinue`.
2261+
Only |:GoDebugAttach|, |:GoDebugStart|, |:GoDebugTest|, and
2262+
|:GoDebugBreakpoint| are available by default. |:GoDebugContinue| becomes
2263+
available after running |:GoDebugAttach|, |:GoDebugStart| or |:GoDebugTest|.
2264+
The rest of the commands and mappings become available after executing
2265+
|:GoDebugContinue|.
2266+
2267+
*:GoDebugAttach*
2268+
:GoDebugAttach pid
2269+
2270+
Start the debug mode for pid; this does several things:
2271+
2272+
* Setup the debug windows according to |'g:go_debug_windows'|.
2273+
* Make the `:GoDebug*` commands and `(go-debug-*)` mappings available.
2274+
2275+
Use |:GoDebugStop| to stop `dlv` and exit debugging mode.
22652276

22662277
*:GoDebugStart*
22672278
:GoDebugStart [pkg] [program-args]

ftplugin/go/commands.vim

+3-2
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,9 @@ command! -nargs=0 GoFillStruct call go#fillstruct#FillStruct()
105105

106106
" -- debug
107107
if !exists(':GoDebugStart')
108-
command! -nargs=* -complete=customlist,go#package#Complete GoDebugStart call go#debug#Start(0, <f-args>)
109-
command! -nargs=* -complete=customlist,go#package#Complete GoDebugTest call go#debug#Start(1, <f-args>)
108+
command! -nargs=* -complete=customlist,go#package#Complete GoDebugStart call go#debug#Start('debug', <f-args>)
109+
command! -nargs=* -complete=customlist,go#package#Complete GoDebugTest call go#debug#Start('test', <f-args>)
110+
command! -nargs=1 GoDebugAttach call go#debug#Start('attach', <f-args>)
110111
command! -nargs=? GoDebugBreakpoint call go#debug#Breakpoint(<f-args>)
111112
endif
112113

0 commit comments

Comments
 (0)