Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lib/debug/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ module DEBUGGER__
host: ['RUBY_DEBUG_HOST', "REMOTE: TCP/IP remote debugging: host", :string, "127.0.0.1"],
sock_path: ['RUBY_DEBUG_SOCK_PATH', "REMOTE: UNIX Domain Socket remote debugging: socket path"],
sock_dir: ['RUBY_DEBUG_SOCK_DIR', "REMOTE: UNIX Domain Socket remote debugging: socket directory"],
local_fs_map: ['RUBY_DEBUG_LOCAL_FS_MAP', "REMOTE: Specify local fs map", :path_map],
cookie: ['RUBY_DEBUG_COOKIE', "REMOTE: Cookie for negotiation"],
open_frontend: ['RUBY_DEBUG_OPEN_FRONTEND',"REMOTE: frontend used by open command (vscode, chrome, default: rdbg)."],
chrome_path: ['RUBY_DEBUG_CHROME_PATH', "REMOTE: Platform dependent path of Chrome (For more information, See [here](https://github.com/ruby/debug/pull/334/files#diff-5fc3d0a901379a95bc111b86cf0090b03f857edfd0b99a0c1537e26735698453R55-R64))"],
Expand Down Expand Up @@ -238,6 +239,8 @@ def self.parse_config_value name, valstr
e
end
}
when :path_map
valstr.split(',').map{|e| e.split(':')}
else
valstr
end
Expand Down Expand Up @@ -384,6 +387,8 @@ def self.config_to_env_hash config
case CONFIG_SET[key][2]
when :path
valstr = config[key].map{|e| e.kind_of?(Regexp) ? e.inspect : e}.join(':')
when :path_map
valstr = config[key].map{|e| e.join(':')}.join(',')
else
valstr = config[key].to_s
end
Expand Down
47 changes: 37 additions & 10 deletions lib/debug/server_dap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,39 @@ def show_protocol dir, msg
end
end

@local_fs = false
# true: all localfs
# Array: part of localfs
# nil: no localfs
@local_fs_map = nil

def self.local_fs_map_path path
case @local_fs_map
when nil
false
when true
path
else # Array
@local_fs_map.each do |(remote_path_prefix, local_path_prefix)|
if path.start_with? remote_path_prefix
return path.sub(remote_path_prefix){ local_path_prefix }
end
end

def self.local_fs
@local_fs
nil
end
end

def self.local_fs_set
@local_fs = true
def self.local_fs_map_set map
return if @local_fs_map # already setup

case map
when String
@local_fs_map = map.split(',').map{|e| e.split(':')}
when true
@local_fs_map = map
when nil
@local_fs_map = CONFIG[:local_fs_map]
end
end

def dap_setup bytes
Expand All @@ -86,7 +111,7 @@ def dap_setup bytes

case self
when UI_UnixDomainServer
UI_DAP.local_fs_set
UI_DAP.local_fs_map_set true
when UI_TcpServer
# TODO: loopback address can be used to connect other FS env, like Docker containers
# UI_DAP.local_fs_set if @local_addr.ipv4_loopback? || @local_addr.ipv6_loopback?
Expand Down Expand Up @@ -228,12 +253,12 @@ def process
when 'launch'
send_response req
@is_attach = false
UI_DAP.local_fs_set if req.dig('arguments', 'localfs')
UI_DAP.local_fs_map_set req.dig('arguments', 'localfs') || req.dig('arguments', 'localfsMap')
when 'attach'
send_response req
Process.kill(UI_ServerBase::TRAP_SIGNAL, Process.pid)
@is_attach = true
UI_DAP.local_fs_set if req.dig('arguments', 'localfs')
UI_DAP.local_fs_map_set req.dig('arguments', 'localfs') || req.dig('arguments', 'localfsMap')
when 'setBreakpoints'
path = args.dig('source', 'path')
SESSION.clear_line_breakpoints path
Expand Down Expand Up @@ -637,7 +662,9 @@ def process_dap args
path = frame.realpath || frame.path
source_name = path ? File.basename(path) : frame.location.to_s

if !UI_DAP.local_fs || !(path && File.exist?(path))
if (path && File.exist?(path)) && (local_path = UI_DAP.local_fs_map_path(path))
# ok
else
ref = frame.file_lines
end

Expand All @@ -648,7 +675,7 @@ def process_dap args
column: 1,
source: {
name: source_name,
path: path,
path: (local_path || path),
sourceReference: ref,
},
}
Expand Down