debug 1.0.0.beta5 → 1.0.0.beta6

Sign up to get free protection for your applications and to get access to all the features.
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