ed-precompiled_debug 1.11.0-arm64-darwin
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CONTRIBUTING.md +573 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +22 -0
- data/README.md +996 -0
- data/Rakefile +57 -0
- data/TODO.md +23 -0
- data/debug.gemspec +33 -0
- data/exe/rdbg +53 -0
- data/ext/debug/debug.c +228 -0
- data/ext/debug/extconf.rb +27 -0
- data/ext/debug/iseq_collector.c +93 -0
- data/lib/debug/3.0/debug.bundle +0 -0
- data/lib/debug/3.1/debug.bundle +0 -0
- data/lib/debug/3.2/debug.bundle +0 -0
- data/lib/debug/3.3/debug.bundle +0 -0
- data/lib/debug/3.4/debug.bundle +0 -0
- data/lib/debug/abbrev_command.rb +77 -0
- data/lib/debug/breakpoint.rb +556 -0
- data/lib/debug/client.rb +263 -0
- data/lib/debug/color.rb +123 -0
- data/lib/debug/config.rb +592 -0
- data/lib/debug/console.rb +224 -0
- data/lib/debug/dap_custom/traceInspector.rb +336 -0
- data/lib/debug/frame_info.rb +191 -0
- data/lib/debug/irb_integration.rb +37 -0
- data/lib/debug/local.rb +115 -0
- data/lib/debug/open.rb +13 -0
- data/lib/debug/open_nonstop.rb +15 -0
- data/lib/debug/prelude.rb +50 -0
- data/lib/debug/server.rb +534 -0
- data/lib/debug/server_cdp.rb +1348 -0
- data/lib/debug/server_dap.rb +1108 -0
- data/lib/debug/session.rb +2667 -0
- data/lib/debug/source_repository.rb +150 -0
- data/lib/debug/start.rb +5 -0
- data/lib/debug/thread_client.rb +1457 -0
- data/lib/debug/tracer.rb +241 -0
- data/lib/debug/version.rb +5 -0
- data/lib/debug.rb +9 -0
- data/misc/README.md.erb +660 -0
- metadata +117 -0
data/lib/debug/client.rb
ADDED
@@ -0,0 +1,263 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'socket'
|
4
|
+
require 'io/console/size'
|
5
|
+
|
6
|
+
require_relative 'config'
|
7
|
+
require_relative 'version'
|
8
|
+
require_relative 'console'
|
9
|
+
|
10
|
+
# $VERBOSE = true
|
11
|
+
|
12
|
+
module DEBUGGER__
|
13
|
+
class CommandLineOptionError < Exception; end
|
14
|
+
|
15
|
+
class Client
|
16
|
+
class << self
|
17
|
+
def util name
|
18
|
+
case name
|
19
|
+
when 'gen-sockpath'
|
20
|
+
puts DEBUGGER__.create_unix_domain_socket_name
|
21
|
+
when 'gen-portpath'
|
22
|
+
port_path = File.join(DEBUGGER__.unix_domain_socket_dir, 'tcp_port')
|
23
|
+
File.unlink port_path if File.exist?(port_path)
|
24
|
+
puts port_path
|
25
|
+
when 'list-socks'
|
26
|
+
cleanup_unix_domain_sockets
|
27
|
+
puts list_connections
|
28
|
+
when 'list-socks-verbose'
|
29
|
+
cleanup_unix_domain_sockets
|
30
|
+
puts list_connections verbose: true
|
31
|
+
when 'setup-autoload'
|
32
|
+
setup_autoload
|
33
|
+
else
|
34
|
+
abort "Unknown utility: #{name}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def working_shell_type
|
39
|
+
shell = `ps -p #{Process.ppid} -o 'args='`
|
40
|
+
case shell
|
41
|
+
when /bash/
|
42
|
+
:bash
|
43
|
+
when /fish/
|
44
|
+
:fish
|
45
|
+
when /csh/
|
46
|
+
:csh
|
47
|
+
when /zsh/
|
48
|
+
:zsh
|
49
|
+
when /dash/
|
50
|
+
:dash
|
51
|
+
else
|
52
|
+
:unknown
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def setup_autoload
|
57
|
+
prelude_path = File.join(__dir__, 'prelude.rb')
|
58
|
+
|
59
|
+
case shell = working_shell_type
|
60
|
+
when :bash, :zsh
|
61
|
+
puts <<~EOS
|
62
|
+
# add the following lines in your ~/.#{shell}_profile
|
63
|
+
|
64
|
+
if test -s #{prelude_path} ; then
|
65
|
+
export RUBYOPT='-r #{prelude_path}'
|
66
|
+
fi
|
67
|
+
|
68
|
+
# Add `Kernel#bb` method which is alias of `Kernel#debugger`
|
69
|
+
# export RUBY_DEBUG_BB=1
|
70
|
+
EOS
|
71
|
+
|
72
|
+
when :fish
|
73
|
+
puts <<~EOS
|
74
|
+
# add the following lines in your ~/.config/fish/config.fish
|
75
|
+
set -x RUBYOPT "-r #{__dir__}/prelude" $RUBYOPT
|
76
|
+
EOS
|
77
|
+
|
78
|
+
else
|
79
|
+
puts "# Sorry that your shell is not supported yet.",
|
80
|
+
"# Please use the content in #{prelude_path} as a reference and modify your login script accordingly."
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def cleanup_unix_domain_sockets
|
85
|
+
Dir.glob(DEBUGGER__.create_unix_domain_socket_name_prefix + '*') do |file|
|
86
|
+
if File.socket?(file) && (/-(\d+)-\d+$/ =~ file || /-(\d+)$/ =~ file)
|
87
|
+
begin
|
88
|
+
Process.kill(0, $1.to_i)
|
89
|
+
rescue Errno::EPERM
|
90
|
+
rescue Errno::ESRCH
|
91
|
+
File.unlink(file)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def list_connections verbose: false
|
98
|
+
socks = Dir.glob(DEBUGGER__.create_unix_domain_socket_name_prefix + '*').find_all do |path|
|
99
|
+
File.socket?(path)
|
100
|
+
end
|
101
|
+
|
102
|
+
if verbose
|
103
|
+
socks = socks.map{|sock_path|
|
104
|
+
Socket.unix(sock_path){|sock|
|
105
|
+
sock.puts "info cookie: #{CONFIG[:cookie] || '-'}"
|
106
|
+
pid = sock.gets.chomp
|
107
|
+
_dbg = sock.gets.chomp
|
108
|
+
_unm = sock.gets.chomp
|
109
|
+
[sock_path, pid]
|
110
|
+
}
|
111
|
+
}
|
112
|
+
end
|
113
|
+
|
114
|
+
socks
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def initialize argv
|
119
|
+
@multi_process = false
|
120
|
+
@pid = nil
|
121
|
+
@console = Console.new
|
122
|
+
|
123
|
+
case argv.size
|
124
|
+
when 0
|
125
|
+
connect_unix
|
126
|
+
when 1
|
127
|
+
if /\A\d+\z/ =~ (arg = argv.shift.strip)
|
128
|
+
connect_tcp nil, arg.to_i
|
129
|
+
else
|
130
|
+
connect_unix arg
|
131
|
+
end
|
132
|
+
when 2
|
133
|
+
connect_tcp argv[0], argv[1]
|
134
|
+
else
|
135
|
+
raise CommandLineOptionError
|
136
|
+
end
|
137
|
+
|
138
|
+
@width = IO.console_size[1]
|
139
|
+
@width = 80 if @width == 0
|
140
|
+
|
141
|
+
send "version: #{VERSION} " +
|
142
|
+
"width: #{@width} " +
|
143
|
+
"cookie: #{CONFIG[:cookie] || '-'} " +
|
144
|
+
"nonstop: #{CONFIG[:nonstop] ? 'true' : 'false'}"
|
145
|
+
end
|
146
|
+
|
147
|
+
def deactivate
|
148
|
+
@console.deactivate if @console
|
149
|
+
end
|
150
|
+
|
151
|
+
def readline
|
152
|
+
if @multi_process
|
153
|
+
@console.readline "(rdbg:remote\##{@pid}) "
|
154
|
+
else
|
155
|
+
@console.readline "(rdbg:remote) "
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def connect_unix name = nil
|
160
|
+
if name
|
161
|
+
if File.exist? name
|
162
|
+
@s = Socket.unix(name)
|
163
|
+
else
|
164
|
+
@s = Socket.unix(File.join(DEBUGGER__.unix_domain_socket_dir, name))
|
165
|
+
end
|
166
|
+
else
|
167
|
+
Client.cleanup_unix_domain_sockets
|
168
|
+
files = Client.list_connections
|
169
|
+
|
170
|
+
case files.size
|
171
|
+
when 0
|
172
|
+
$stderr.puts "No debug session is available."
|
173
|
+
exit
|
174
|
+
when 1
|
175
|
+
@s = Socket.unix(files.first)
|
176
|
+
else
|
177
|
+
files = Client.list_connections verbose: true
|
178
|
+
$stderr.puts "Please select a debug session:"
|
179
|
+
files.each{|(f, desc)|
|
180
|
+
$stderr.puts " #{File.basename(f)} (#{desc})"
|
181
|
+
}
|
182
|
+
exit
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def connect_tcp host, port
|
188
|
+
@s = Socket.tcp(host, port)
|
189
|
+
end
|
190
|
+
|
191
|
+
def send msg
|
192
|
+
p send: msg if $VERBOSE
|
193
|
+
@s.puts msg
|
194
|
+
end
|
195
|
+
|
196
|
+
def connect
|
197
|
+
pre_commands = (CONFIG[:commands] || '').split(';;')
|
198
|
+
|
199
|
+
trap(:SIGINT){
|
200
|
+
send "pause"
|
201
|
+
}
|
202
|
+
|
203
|
+
begin
|
204
|
+
trap(:SIGWINCH){
|
205
|
+
@width = IO.console_size[1]
|
206
|
+
}
|
207
|
+
rescue ArgumentError
|
208
|
+
@width = 80
|
209
|
+
end
|
210
|
+
|
211
|
+
while line = @s.gets
|
212
|
+
p recv: line if $VERBOSE
|
213
|
+
case line
|
214
|
+
|
215
|
+
when /^out (.*)/
|
216
|
+
puts "#{$1}"
|
217
|
+
|
218
|
+
when /^input (.+)/
|
219
|
+
pid = $1
|
220
|
+
@multi_process = true if @pid && @pid != pid
|
221
|
+
@pid = pid
|
222
|
+
prev_trap = trap(:SIGINT, 'DEFAULT')
|
223
|
+
|
224
|
+
begin
|
225
|
+
if pre_commands.empty?
|
226
|
+
line = readline
|
227
|
+
else
|
228
|
+
line = pre_commands.shift
|
229
|
+
puts "(rdbg:remote:command) #{line}"
|
230
|
+
end
|
231
|
+
rescue Interrupt
|
232
|
+
retry
|
233
|
+
ensure
|
234
|
+
trap(:SIGINT, prev_trap)
|
235
|
+
end
|
236
|
+
|
237
|
+
line = (line || 'quit').strip
|
238
|
+
send "command #{pid} #{@width} #{line}"
|
239
|
+
|
240
|
+
when /^ask (\d+) (.*)/
|
241
|
+
pid = $1
|
242
|
+
print $2
|
243
|
+
send "answer #{pid} #{$stdin.gets || ''}"
|
244
|
+
|
245
|
+
when /^quit/
|
246
|
+
raise 'quit'
|
247
|
+
|
248
|
+
else
|
249
|
+
puts "(unknown) #{line.inspect}"
|
250
|
+
end
|
251
|
+
end
|
252
|
+
rescue => e
|
253
|
+
STDERR.puts "disconnected (#{e})"
|
254
|
+
exit
|
255
|
+
ensure
|
256
|
+
deactivate
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
if __FILE__ == $0
|
262
|
+
DEBUGGER__::Client.new(argv).connect
|
263
|
+
end
|
data/lib/debug/color.rb
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'irb/color'
|
5
|
+
|
6
|
+
module IRB
|
7
|
+
module Color
|
8
|
+
DIM = 2 unless defined? DIM
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
require "irb/color_printer"
|
13
|
+
rescue LoadError
|
14
|
+
warn "DEBUGGER: can not load newer irb for coloring. Write 'gem \"debug\" in your Gemfile."
|
15
|
+
end
|
16
|
+
|
17
|
+
module DEBUGGER__
|
18
|
+
module Color
|
19
|
+
if defined? IRB::Color.colorize
|
20
|
+
begin
|
21
|
+
IRB::Color.colorize('', [:DIM], colorable: true)
|
22
|
+
SUPPORT_COLORABLE_OPTION = true
|
23
|
+
rescue ArgumentError
|
24
|
+
end
|
25
|
+
|
26
|
+
if defined? SUPPORT_COLORABLE_OPTION
|
27
|
+
def irb_colorize str, color
|
28
|
+
IRB::Color.colorize str, color, colorable: true
|
29
|
+
end
|
30
|
+
else
|
31
|
+
def irb_colorize str, color
|
32
|
+
IRB::Color.colorize str, color
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def colorize str, color
|
37
|
+
if !CONFIG[:no_color]
|
38
|
+
irb_colorize str, color
|
39
|
+
else
|
40
|
+
str
|
41
|
+
end
|
42
|
+
end
|
43
|
+
else
|
44
|
+
def colorize str, color
|
45
|
+
str
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
if defined? IRB::ColorPrinter.pp
|
50
|
+
def color_pp obj, width
|
51
|
+
with_inspection_error_guard do
|
52
|
+
if !CONFIG[:no_color]
|
53
|
+
IRB::ColorPrinter.pp(obj, "".dup, width)
|
54
|
+
else
|
55
|
+
obj.pretty_inspect
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
else
|
60
|
+
def color_pp obj, width
|
61
|
+
with_inspection_error_guard do
|
62
|
+
obj.pretty_inspect
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def colored_inspect obj, width: SESSION.width, no_color: false
|
68
|
+
with_inspection_error_guard do
|
69
|
+
if !no_color
|
70
|
+
color_pp obj, width
|
71
|
+
else
|
72
|
+
obj.pretty_inspect
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
if defined? IRB::Color.colorize_code
|
78
|
+
if defined? SUPPORT_COLORABLE_OPTION
|
79
|
+
def colorize_code code
|
80
|
+
IRB::Color.colorize_code(code, colorable: true)
|
81
|
+
end
|
82
|
+
else
|
83
|
+
def colorize_code code
|
84
|
+
IRB::Color.colorize_code(code)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
else
|
88
|
+
def colorize_code code
|
89
|
+
code
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def colorize_cyan(str)
|
94
|
+
colorize(str, [:CYAN, :BOLD])
|
95
|
+
end
|
96
|
+
|
97
|
+
def colorize_blue(str)
|
98
|
+
colorize(str, [:BLUE, :BOLD])
|
99
|
+
end
|
100
|
+
|
101
|
+
def colorize_magenta(str)
|
102
|
+
colorize(str, [:MAGENTA, :BOLD])
|
103
|
+
end
|
104
|
+
|
105
|
+
def colorize_dim(str)
|
106
|
+
colorize(str, [:DIM])
|
107
|
+
end
|
108
|
+
|
109
|
+
def with_inspection_error_guard
|
110
|
+
yield
|
111
|
+
rescue Exception => ex
|
112
|
+
err_msg = "#{ex.inspect} rescued during inspection"
|
113
|
+
string_result = obj.to_s rescue nil
|
114
|
+
|
115
|
+
# don't colorize the string here because it's not from user's application
|
116
|
+
if string_result
|
117
|
+
%Q{"#{string_result}" from #to_s because #{err_msg}}
|
118
|
+
else
|
119
|
+
err_msg
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|