ed-precompiled_debug 1.11.0

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.
@@ -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
@@ -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