Skip to content

Commit 3a18fb1

Browse files
committed
debug: support path substitutions
Add g:go_debug_subtitution_paths and hook up their use to the debugger so that binaries that are compiled at a different location than where the local source exists can be debugged. Closes #3245
1 parent 81f8cd0 commit 3a18fb1

File tree

3 files changed

+46
-8
lines changed

3 files changed

+46
-8
lines changed

autoload/go/config.vim

+4
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,10 @@ function! go#config#DebugWindows() abort
211211

212212
endfunction
213213

214+
function! go#config#DebugSubstitutePaths() abort
215+
return get(g:, 'go_debug_substitute_paths', [])
216+
endfunction
217+
214218
function! go#config#DebugPreserveLayout() abort
215219
return get(g:, 'go_debug_preserve_layout', 0)
216220
endfunction

autoload/go/debug.vim

+31-8
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ function! s:update_breakpoint(res) abort
158158
endif
159159

160160
exe bufs[0][0] 'wincmd w'
161-
let filename = state.currentThread.file
161+
let filename = s:substituteRemotePath(state.currentThread.file)
162162
let linenr = state.currentThread.line
163163
let oldfile = fnamemodify(expand('%'), ':p:gs!\\!/!')
164164
if oldfile != filename
@@ -202,7 +202,7 @@ function! s:show_stacktrace(check_errors, res) abort
202202
if loc.file is# '?' || !has_key(loc, 'function')
203203
continue
204204
endif
205-
call setline(i+1, printf('%s - %s:%d', loc.function.name, fnamemodify(loc.file, ':p'), loc.line))
205+
call setline(i+1, printf('%s - %s:%d', loc.function.name, s:substituteRemotePath(fnamemodify(loc.file, ':p')), loc.line))
206206
endfor
207207
finally
208208
setlocal nomodifiable
@@ -357,7 +357,7 @@ function! s:goto_file() abort
357357
return
358358
endif
359359
exe bufs[0][0] 'wincmd w'
360-
let filename = m[1]
360+
let filename = s:substituteLocalPath(m[1])
361361
let linenr = m[2]
362362
let oldfile = fnamemodify(expand('%'), ':p:gs!\\!/!')
363363
if oldfile != filename
@@ -1140,9 +1140,9 @@ function! s:show_goroutines(currentGoroutineID, res) abort
11401140
" lines is modified, then make sure that go#debug#Goroutine is also
11411141
" changed if needed.
11421142
if l:goroutine.id == a:currentGoroutineID
1143-
let l:g = printf("* Goroutine %s - %s: %s:%s %s (thread: %s)", l:goroutine.id, l:goroutineType, l:loc.file, l:loc.line, l:loc.function.name, l:goroutine.threadID)
1143+
let l:g = printf("* Goroutine %s - %s: %s:%s %s (thread: %s)", l:goroutine.id, l:goroutineType, s:substituteRemotePath(l:loc.file), l:loc.line, l:loc.function.name, l:goroutine.threadID)
11441144
else
1145-
let l:g = printf(" Goroutine %s - %s: %s:%s %s (thread: %s)", l:goroutine.id, l:goroutineType, l:loc.file, l:loc.line, l:loc.function.name, l:goroutine.threadID)
1145+
let l:g = printf(" Goroutine %s - %s: %s:%s %s (thread: %s)", l:goroutine.id, l:goroutineType, s:substituteRemotePath(l:loc.file), l:loc.line, l:loc.function.name, l:goroutine.threadID)
11461146
endif
11471147
let v += [l:g]
11481148
endfor
@@ -1454,10 +1454,10 @@ function! go#debug#Breakpoint(...) abort
14541454
else " Add breakpoint
14551455
if s:isReady()
14561456
let l:promise = go#promise#New(function('s:rpc_response'), 20000, {})
1457-
call s:call_jsonrpc(l:promise.wrapper, 'RPCServer.CreateBreakpoint', {'Breakpoint': {'file': l:filename, 'line': l:linenr}})
1457+
call s:call_jsonrpc(l:promise.wrapper, 'RPCServer.CreateBreakpoint', {'Breakpoint': {'file': s:substituteLocalPath(l:filename), 'line': l:linenr}})
14581458
let l:res = l:promise.await()
14591459
let l:bt = l:res.result.Breakpoint
1460-
call s:sign_place(l:bt.id, l:bt.file, l:bt.line)
1460+
call s:sign_place(l:bt.id, s:substituteRemotePath(l:bt.file), l:bt.line)
14611461
else
14621462
let l:id = len(s:list_breakpoints()) + 1
14631463
call s:sign_place(l:id, l:filename, l:linenr)
@@ -1617,7 +1617,7 @@ function! s:handle_staleness_check_response(filename, check_errors, res) abort
16171617
endfunction
16181618

16191619
function! s:warn_stale(filename) abort
1620-
call go#util#EchoWarning(printf('file locations may be incorrect, because %s has changed since debugging started', a:filename))
1620+
call go#util#EchoWarning(printf('file locations may be incorrect, because %s has changed since debugging started', a:filename))
16211621
endfunction
16221622

16231623

@@ -1737,6 +1737,29 @@ function! s:restore_mapping(maparg)
17371737
return
17381738
endfunction
17391739

1740+
function! s:substituteRemotePath(path) abort
1741+
return s:substitutePath(a:path, go#config#DebugSubstitutePaths())
1742+
endfunction
1743+
1744+
function! s:substituteLocalPath(path) abort
1745+
return s:substitutePath(a:path, map(deepcopy(go#config#DebugSubstitutePaths()), '[v:val[1], v:val[0]]'))
1746+
endfunction
1747+
1748+
function! s:substitutePath(path, substitutions) abort
1749+
for [l:from, l:to] in a:substitutions
1750+
if len(a:path) < len(l:from)
1751+
continue
1752+
endif
1753+
if a:path[0:len(l:from)-1] != l:from
1754+
continue
1755+
endif
1756+
1757+
return printf('%s%s', l:to, a:path[len(l:from):-1])
1758+
endfor
1759+
1760+
return a:path
1761+
endfunction
1762+
17401763
" restore Vi compatibility settings
17411764
let &cpo = s:cpo_save
17421765
unlet s:cpo_save

doc/vim-go.txt

+11
Original file line numberDiff line numberDiff line change
@@ -2517,6 +2517,17 @@ Preserve window layout in debugging mode. This setting is considered only when
25172517
|'g:go_debug_windows'| is not empty.
25182518
>
25192519
let g:go_debug_preserve_layout = 0
2520+
<
2521+
*'g:go_debug_substitute_paths'*
2522+
2523+
Substitute paths in the debugger. This is a list of lists, where each element
2524+
is a list where the remote path (the from side) is the first element and the
2525+
local path (the to side) is the second element. These are necessary when the
2526+
binary being debugged was not built from the same location that its source
2527+
resides locally. By default it is empty.
2528+
2529+
>
2530+
let g:go_debug_substitute_paths = [['/compiled/from', '/cloned/to']]
25202531
<
25212532
*'g:go_debug_mappings'*
25222533

0 commit comments

Comments
 (0)