debug 1.0.0.beta5 → 1.0.0.beta6
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 +4 -4
- data/CONTRIBUTING.md +193 -2
- data/README.md +20 -12
- data/bin/gentest +22 -0
- data/exe/rdbg +9 -13
- data/lib/debug.rb +3 -0
- data/lib/debug/breakpoint.rb +11 -0
- data/lib/debug/client.rb +5 -7
- data/lib/debug/color.rb +5 -3
- data/lib/debug/config.rb +25 -13
- data/lib/debug/console.rb +13 -0
- data/lib/debug/frame_info.rb +2 -1
- data/lib/debug/open.rb +1 -0
- data/lib/debug/run.rb +3 -2
- data/lib/debug/server.rb +25 -16
- data/lib/debug/server_dap.rb +4 -2
- data/lib/debug/session.rb +140 -64
- data/lib/debug/source_repository.rb +2 -0
- data/lib/debug/thread_client.rb +43 -31
- data/lib/debug/version.rb +3 -1
- data/misc/README.md.erb +13 -9
- metadata +3 -3
- data/lib/debug/test_console.rb +0 -0
data/lib/debug/config.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
module DEBUGGER__
|
3
4
|
def self.unix_domain_socket_dir
|
@@ -34,15 +35,18 @@ module DEBUGGER__
|
|
34
35
|
nonstop: 'RUBY_DEBUG_NONSTOP', # Nonstop mode ('1' is nonstop)
|
35
36
|
init_script: 'RUBY_DEBUG_INIT_SCRIPT', # debug command script path loaded at first stop
|
36
37
|
commands: 'RUBY_DEBUG_COMMANDS', # debug commands invoked at first stop. commands should be separated by ';;'
|
38
|
+
no_rc: 'RUBY_DEBUG_NO_RC', # ignore loading ~/.rdbgrc(.rb)
|
37
39
|
|
38
40
|
# UI setting
|
39
41
|
show_src_lines: 'RUBY_DEBUG_SHOW_SRC_LINES', # Show n lines source code on breakpoint (default: 10 lines).
|
40
42
|
show_frames: 'RUBY_DEBUG_SHOW_FRAMES', # Show n frames on breakpoint (default: 2 frames).
|
41
43
|
use_short_path: 'RUBY_DEBUG_USE_SHORT_PATH', # Show shoten PATH (like $(Gem)/foo.rb).
|
42
44
|
skip_nosrc: 'RUBY_DEBUG_SKIP_NOSRC', # Skip on no source code lines (default: false).
|
43
|
-
|
45
|
+
no_color: 'RUBY_DEBUG_NO_COLOR', # Do not use colorize
|
46
|
+
no_sigint_hook: 'RUBY_DEBUG_NO_SIGINT_HOOK', # Do not suspend on SIGINT
|
47
|
+
quiet: 'RUBY_DEBUG_QUIET', # Do not show messages
|
44
48
|
|
45
|
-
# remote
|
49
|
+
# remote setting
|
46
50
|
port: 'RUBY_DEBUG_PORT', # TCP/IP remote debugging: port
|
47
51
|
host: 'RUBY_DEBUG_HOST', # TCP/IP remote debugging: host (localhost if not given)
|
48
52
|
sock_path: 'RUBY_DEBUG_SOCK_PATH', # UNIX Domain Socket remote debugging: socket path
|
@@ -50,16 +54,15 @@ module DEBUGGER__
|
|
50
54
|
cookie: 'RUBY_DEBUG_COOKIE', # Cookie for negotiation
|
51
55
|
}.freeze
|
52
56
|
|
53
|
-
def self.
|
54
|
-
CONFIG_MAP.
|
55
|
-
|
57
|
+
def self.config_to_env_hash config
|
58
|
+
CONFIG_MAP.each_with_object({}){|(key, evname), env|
|
59
|
+
env[evname] = config[key].to_s if config[key]
|
56
60
|
}
|
57
61
|
end
|
58
62
|
|
59
63
|
def self.parse_argv argv
|
60
64
|
config = {
|
61
65
|
mode: :start,
|
62
|
-
use_colorize: true,
|
63
66
|
}
|
64
67
|
CONFIG_MAP.each{|key, evname|
|
65
68
|
if val = ENV[evname]
|
@@ -90,14 +93,26 @@ module DEBUGGER__
|
|
90
93
|
config[:nonstop] = '1'
|
91
94
|
end
|
92
95
|
|
93
|
-
o.on('-e COMMAND', '
|
96
|
+
o.on('-e COMMAND', 'Execute debug command at the beginning of the script.') do |cmd|
|
94
97
|
config[:commands] ||= ''
|
95
|
-
config[:commands]
|
98
|
+
config[:commands] += cmd + ';;'
|
96
99
|
end
|
97
100
|
|
98
|
-
o.on('-x FILE', '--init-script=FILE', '
|
101
|
+
o.on('-x FILE', '--init-script=FILE', 'Execute debug command in the FILE.') do |file|
|
99
102
|
config[:init_script] = file
|
100
103
|
end
|
104
|
+
o.on('--no-rc', 'Ignore ~/.rdbgrc') do
|
105
|
+
config[:no_rc] = true
|
106
|
+
end
|
107
|
+
o.on('--no-color', 'Disable colorize') do
|
108
|
+
config[:no_color] = true
|
109
|
+
end
|
110
|
+
|
111
|
+
o.on('-c', '--command', 'Enable command mode.',
|
112
|
+
'The first argument should be a command name in $PATH.',
|
113
|
+
'Example: \'rdbg -c bundle exec rake test\'') do
|
114
|
+
config[:command] = true
|
115
|
+
end
|
101
116
|
|
102
117
|
o.separator ''
|
103
118
|
|
@@ -154,11 +169,8 @@ module DEBUGGER__
|
|
154
169
|
exit
|
155
170
|
end
|
156
171
|
|
157
|
-
o.on('-c', '--command', 'Command mode (first argument is command name)') do
|
158
|
-
config[:command] = true
|
159
|
-
end
|
160
|
-
|
161
172
|
o.on('--util=NAME', 'Utility mode (used by tools)') do |name|
|
173
|
+
require_relative 'client'
|
162
174
|
Client.new(name)
|
163
175
|
exit
|
164
176
|
end
|
data/lib/debug/console.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'session'
|
2
4
|
return unless defined?(DEBUGGER__)
|
3
5
|
|
@@ -6,6 +8,17 @@ require 'io/console/size'
|
|
6
8
|
module DEBUGGER__
|
7
9
|
class UI_Console < UI_Base
|
8
10
|
def initialize
|
11
|
+
unless CONFIG[:no_sigint_hook]
|
12
|
+
@prev_handler = trap(:SIGINT){
|
13
|
+
ThreadClient.current.on_trap :SIGINT
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def close
|
19
|
+
if @prev_handler
|
20
|
+
trap(:SIGINT, @prev_handler)
|
21
|
+
end
|
9
22
|
end
|
10
23
|
|
11
24
|
def remote?
|
data/lib/debug/frame_info.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
module DEBUGGER__
|
3
4
|
FrameInfo = Struct.new(:location, :self, :binding, :iseq, :class, :frame_depth,
|
@@ -9,7 +10,7 @@ module DEBUGGER__
|
|
9
10
|
if File.exist? File.join(__dir__, 'debug.so')
|
10
11
|
require_relative 'debug.so'
|
11
12
|
else
|
12
|
-
|
13
|
+
require_relative 'debug'
|
13
14
|
end
|
14
15
|
|
15
16
|
class FrameInfo
|
data/lib/debug/open.rb
CHANGED
data/lib/debug/run.rb
CHANGED
data/lib/debug/server.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'socket'
|
2
4
|
|
3
5
|
require_relative 'session'
|
@@ -13,8 +15,8 @@ module DEBUGGER__
|
|
13
15
|
@accept_m = Mutex.new
|
14
16
|
@accept_cv = ConditionVariable.new
|
15
17
|
@client_addr = nil
|
16
|
-
@q_msg =
|
17
|
-
@q_ans =
|
18
|
+
@q_msg = nil
|
19
|
+
@q_ans = nil
|
18
20
|
@unsent_messages = []
|
19
21
|
@width = 80
|
20
22
|
|
@@ -23,7 +25,7 @@ module DEBUGGER__
|
|
23
25
|
Thread.current.abort_on_exception = true
|
24
26
|
|
25
27
|
accept do |server|
|
26
|
-
DEBUGGER__.
|
28
|
+
DEBUGGER__.warn "Connected."
|
27
29
|
|
28
30
|
@accept_m.synchronize{
|
29
31
|
@sock = server
|
@@ -36,6 +38,9 @@ module DEBUGGER__
|
|
36
38
|
@sock.puts m
|
37
39
|
}
|
38
40
|
@unsent_messages.clear
|
41
|
+
|
42
|
+
@q_msg = Queue.new
|
43
|
+
@q_ans = Queue.new
|
39
44
|
}
|
40
45
|
|
41
46
|
setup_interrupt do
|
@@ -43,12 +48,14 @@ module DEBUGGER__
|
|
43
48
|
end
|
44
49
|
|
45
50
|
rescue => e
|
46
|
-
DEBUGGER__.
|
51
|
+
DEBUGGER__.warn "ReaderThreadError: #{e}", :error
|
47
52
|
ensure
|
48
|
-
DEBUGGER__.
|
53
|
+
DEBUGGER__.warn "Disconnected."
|
49
54
|
@sock = nil
|
50
55
|
@q_msg.close
|
56
|
+
@q_msg = nil
|
51
57
|
@q_ans.close
|
58
|
+
@q_ans = nil
|
52
59
|
end
|
53
60
|
end
|
54
61
|
end
|
@@ -81,9 +88,6 @@ module DEBUGGER__
|
|
81
88
|
end
|
82
89
|
|
83
90
|
def process
|
84
|
-
@q_msg = Queue.new
|
85
|
-
@q_ans = Queue.new
|
86
|
-
|
87
91
|
pause
|
88
92
|
|
89
93
|
while line = @sock.gets
|
@@ -141,12 +145,20 @@ module DEBUGGER__
|
|
141
145
|
if s = @sock # already connection
|
142
146
|
# ok
|
143
147
|
elsif skip == true # skip process
|
144
|
-
|
148
|
+
no_sock = true
|
149
|
+
r = @accept_m.synchronize do
|
150
|
+
if @sock
|
151
|
+
no_sock = false
|
152
|
+
else
|
153
|
+
yield nil
|
154
|
+
end
|
155
|
+
end
|
156
|
+
return r if no_sock
|
145
157
|
else # wait for connection
|
146
158
|
until s = @sock
|
147
159
|
@accept_m.synchronize{
|
148
160
|
unless @sock
|
149
|
-
DEBUGGER__.
|
161
|
+
DEBUGGER__.warn "wait for debuger connection..."
|
150
162
|
@accept_cv.wait(@accept_m)
|
151
163
|
end
|
152
164
|
}
|
@@ -190,6 +202,7 @@ module DEBUGGER__
|
|
190
202
|
def readline
|
191
203
|
(sock do |s|
|
192
204
|
s.puts "input"
|
205
|
+
sleep 0.01 until @q_msg
|
193
206
|
@q_msg.pop
|
194
207
|
end || 'continue').strip
|
195
208
|
end
|
@@ -224,7 +237,7 @@ module DEBUGGER__
|
|
224
237
|
|
225
238
|
def accept
|
226
239
|
Socket.tcp_server_sockets @host, @port do |socks|
|
227
|
-
::DEBUGGER__.
|
240
|
+
::DEBUGGER__.warn "Debugger can attach via TCP/IP (#{socks.map{|e| e.local_address.inspect}})"
|
228
241
|
Socket.accept_loop(socks) do |sock, client|
|
229
242
|
@client_addr = client
|
230
243
|
yield sock
|
@@ -254,7 +267,7 @@ module DEBUGGER__
|
|
254
267
|
@sock_path = DEBUGGER__.create_unix_domain_socket_name(@sock_dir)
|
255
268
|
end
|
256
269
|
|
257
|
-
::DEBUGGER__.
|
270
|
+
::DEBUGGER__.warn "Debugger can attach via UNIX domain socket (#{@sock_path})"
|
258
271
|
Socket.unix_server_loop @sock_path do |sock, client|
|
259
272
|
@client_addr = client
|
260
273
|
yield sock
|
@@ -263,8 +276,4 @@ module DEBUGGER__
|
|
263
276
|
end
|
264
277
|
end
|
265
278
|
end
|
266
|
-
|
267
|
-
def self.message msg
|
268
|
-
$stderr.puts "DEBUGGER: #{msg}"
|
269
|
-
end
|
270
279
|
end
|
data/lib/debug/server_dap.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'json'
|
2
4
|
|
3
5
|
module DEBUGGER__
|
@@ -5,7 +7,7 @@ module DEBUGGER__
|
|
5
7
|
SHOW_PROTOCOL = ENV['RUBY_DEBUG_DAP_SHOW_PROTOCOL'] == '1'
|
6
8
|
|
7
9
|
def dap_setup bytes
|
8
|
-
DEBUGGER__.set_config(
|
10
|
+
DEBUGGER__.set_config(no_color: true)
|
9
11
|
@seq = 0
|
10
12
|
|
11
13
|
$stderr.puts '[>]' + bytes if SHOW_PROTOCOL
|
@@ -436,7 +438,7 @@ module DEBUGGER__
|
|
436
438
|
when :backtrace
|
437
439
|
event! :dap_result, :backtrace, req, {
|
438
440
|
stackFrames: @target_frames.map.with_index{|frame, i|
|
439
|
-
path = frame.
|
441
|
+
path = frame.realpath
|
440
442
|
ref = frame.file_lines unless File.exist?(path)
|
441
443
|
|
442
444
|
{
|
data/lib/debug/session.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
# skip to load debugger for bundle exec
|
3
4
|
return if $0.end_with?('bin/bundle') && ARGV.first == 'exec'
|
4
5
|
|
@@ -52,6 +53,8 @@ class RubyVM::InstructionSequence
|
|
52
53
|
end
|
53
54
|
|
54
55
|
module DEBUGGER__
|
56
|
+
PresetCommand = Struct.new(:commands, :source, :auto_continue)
|
57
|
+
|
55
58
|
class Session
|
56
59
|
def initialize ui
|
57
60
|
@ui = ui
|
@@ -67,7 +70,7 @@ module DEBUGGER__
|
|
67
70
|
@displays = []
|
68
71
|
@tc = nil
|
69
72
|
@tc_id = 0
|
70
|
-
@
|
73
|
+
@preset_command = nil
|
71
74
|
|
72
75
|
@frame_map = {} # {id => [threadId, frame_depth]} for DAP
|
73
76
|
@var_map = {1 => [:globals], } # {id => ...} for DAP
|
@@ -98,6 +101,12 @@ module DEBUGGER__
|
|
98
101
|
@tp_thread_begin.enable
|
99
102
|
end
|
100
103
|
|
104
|
+
def reset_ui ui
|
105
|
+
@ui.close
|
106
|
+
@ui = ui
|
107
|
+
@management_threads << @ui.reader_thread if @ui.respond_to? :reader_thread
|
108
|
+
end
|
109
|
+
|
101
110
|
def session_server_main
|
102
111
|
while evt = @q_evt.pop
|
103
112
|
# varible `@internal_info` is only used for test
|
@@ -105,6 +114,8 @@ module DEBUGGER__
|
|
105
114
|
output.each{|str| @ui.puts str}
|
106
115
|
|
107
116
|
case ev
|
117
|
+
when :init
|
118
|
+
wait_command_loop tc
|
108
119
|
when :load
|
109
120
|
iseq, src = ev_args
|
110
121
|
on_load iseq, src
|
@@ -133,10 +144,6 @@ module DEBUGGER__
|
|
133
144
|
end
|
134
145
|
when :result
|
135
146
|
case ev_args.first
|
136
|
-
when :watch
|
137
|
-
bp = ev_args[1]
|
138
|
-
@bps[bp.key] = bp
|
139
|
-
show_bps bp
|
140
147
|
when :try_display
|
141
148
|
failed_results = ev_args[1]
|
142
149
|
if failed_results.size > 0
|
@@ -145,10 +152,10 @@ module DEBUGGER__
|
|
145
152
|
@ui.puts "canceled: #{@displays.pop}"
|
146
153
|
end
|
147
154
|
end
|
148
|
-
when :method_breakpoint
|
155
|
+
when :method_breakpoint, :watch_breakpoint
|
149
156
|
bp = ev_args[1]
|
150
157
|
if bp
|
151
|
-
|
158
|
+
add_breakpoint(bp)
|
152
159
|
show_bps bp
|
153
160
|
else
|
154
161
|
# can't make a bp
|
@@ -169,15 +176,24 @@ module DEBUGGER__
|
|
169
176
|
@th_clients.each{|th, thc| thc.close}
|
170
177
|
end
|
171
178
|
|
172
|
-
def
|
173
|
-
cmds.
|
174
|
-
c.gsub(
|
175
|
-
|
176
|
-
}
|
179
|
+
def add_preset_commands name, cmds, kick: true, continue: true
|
180
|
+
cs = cmds.map{|c|
|
181
|
+
c = c.strip.gsub(/\A\s*\#.*/, '').strip
|
182
|
+
c unless c.empty?
|
183
|
+
}.compact
|
184
|
+
|
185
|
+
unless cs.empty?
|
186
|
+
if @preset_command
|
187
|
+
@preset_command.commands += cs
|
188
|
+
else
|
189
|
+
@preset_command = PresetCommand.new(cs, name, continue)
|
190
|
+
end
|
191
|
+
ThreadClient.current.on_init name if kick
|
192
|
+
end
|
177
193
|
end
|
178
194
|
|
179
195
|
def source iseq
|
180
|
-
if CONFIG[:
|
196
|
+
if !CONFIG[:no_color]
|
181
197
|
@sr.get_colored(iseq)
|
182
198
|
else
|
183
199
|
@sr.get(iseq)
|
@@ -207,12 +223,23 @@ module DEBUGGER__
|
|
207
223
|
end
|
208
224
|
|
209
225
|
def wait_command
|
210
|
-
if @
|
226
|
+
if @preset_command
|
227
|
+
if @preset_command.commands.empty?
|
228
|
+
if @preset_command.auto_continue
|
229
|
+
@preset_command = nil
|
230
|
+
@tc << :continue
|
231
|
+
return
|
232
|
+
else
|
233
|
+
@preset_command = nil
|
234
|
+
return :retry
|
235
|
+
end
|
236
|
+
else
|
237
|
+
line = @preset_command.commands.shift
|
238
|
+
@ui.puts "(rdbg:#{@preset_command.source}) #{line}"
|
239
|
+
end
|
240
|
+
else
|
211
241
|
@ui.puts "INTERNAL_INFO: #{JSON.generate(@internal_info)}" if ENV['RUBY_DEBUG_TEST_MODE']
|
212
242
|
line = @ui.readline
|
213
|
-
else
|
214
|
-
line = @initial_commands.shift.strip
|
215
|
-
@ui.puts "(rdbg:init) #{line}"
|
216
243
|
end
|
217
244
|
|
218
245
|
case line
|
@@ -247,21 +274,25 @@ module DEBUGGER__
|
|
247
274
|
# * `s[tep]`
|
248
275
|
# * Step in. Resume the program until next breakable point.
|
249
276
|
when 's', 'step'
|
277
|
+
cancel_auto_continue
|
250
278
|
@tc << [:step, :in]
|
251
279
|
|
252
280
|
# * `n[ext]`
|
253
281
|
# * Step over. Resume the program until next line.
|
254
282
|
when 'n', 'next'
|
283
|
+
cancel_auto_continue
|
255
284
|
@tc << [:step, :next]
|
256
285
|
|
257
286
|
# * `fin[ish]`
|
258
287
|
# * Finish this frame. Resume the program until the current frame is finished.
|
259
288
|
when 'fin', 'finish'
|
289
|
+
cancel_auto_continue
|
260
290
|
@tc << [:step, :finish]
|
261
291
|
|
262
292
|
# * `c[ontinue]`
|
263
293
|
# * Resume the program.
|
264
294
|
when 'c', 'continue'
|
295
|
+
cancel_auto_continue
|
265
296
|
@tc << :continue
|
266
297
|
|
267
298
|
# * `q[uit]` or `Ctrl-D`
|
@@ -366,8 +397,8 @@ module DEBUGGER__
|
|
366
397
|
# * Stop the execution when the result of current scope's `@ivar` is changed.
|
367
398
|
# * Note that this feature is super slow.
|
368
399
|
when 'wat', 'watch'
|
369
|
-
if arg
|
370
|
-
@tc << [:
|
400
|
+
if arg && arg.match?(/\A@\w+/)
|
401
|
+
@tc << [:breakpoint, :watch, arg]
|
371
402
|
else
|
372
403
|
show_bps
|
373
404
|
return :retry
|
@@ -481,9 +512,7 @@ module DEBUGGER__
|
|
481
512
|
case arg
|
482
513
|
when /(\d+)/
|
483
514
|
if @displays[n = $1.to_i]
|
484
|
-
|
485
|
-
@displays.delete_at n
|
486
|
-
end
|
515
|
+
@displays.delete_at n
|
487
516
|
end
|
488
517
|
@tc << [:eval, :display, @displays]
|
489
518
|
when nil
|
@@ -560,6 +589,9 @@ module DEBUGGER__
|
|
560
589
|
end
|
561
590
|
@tc << [:eval, :call, 'binding.irb']
|
562
591
|
|
592
|
+
# don't repeat irb command
|
593
|
+
@repl_prev_line = nil
|
594
|
+
|
563
595
|
### Thread control
|
564
596
|
|
565
597
|
# * `th[read]`
|
@@ -608,6 +640,12 @@ module DEBUGGER__
|
|
608
640
|
return :retry
|
609
641
|
end
|
610
642
|
|
643
|
+
def cancel_auto_continue
|
644
|
+
if @preset_command&.auto_continue
|
645
|
+
@preset_command.auto_continue = false
|
646
|
+
end
|
647
|
+
end
|
648
|
+
|
611
649
|
def show_help arg
|
612
650
|
DEBUGGER__.helps.each{|cat, cs|
|
613
651
|
cs.each{|ws, desc|
|
@@ -883,10 +921,16 @@ module DEBUGGER__
|
|
883
921
|
|
884
922
|
def add_breakpoint bp
|
885
923
|
if @bps.has_key? bp.key
|
886
|
-
|
924
|
+
unless bp.duplicable?
|
925
|
+
@ui.puts "duplicated breakpoint: #{bp}"
|
926
|
+
bp.disable
|
927
|
+
end
|
887
928
|
else
|
888
929
|
@bps[bp.key] = bp
|
889
930
|
end
|
931
|
+
|
932
|
+
# don't repeat commands that add breakpoints
|
933
|
+
@repl_prev_line = nil
|
890
934
|
end
|
891
935
|
|
892
936
|
def rehash_bps
|
@@ -932,6 +976,7 @@ module DEBUGGER__
|
|
932
976
|
def add_line_breakpoint file, line, **kw
|
933
977
|
file = resolve_path(file)
|
934
978
|
bp = LineBreakpoint.new(file, line, **kw)
|
979
|
+
|
935
980
|
add_breakpoint bp
|
936
981
|
rescue Errno::ENOENT => e
|
937
982
|
@ui.puts e.message
|
@@ -1022,44 +1067,71 @@ module DEBUGGER__
|
|
1022
1067
|
|
1023
1068
|
# start methods
|
1024
1069
|
|
1025
|
-
def self.
|
1070
|
+
def self.start nonstop: false, **kw
|
1026
1071
|
set_config(kw)
|
1027
1072
|
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1073
|
+
unless defined? SESSION
|
1074
|
+
require_relative 'console'
|
1075
|
+
initialize_session UI_Console.new
|
1076
|
+
end
|
1031
1077
|
|
1032
|
-
|
1033
|
-
ThreadClient.current.on_trap :SIGINT
|
1034
|
-
}
|
1078
|
+
setup_initial_suspend unless nonstop
|
1035
1079
|
end
|
1036
1080
|
|
1037
|
-
def self.open host: nil, port: ::DEBUGGER__::CONFIG[:port], sock_path: nil, sock_dir: nil, **kw
|
1081
|
+
def self.open host: nil, port: ::DEBUGGER__::CONFIG[:port], sock_path: nil, sock_dir: nil, nonstop: false, **kw
|
1038
1082
|
set_config(kw)
|
1039
1083
|
|
1040
1084
|
if port
|
1041
|
-
open_tcp host: host, port: port
|
1085
|
+
open_tcp host: host, port: port, nonstop: nonstop
|
1042
1086
|
else
|
1043
|
-
open_unix sock_path: sock_path, sock_dir: sock_dir
|
1087
|
+
open_unix sock_path: sock_path, sock_dir: sock_dir, nonstop: nonstop
|
1044
1088
|
end
|
1045
1089
|
end
|
1046
1090
|
|
1047
|
-
def self.open_tcp host: nil, port:, **kw
|
1091
|
+
def self.open_tcp host: nil, port:, nonstop: false, **kw
|
1048
1092
|
set_config(kw)
|
1049
1093
|
require_relative 'server'
|
1050
|
-
|
1094
|
+
|
1095
|
+
if defined? SESSION
|
1096
|
+
SESSION.reset_ui UI_TcpServer.new(host: host, port: port)
|
1097
|
+
else
|
1098
|
+
initialize_session UI_TcpServer.new(host: host, port: port)
|
1099
|
+
end
|
1100
|
+
|
1101
|
+
setup_initial_suspend unless nonstop
|
1051
1102
|
end
|
1052
1103
|
|
1053
|
-
def self.open_unix sock_path: nil, sock_dir: nil, **kw
|
1104
|
+
def self.open_unix sock_path: nil, sock_dir: nil, nonstop: false, **kw
|
1054
1105
|
set_config(kw)
|
1055
1106
|
require_relative 'server'
|
1056
|
-
|
1107
|
+
|
1108
|
+
if defined? SESSION
|
1109
|
+
SESSION.reset_ui UI_UnixDomainServer.new(sock_dir: sock_dir, sock_path: sock_path)
|
1110
|
+
else
|
1111
|
+
initialize_session UI_UnixDomainServer.new(sock_dir: sock_dir, sock_path: sock_path)
|
1112
|
+
end
|
1113
|
+
|
1114
|
+
setup_initial_suspend unless nonstop
|
1057
1115
|
end
|
1058
1116
|
|
1059
1117
|
# boot utilities
|
1060
1118
|
|
1119
|
+
def self.setup_initial_suspend
|
1120
|
+
if !::DEBUGGER__::CONFIG[:nonstop]
|
1121
|
+
if loc = ::DEBUGGER__.require_location
|
1122
|
+
# require 'debug/console' or 'debug'
|
1123
|
+
add_line_breakpoint loc.absolute_path, loc.lineno + 1, oneshot: true, hook_call: false
|
1124
|
+
else
|
1125
|
+
# -r
|
1126
|
+
add_line_breakpoint $0, 1, oneshot: true, hook_call: false
|
1127
|
+
end
|
1128
|
+
end
|
1129
|
+
end
|
1130
|
+
|
1061
1131
|
class << self
|
1062
1132
|
define_method :initialize_session do |ui|
|
1133
|
+
DEBUGGER__.warn "Session start (pid: #{Process.pid})"
|
1134
|
+
|
1063
1135
|
::DEBUGGER__.const_set(:SESSION, Session.new(ui))
|
1064
1136
|
|
1065
1137
|
# default breakpoints
|
@@ -1067,10 +1139,15 @@ module DEBUGGER__
|
|
1067
1139
|
# ::DEBUGGER__.add_catch_breakpoint 'RuntimeError'
|
1068
1140
|
|
1069
1141
|
Binding.module_eval do
|
1070
|
-
def bp command: nil
|
1142
|
+
def bp command: nil, nonstop: nil
|
1071
1143
|
if command
|
1072
1144
|
cmds = command.split(";;")
|
1073
|
-
|
1145
|
+
# nonstop
|
1146
|
+
# nil, true -> auto_continue
|
1147
|
+
# false -> stop
|
1148
|
+
SESSION.add_preset_commands 'binding.bp(command:)', cmds,
|
1149
|
+
kick: false,
|
1150
|
+
continue: nonstop == false ? false : true
|
1074
1151
|
end
|
1075
1152
|
|
1076
1153
|
::DEBUGGER__.add_line_breakpoint __FILE__, __LINE__ + 1, oneshot: true
|
@@ -1078,36 +1155,26 @@ module DEBUGGER__
|
|
1078
1155
|
end
|
1079
1156
|
end
|
1080
1157
|
|
1081
|
-
if !::DEBUGGER__::CONFIG[:nonstop]
|
1082
|
-
if loc = ::DEBUGGER__.require_location
|
1083
|
-
# require 'debug/console' or 'debug'
|
1084
|
-
add_line_breakpoint loc.absolute_path, loc.lineno + 1, oneshot: true, hook_call: false
|
1085
|
-
else
|
1086
|
-
# -r
|
1087
|
-
add_line_breakpoint $0, 1, oneshot: true, hook_call: false
|
1088
|
-
end
|
1089
|
-
end
|
1090
|
-
|
1091
1158
|
load_rc
|
1092
1159
|
end
|
1093
1160
|
end
|
1094
1161
|
|
1095
1162
|
def self.load_rc
|
1096
|
-
[
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
[init_script = ::DEBUGGER__::CONFIG[:init_script],
|
1104
|
-
'./.rdbgrc',
|
1105
|
-
File.expand_path('~/.rdbgrc')].each{|path|
|
1106
|
-
next unless path
|
1163
|
+
[[File.expand_path('~/.rdbgrc'), true],
|
1164
|
+
[File.expand_path('~/.rdbgrc.rb'), true],
|
1165
|
+
# ['./.rdbgrc', true], # disable because of security concern
|
1166
|
+
[::DEBUGGER__::CONFIG[:init_script], false],
|
1167
|
+
].each{|(path, rc)|
|
1168
|
+
next unless path
|
1169
|
+
next if rc && ::DEBUGGER__::CONFIG[:no_rc] # ignore rc
|
1107
1170
|
|
1108
1171
|
if File.file? path
|
1109
|
-
|
1110
|
-
|
1172
|
+
if path.end_with?('.rb')
|
1173
|
+
load path
|
1174
|
+
else
|
1175
|
+
::DEBUGGER__::SESSION.add_preset_commands path, File.readlines(path)
|
1176
|
+
end
|
1177
|
+
elsif !rc
|
1111
1178
|
warn "Not found: #{path}"
|
1112
1179
|
end
|
1113
1180
|
}
|
@@ -1115,7 +1182,7 @@ module DEBUGGER__
|
|
1115
1182
|
# given debug commands
|
1116
1183
|
if ::DEBUGGER__::CONFIG[:commands]
|
1117
1184
|
cmds = ::DEBUGGER__::CONFIG[:commands].split(';;')
|
1118
|
-
::DEBUGGER__::SESSION.
|
1185
|
+
::DEBUGGER__::SESSION.add_preset_commands "commands", cmds, kick: false, continue: false
|
1119
1186
|
end
|
1120
1187
|
end
|
1121
1188
|
|
@@ -1194,4 +1261,13 @@ module DEBUGGER__
|
|
1194
1261
|
str
|
1195
1262
|
end
|
1196
1263
|
end
|
1264
|
+
|
1265
|
+
def self.warn msg, level = :warn
|
1266
|
+
case level
|
1267
|
+
when :warn
|
1268
|
+
STDERR.puts "DEBUGGER: #{msg}" unless CONFIG[:quiet]
|
1269
|
+
when :error
|
1270
|
+
STDERR.puts "DEBUGGER: #{msg}"
|
1271
|
+
end
|
1272
|
+
end
|
1197
1273
|
end
|