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.
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
- use_colorize: 'RUBY_DEBUG_USE_COLORIZE', # Show coloring
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.config_to_env config
54
- CONFIG_MAP.each{|key, evname|
55
- ENV[evname] = config[key].to_s if config[key]
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', 'execute debug command at the beginning of the script.') do |cmd|
96
+ o.on('-e COMMAND', 'Execute debug command at the beginning of the script.') do |cmd|
94
97
  config[:commands] ||= ''
95
- config[:commands] << cmd + ';;'
98
+ config[:commands] += cmd + ';;'
96
99
  end
97
100
 
98
- o.on('-x FILE', '--init-script=FILE', 'execute debug command in the FILE.') do |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?
@@ -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
- require "debug/debug"
13
+ require_relative 'debug'
13
14
  end
14
15
 
15
16
  class FrameInfo
data/lib/debug/open.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  #
2
3
  # Open the door for the debugger to connect.
3
4
  # Users can connect to debuggee program with "rdbg --attach" option.
data/lib/debug/run.rb CHANGED
@@ -1,4 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'console'
2
4
  return unless defined?(DEBUGGER__)
3
-
4
- DEBUGGER__.console
5
+ DEBUGGER__.start
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 = Queue.new
17
- @q_ans = Queue.new
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__.message "Connected."
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__.message "ReaderThreadError: #{e}"
51
+ DEBUGGER__.warn "ReaderThreadError: #{e}", :error
47
52
  ensure
48
- DEBUGGER__.message "Disconnected."
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
- return yield nil
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__.message "wait for debuger connection..."
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__.message "Debugger can attach via TCP/IP (#{socks.map{|e| e.local_address.inspect}})"
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__.message "Debugger can attach via UNIX domain socket (#{@sock_path})"
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
@@ -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(use_colorize: false)
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.path
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
- @initial_commands = []
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
- @bps[bp.key] = bp
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 add_initial_commands cmds
173
- cmds.each{|c|
174
- c.gsub('#.*', '').strip!
175
- @initial_commands << c unless c.empty?
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[:use_colorize]
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 @initial_commands.empty?
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 << [:eval, :watch, arg]
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
- if ask "clear \##{n} #{@displays[n]}?"
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
- @ui.puts "duplicated breakpoint: #{bp}"
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.console **kw
1070
+ def self.start nonstop: false, **kw
1026
1071
  set_config(kw)
1027
1072
 
1028
- require_relative 'console'
1029
-
1030
- initialize_session UI_Console.new
1073
+ unless defined? SESSION
1074
+ require_relative 'console'
1075
+ initialize_session UI_Console.new
1076
+ end
1031
1077
 
1032
- @prev_handler = trap(:SIGINT){
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
- initialize_session UI_TcpServer.new(host: host, port: port)
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
- initialize_session UI_UnixDomainServer.new(sock_dir: sock_dir, sock_path: sock_path)
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
- SESSION.add_initial_commands cmds
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
- ['./rdbgrc.rb', File.expand_path('~/.rdbgrc.rb')].each{|path|
1097
- if File.file? path
1098
- load path
1099
- end
1100
- }
1101
-
1102
- # debug commands file
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
- ::DEBUGGER__::SESSION.add_initial_commands File.readlines(path)
1110
- elsif path == init_script
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.add_initial_commands cmds
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