Skip to content

Commit

Permalink
DAP: introduce Rdbg Inspector
Browse files Browse the repository at this point in the history
  • Loading branch information
ono-max committed Apr 8, 2023
1 parent 9047fc8 commit 03e2f99
Show file tree
Hide file tree
Showing 3 changed files with 226 additions and 0 deletions.
78 changes: 78 additions & 0 deletions lib/debug/dap_custom/recordInspector.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
module DEBUGGER__
module DAP_RecordInspector
module Custom_UI_DAP
def custom_dap_request_rdbgRecordInspector(req)
@q_msg << req
end
end

module Custom_Session
def custom_dap_request_rdbgRecordInspector(req)
cmd = req.dig('arguments', 'command')
case cmd
when 'enable'
request_tc [:record, :on]
@ui.respond req, {}
when 'disable'
request_tc [:record, :off]
@ui.respond req, {}
when 'step'
tid = req.dig('arguments', 'threadId')
count = req.dig('arguments', 'count')
if tc = find_waiting_tc(tid)
tc << [:step, :in, count]
else
fail_response req
end
when 'stepBack'
tid = req.dig('arguments', 'threadId')
count = req.dig('arguments', 'count')
if tc = find_waiting_tc(tid)
tc << [:step, :back, count]
else
fail_response req
end
when 'collect'
tid = req.dig('arguments', 'threadId')
if tc = find_waiting_tc(tid)
tc << [:dap, :rdbgRecordInspector, req]
else
fail_response req
end
else
raise "Unknown command #{cmd}"
end
end

def custom_dap_request_event_rdbgRecordInspector(req, result)
@ui.respond req, result
end
end

module Custom_ThreadClient
def custom_dap_request_rdbgRecordInspector(req)
logs = []
log_index = nil
unless @recorder.nil?
log_index = @recorder.log_index
@recorder.log.each{|frames|
crt_frame = frames[0]
logs << {
name: crt_frame.name,
location: {
path: crt_frame.location.path,
line: crt_frame.location.lineno,
},
depth: crt_frame.frame_depth
}
}
end
event! :protocol_result, :rdbgRecordInspector, req, logs: logs, stoppedIndex: log_index
end
end

::DEBUGGER__::UI_DAP.include Custom_UI_DAP
::DEBUGGER__::Session.include Custom_Session
::DEBUGGER__::ThreadClient.include Custom_ThreadClient
end
end
136 changes: 136 additions & 0 deletions lib/debug/dap_custom/traceInspector.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
module DEBUGGER__
module DAP_TraceInspector
class MultiTracer < Tracer
MAX_LOG_SIZE = 4000
def initialize ui, evts, **kw
@evts = evts
@log = []
super(ui, **kw)
@type = 'multi'
end

attr_reader :log

def setup
@tracer = TracePoint.new(*@evts){|tp|
next if skip?(tp)

case tp.event
when :call, :c_call, :b_call
append(call_trace_log(tp))
when :return, :c_return, :b_return
return_str = DEBUGGER__.safe_inspect(tp.return_value, short: true, max_length: 120)
append(call_trace_log(tp, return_str: return_str))
when :line
append(line_trace_log(tp))
end
}
end

def call_identifier_str tp
if tp.defined_class
minfo(tp)
else
"block"
end
end

def append log
if @log.size >= MAX_LOG_SIZE
@log.shift
end
@log << log
end

def call_trace_log tp, return_str: nil
log = {
depth: DEBUGGER__.frame_depth,
name: call_identifier_str(tp),
threadId: Thread.current.instance_variable_get(:@__thread_client_id),
location: {
path: tp.path,
line: tp.lineno
}
}
log[:returnValue] = return_str if return_str
log
end

def line_trace_log tp
{
depth: DEBUGGER__.frame_depth,
threadId: Thread.current.instance_variable_get(:@__thread_client_id),
location: {
path: tp.path,
line: tp.lineno
}
}
end

def skip? tp
super || !@evts.include?(tp.event)
end
end

module Custom_UI_DAP
def custom_dap_request_rdbgTraceInspector(req)
@q_msg << req
end
end

module Custom_Session
def custom_dap_request_rdbgTraceInspector(req)
cmd = req.dig('arguments', 'command')
case cmd
when 'enable'
events = req.dig('arguments', 'events')
evts = []
events.each{|evt|
case evt
when 'line'
evts << :line
when 'call'
evts << :call
evts << :c_call
evts << :b_call
when 'return'
evts << :return
evts << :c_return
evts << :b_return
else
raise "unknown trace type #{evt}"
end
}
add_tracer MultiTracer.new @ui, evts
@ui.respond req, {}
when 'disable'
if t = find_multi_trace
t.disable
end
@ui.respond req, {}
when 'collect'
logs = []
if t = find_multi_trace
logs = t.log
end
@ui.respond req, logs: logs
else
raise "unknown command #{cmd}"
end
return :retry
end

def find_multi_trace
@tracers.values.each{|t|
if t.type == 'multi'
return t
end
}
return nil
end
end

::DEBUGGER__::UI_DAP.include Custom_UI_DAP
::DEBUGGER__::Session.include Custom_Session
end
end
12 changes: 12 additions & 0 deletions lib/debug/server_dap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,14 @@ def recv_request
retry
end

def load_rdbgExtension req
if exts = req.dig('arguments', 'rdbgExtension')
exts.each{|ext|
require_relative "dap_custom/#{File.basename(ext)}"
}
end
end

def process
while req = recv_request
raise "not a request: #{req.inspect}" unless req['type'] == 'request'
Expand All @@ -288,6 +296,8 @@ def process
UI_DAP.local_fs_map_set req.dig('arguments', 'localfs') || req.dig('arguments', 'localfsMap') || true
@nonstop = true

load_rdbgExtension req

when 'attach'
send_response req
UI_DAP.local_fs_map_set req.dig('arguments', 'localfs') || req.dig('arguments', 'localfsMap')
Expand All @@ -298,6 +308,8 @@ def process
@nonstop = false
end

load_rdbgExtension req

when 'configurationDone'
send_response req

Expand Down

0 comments on commit 03e2f99

Please sign in to comment.