debug 1.3.3 → 1.5.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.
@@ -4,11 +4,17 @@ require_relative 'color'
4
4
 
5
5
  module DEBUGGER__
6
6
  class Breakpoint
7
+ include SkipPathHelper
8
+
7
9
  attr_reader :key
8
10
 
9
- def initialize do_enable = true
11
+ def initialize cond, command, path, do_enable: true
10
12
  @deleted = false
11
13
 
14
+ @cond = cond
15
+ @command = command
16
+ @path = path
17
+
12
18
  setup
13
19
  enable if do_enable
14
20
  end
@@ -23,6 +29,10 @@ module DEBUGGER__
23
29
  nil
24
30
  end
25
31
 
32
+ def oneshot?
33
+ defined?(@oneshot) && @oneshot
34
+ end
35
+
26
36
  def setup
27
37
  raise "not implemented..."
28
38
  end
@@ -75,6 +85,17 @@ module DEBUGGER__
75
85
  false
76
86
  end
77
87
 
88
+ def skip_path?(path)
89
+ case @path
90
+ when Regexp
91
+ !path.match?(@path)
92
+ when String
93
+ !path.include?(@path)
94
+ else
95
+ super
96
+ end
97
+ end
98
+
78
99
  include Color
79
100
 
80
101
  def generate_label(name)
@@ -87,24 +108,43 @@ module DEBUGGER__
87
108
  TracePoint.new(:line){}.enable{}
88
109
  end
89
110
 
111
+ class ISeqBreakpoint < Breakpoint
112
+ def initialize iseq, events, oneshot: false
113
+ @events = events
114
+ @iseq = iseq
115
+ @oneshot = oneshot
116
+ @key = [:iseq, @iseq.path, @iseq.first_lineno].freeze
117
+
118
+ super(nil, nil, nil)
119
+ end
120
+
121
+ def setup
122
+ @tp = TracePoint.new(*@events) do |tp|
123
+ delete if @oneshot
124
+ suspend
125
+ end
126
+ end
127
+
128
+ def enable
129
+ @tp.enable(target: @iseq)
130
+ end
131
+ end
132
+
90
133
  class LineBreakpoint < Breakpoint
91
134
  attr_reader :path, :line, :iseq
92
135
 
93
136
  def initialize path, line, cond: nil, oneshot: false, hook_call: true, command: nil
94
- @path = path
95
137
  @line = line
96
- @cond = cond
97
138
  @oneshot = oneshot
98
139
  @hook_call = hook_call
99
- @command = command
100
140
  @pending = false
101
141
 
102
142
  @iseq = nil
103
143
  @type = nil
104
144
 
105
- @key = [@path, @line].freeze
145
+ @key = [path, @line].freeze
106
146
 
107
- super()
147
+ super(cond, command, path)
108
148
 
109
149
  try_activate
110
150
  @pending = !@iseq
@@ -180,7 +220,7 @@ module DEBUGGER__
180
220
  nearest = nil # NearestISeq
181
221
 
182
222
  ObjectSpace.each_iseq{|iseq|
183
- if (iseq.absolute_path || iseq.path) == self.path &&
223
+ if DEBUGGER__.compare_path((iseq.absolute_path || iseq.path), self.path) &&
184
224
  iseq.first_lineno <= self.line &&
185
225
  iseq.type != :ensure # ensure iseq is copied (duplicated)
186
226
 
@@ -235,24 +275,21 @@ module DEBUGGER__
235
275
 
236
276
  class CatchBreakpoint < Breakpoint
237
277
  attr_reader :last_exc
238
- include SkipPathHelper
239
278
 
240
- def initialize pat, cond: nil, command: nil
279
+ def initialize pat, cond: nil, command: nil, path: nil
241
280
  @pat = pat.freeze
242
281
  @key = [:catch, @pat].freeze
243
282
  @last_exc = nil
244
283
 
245
- @cond = cond
246
- @command = command
247
-
248
- super()
284
+ super(cond, command, path)
249
285
  end
250
286
 
251
287
  def setup
252
288
  @tp = TracePoint.new(:raise){|tp|
253
- next if skip_path?(tp.path)
254
289
  exc = tp.raised_exception
255
290
  next if SystemExit === exc
291
+ next if skip_path?(tp.path)
292
+
256
293
  next if !safe_eval(tp.binding, @cond) if @cond
257
294
  should_suspend = false
258
295
 
@@ -277,47 +314,52 @@ module DEBUGGER__
277
314
  end
278
315
 
279
316
  class CheckBreakpoint < Breakpoint
280
- def initialize expr
281
- @expr = expr.freeze
282
- @key = [:check, @expr].freeze
317
+ def initialize cond:, command: nil, path: nil
318
+ @key = [:check, cond].freeze
283
319
 
284
- super()
320
+ super(cond, command, path)
285
321
  end
286
322
 
287
323
  def setup
288
324
  @tp = TracePoint.new(:line){|tp|
289
- next if tp.path.start_with? __dir__
290
- next if tp.path.start_with? '<internal:'
325
+ next if SESSION.in_subsession? # TODO: Ractor support
291
326
  next if ThreadClient.current.management?
327
+ next if skip_path?(tp.path)
292
328
 
293
- if safe_eval tp.binding, @expr
329
+ if safe_eval tp.binding, @cond
294
330
  suspend
295
331
  end
296
332
  }
297
333
  end
298
334
 
299
335
  def to_s
300
- "#{generate_label("Check")} #{@expr}"
336
+ s = "#{generate_label("Check")}"
337
+ s += super
338
+ s
301
339
  end
302
340
  end
303
341
 
304
342
  class WatchIVarBreakpoint < Breakpoint
305
- def initialize ivar, object, current
343
+ def initialize ivar, object, current, cond: nil, command: nil, path: nil
306
344
  @ivar = ivar.to_sym
307
345
  @object = object
308
- @key = [:watch, @ivar].freeze
346
+ @key = [:watch, object.object_id, @ivar].freeze
309
347
 
310
348
  @current = current
311
- super()
349
+
350
+ super(cond, command, path)
312
351
  end
313
352
 
314
- def watch_eval
353
+ def watch_eval(tp)
315
354
  result = @object.instance_variable_get(@ivar)
316
355
  if result != @current
317
356
  begin
318
357
  @prev = @current
319
358
  @current = result
320
- suspend
359
+
360
+ if (@cond.nil? || @object.instance_eval(@cond)) && !skip_path?(tp.path)
361
+ suspend
362
+ end
321
363
  ensure
322
364
  remove_instance_variable(:@prev)
323
365
  end
@@ -328,10 +370,7 @@ module DEBUGGER__
328
370
 
329
371
  def setup
330
372
  @tp = TracePoint.new(:line, :return, :b_return){|tp|
331
- next if tp.path.start_with? __dir__
332
- next if tp.path.start_with? '<internal:'
333
-
334
- watch_eval
373
+ watch_eval(tp)
335
374
  }
336
375
  end
337
376
 
@@ -349,7 +388,7 @@ module DEBUGGER__
349
388
  class MethodBreakpoint < Breakpoint
350
389
  attr_reader :sig_method_name, :method
351
390
 
352
- def initialize b, klass_name, op, method_name, cond: nil, command: nil
391
+ def initialize b, klass_name, op, method_name, cond: nil, command: nil, path: nil
353
392
  @sig_klass_name = klass_name
354
393
  @sig_op = op
355
394
  @sig_method_name = method_name
@@ -358,19 +397,19 @@ module DEBUGGER__
358
397
 
359
398
  @klass = nil
360
399
  @method = nil
361
- @cond = cond
362
400
  @cond_class = nil
363
- @command = command
364
401
  @key = "#{klass_name}#{op}#{method_name}".freeze
365
402
 
366
- super(false)
403
+ super(cond, command, path, do_enable: false)
367
404
  end
368
405
 
369
406
  def setup
370
407
  @tp = TracePoint.new(:call){|tp|
371
408
  next if !safe_eval(tp.binding, @cond) if @cond
372
409
  next if @cond_class && !tp.self.kind_of?(@cond_class)
373
- next if @override_method ? (caller_locations(2, 1).first.to_s.start_with?(__dir__)) : tp.path.start_with?(__dir__)
410
+
411
+ caller_location = caller_locations(2, 1).first.to_s
412
+ next if skip_path?(caller_location)
374
413
 
375
414
  suspend
376
415
  }
data/lib/debug/client.rb CHANGED
@@ -18,29 +18,69 @@ module DEBUGGER__
18
18
  case name
19
19
  when 'gen-sockpath'
20
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
21
25
  when 'list-socks'
22
26
  cleanup_unix_domain_sockets
23
27
  puts list_connections
24
- when 'init'
25
- if ARGV.shift == '-'
26
- puts <<~EOS
27
- export RUBYOPT="-r #{__dir__}/prelude $(RUBYOPT)"
28
- EOS
29
- else
30
- puts <<~EOS
31
- # add the following lines in your .bash_profile
32
-
33
- eval "$(rdbg init -)"
34
- EOS
35
- end
28
+ when 'setup-autoload'
29
+ setup_autoload
30
+ else
31
+ abort "Unknown utility: #{name}"
32
+ end
33
+ end
34
+
35
+ def working_shell_type
36
+ shell = `ps -p #{Process.ppid} -o 'args='`
37
+ case shell
38
+ when /bash/
39
+ :bash
40
+ when /fish/
41
+ :fish
42
+ when /csh/
43
+ :csh
44
+ when /zsh/
45
+ :szh
46
+ when /dash/
47
+ :dash
48
+ else
49
+ :unknown
50
+ end
51
+ end
52
+
53
+ def setup_autoload
54
+ prelude_path = File.join(__dir__, 'prelude.rb')
55
+
56
+ case shell = working_shell_type
57
+ when :bash, :zsh
58
+ puts <<~EOS
59
+ # add the following lines in your ~/.#{shell}_profile
60
+
61
+ if test -s #{prelude_path} ; then
62
+ export RUBYOPT='-r #{prelude_path}'
63
+ fi
64
+
65
+ # Add `Kernel#bb` method which is alias of `Kernel#debugger`
66
+ # export RUBY_DEBUG_BB=1
67
+ EOS
68
+
69
+ when :fish
70
+ puts <<~EOS
71
+ # add the following lines in your ~/.config/fish/config.fish
72
+ set -x RUBYOPT "-r #{__dir__}/prelude" $RUBYOPT
73
+ EOS
74
+
36
75
  else
37
- raise "Unknown utility: #{name}"
76
+ puts "# Sorry that your shell is not supported yet.",
77
+ "# Please use the content in #{prelude_path} as a reference and modify your login script accordingly."
38
78
  end
39
79
  end
40
80
 
41
81
  def cleanup_unix_domain_sockets
42
82
  Dir.glob(DEBUGGER__.create_unix_domain_socket_name_prefix + '*') do |file|
43
- if /(\d+)$/ =~ file
83
+ if File.socket?(file) && (/-(\d+)-\d+$/ =~ file || /-(\d+)$/ =~ file)
44
84
  begin
45
85
  Process.kill(0, $1.to_i)
46
86
  rescue Errno::EPERM
@@ -52,7 +92,9 @@ module DEBUGGER__
52
92
  end
53
93
 
54
94
  def list_connections
55
- Dir.glob(DEBUGGER__.create_unix_domain_socket_name_prefix + '*')
95
+ Dir.glob(DEBUGGER__.create_unix_domain_socket_name_prefix + '*').find_all do |path|
96
+ File.socket?(path)
97
+ end
56
98
  end
57
99
  end
58
100
 
@@ -134,9 +176,14 @@ module DEBUGGER__
134
176
  trap(:SIGINT){
135
177
  send "pause"
136
178
  }
137
- trap(:SIGWINCH){
138
- @width = IO.console_size[1]
139
- }
179
+
180
+ begin
181
+ trap(:SIGWINCH){
182
+ @width = IO.console_size[1]
183
+ }
184
+ rescue ArgumentError
185
+ @width = 80
186
+ end
140
187
 
141
188
  while line = @s.gets
142
189
  p recv: line if $VERBOSE
data/lib/debug/color.rb CHANGED
@@ -48,33 +48,29 @@ module DEBUGGER__
48
48
 
49
49
  if defined? IRB::ColorPrinter.pp
50
50
  def color_pp obj, width
51
- if !CONFIG[:no_color]
52
- IRB::ColorPrinter.pp(obj, "".dup, width)
53
- else
54
- obj.pretty_inspect
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
55
57
  end
56
58
  end
57
59
  else
58
60
  def color_pp obj, width
59
- obj.pretty_inspect
61
+ with_inspection_error_guard do
62
+ obj.pretty_inspect
63
+ end
60
64
  end
61
65
  end
62
66
 
63
67
  def colored_inspect obj, width: SESSION.width, no_color: false
64
- if !no_color
65
- color_pp obj, width
66
- else
67
- obj.pretty_inspect
68
- end
69
- rescue => ex
70
- err_msg = "#{ex.inspect} rescued during inspection"
71
- string_result = obj.to_s rescue nil
72
-
73
- # don't colorize the string here because it's not from user's application
74
- if string_result
75
- %Q{"#{string_result}" from #to_s because #{err_msg}}
76
- else
77
- err_msg
68
+ with_inspection_error_guard do
69
+ if !no_color
70
+ color_pp obj, width
71
+ else
72
+ obj.pretty_inspect
73
+ end
78
74
  end
79
75
  end
80
76
 
@@ -109,5 +105,19 @@ module DEBUGGER__
109
105
  def colorize_dim(str)
110
106
  colorize(str, [:DIM])
111
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
112
122
  end
113
123
  end
data/lib/debug/config.rb CHANGED
@@ -43,20 +43,23 @@ module DEBUGGER__
43
43
  sock_dir: ['RUBY_DEBUG_SOCK_DIR', "REMOTE: UNIX Domain Socket remote debugging: socket directory"],
44
44
  cookie: ['RUBY_DEBUG_COOKIE', "REMOTE: Cookie for negotiation"],
45
45
  open_frontend: ['RUBY_DEBUG_OPEN_FRONTEND',"REMOTE: frontend used by open command (vscode, chrome, default: rdbg)."],
46
+ chrome_path: ['RUBY_DEBUG_CHROME_PATH', "REMOTE: Platform dependent path of Chrome (For more information, See [here](https://github.com/ruby/debug/pull/334/files#diff-5fc3d0a901379a95bc111b86cf0090b03f857edfd0b99a0c1537e26735698453R55-R64))"],
46
47
 
47
48
  # obsolete
48
49
  parent_on_fork: ['RUBY_DEBUG_PARENT_ON_FORK', "OBSOLETE: Keep debugging parent process on fork (default: false)", :bool],
49
50
  }.freeze
50
51
 
51
- CONFIG_MAP = CONFIG_SET.map{|k, (ev, desc)| [k, ev]}.to_h.freeze
52
+ CONFIG_MAP = CONFIG_SET.map{|k, (ev, _)| [k, ev]}.to_h.freeze
52
53
 
53
54
  class Config
55
+ @config = nil
56
+
54
57
  def self.config
55
58
  @config
56
59
  end
57
60
 
58
61
  def initialize argv
59
- if self.class.instance_variable_defined? :@config
62
+ if self.class.config
60
63
  raise 'Can not make multiple configurations in one process'
61
64
  end
62
65
 
@@ -480,7 +483,7 @@ module DEBUGGER__
480
483
  self.helps.each{|cat, cmds|
481
484
  r << "### #{cat}"
482
485
  r << ''
483
- cmds.each{|ws, desc|
486
+ cmds.each{|_, desc|
484
487
  r << desc
485
488
  }
486
489
  r << ''
data/lib/debug/console.rb CHANGED
@@ -30,10 +30,38 @@ module DEBUGGER__
30
30
  prepend m
31
31
  end if SIGWINCH_SUPPORTED
32
32
 
33
+ def parse_input buff, commands
34
+ c, rest = get_command buff
35
+ case
36
+ when commands.keys.include?(c)
37
+ :command
38
+ when !rest && /\A\s*[a-z]*\z/ =~ c
39
+ nil
40
+ else
41
+ :ruby
42
+ end
43
+ end
44
+
33
45
  def readline_setup prompt
34
46
  load_history_if_not_loaded
35
47
  commands = DEBUGGER__.commands
36
48
 
49
+ prev_completion_proc = Reline.completion_proc
50
+ prev_output_modifier_proc = Reline.output_modifier_proc
51
+ prev_prompt_proc = Reline.prompt_proc
52
+
53
+ # prompt state
54
+ state = nil # :command, :ruby, nil (unknown)
55
+
56
+ Reline.prompt_proc = -> args, *kw do
57
+ case state = parse_input(args.first, commands)
58
+ when nil, :command
59
+ [prompt, prompt]
60
+ when :ruby
61
+ [prompt.sub('rdbg'){colorize('ruby', [:RED])}] * 2
62
+ end
63
+ end
64
+
37
65
  Reline.completion_proc = -> given do
38
66
  buff = Reline.line_buffer
39
67
  Reline.completion_append_character= ' '
@@ -46,17 +74,16 @@ module DEBUGGER__
46
74
  end
47
75
  files
48
76
  else
49
- commands.keys.grep(/\A#{given}/)
77
+ commands.keys.grep(/\A#{Regexp.escape(given)}/)
50
78
  end
51
79
  end
52
80
 
53
81
  Reline.output_modifier_proc = -> buff, **kw do
54
82
  c, rest = get_command buff
55
83
 
56
- case
57
- when commands.keys.include?(c = c.strip)
58
- # [:DIM, :CYAN, :BLUE, :CLEAR, :UNDERLINE, :REVERSE, :RED, :GREEN, :MAGENTA, :BOLD, :YELLOW]
59
- cmd = colorize(c.strip, [:CYAN, :UNDERLINE])
84
+ case state
85
+ when :command
86
+ cmd = colorize(c, [:CYAN, :UNDERLINE])
60
87
 
61
88
  if commands[c] == c
62
89
  rprompt = colorize(" # command", [:DIM])
@@ -64,28 +91,36 @@ module DEBUGGER__
64
91
  rprompt = colorize(" # #{commands[c]} command", [:DIM])
65
92
  end
66
93
 
67
- rest = (rest ? colorize_code(rest) : '') + rprompt
68
- cmd + rest
69
- when !rest && /\A\s*[a-z]*\z/ =~ c
94
+ rest = rest ? colorize_code(rest) : ''
95
+ cmd + rest + rprompt
96
+ when nil
70
97
  buff
71
- else
72
- colorize_code(buff.chomp) + colorize(" # ruby", [:DIM])
98
+ when :ruby
99
+ colorize_code(buff.chomp)
73
100
  end
74
101
  end
102
+
103
+ yield
104
+
105
+ ensure
106
+ Reline.completion_proc = prev_completion_proc
107
+ Reline.output_modifier_proc = prev_output_modifier_proc
108
+ Reline.prompt_proc = prev_prompt_proc
75
109
  end
76
110
 
77
111
  private def get_command line
78
112
  case line.chomp
79
113
  when /\A(\s*[a-z]+)(\s.*)?\z$/
80
- return $1, $2
114
+ return $1.strip, $2
81
115
  else
82
- line.chomp
116
+ line.strip
83
117
  end
84
118
  end
85
119
 
86
120
  def readline prompt
87
- readline_setup prompt
88
- Reline.readmultiline(prompt, true){ true }
121
+ readline_setup prompt do
122
+ Reline.readmultiline(prompt, true){ true }
123
+ end
89
124
  end
90
125
 
91
126
  def history
@@ -145,7 +180,7 @@ module DEBUGGER__
145
180
  FH = "# Today's OMIKUJI: "
146
181
 
147
182
  def read_history_file
148
- if history && File.exists?(path = history_file)
183
+ if history && File.exist?(path = history_file)
149
184
  f = (['', 'DAI-', 'CHU-', 'SHO-'].map{|e| e+'KICHI'}+['KYO']).sample
150
185
  ["#{FH}#{f}".dup] + File.readlines(path)
151
186
  else
@@ -2,10 +2,11 @@
2
2
 
3
3
  module DEBUGGER__
4
4
  FrameInfo = Struct.new(:location, :self, :binding, :iseq, :class, :frame_depth,
5
- :has_return_value, :return_value,
5
+ :has_return_value, :return_value,
6
6
  :has_raised_exception, :raised_exception,
7
7
  :show_line,
8
- :_local_variables, :_callee # for recorder
8
+ :_local_variables, :_callee, # for recorder
9
+ :dupped_binding,
9
10
  )
10
11
 
11
12
  # extend FrameInfo with debug.so
@@ -31,7 +32,7 @@ module DEBUGGER__
31
32
  use_short_path = CONFIG[:use_short_path]
32
33
 
33
34
  case
34
- when use_short_path && path.start_with?(dir = CONFIG["rubylibdir"] + '/')
35
+ when use_short_path && path.start_with?(dir = RbConfig::CONFIG["rubylibdir"] + '/')
35
36
  path.sub(dir, '$(rubylibdir)/')
36
37
  when use_short_path && Gem.path.any? do |gp|
37
38
  path.start_with?(dir = gp + '/gems/')
@@ -82,14 +83,14 @@ module DEBUGGER__
82
83
 
83
84
  def block_identifier
84
85
  return unless frame_type == :block
85
- args = parameters_info(iseq.argc)
86
+ args = parameters_info
86
87
  _, level, block_loc = location.label.match(BLOCK_LABL_REGEXP).to_a
87
88
  [level || "", block_loc, args]
88
89
  end
89
90
 
90
91
  def method_identifier
91
92
  return unless frame_type == :method
92
- args = parameters_info(iseq.argc)
93
+ args = parameters_info
93
94
  ci = "#{klass_sig}#{callee}"
94
95
  [ci, args]
95
96
  end
@@ -110,7 +111,7 @@ module DEBUGGER__
110
111
 
111
112
  def return_str
112
113
  if self.binding && iseq && has_return_value
113
- DEBUGGER__.short_inspect(return_value)
114
+ DEBUGGER__.safe_inspect(return_value, short: true)
114
115
  end
115
116
  end
116
117
 
@@ -118,19 +119,12 @@ module DEBUGGER__
118
119
  "#{pretty_path}:#{location.lineno}"
119
120
  end
120
121
 
121
- private def make_binding
122
- __newb__ = self.self.instance_eval('binding')
123
- self.local_variables.each{|var, val|
124
- __newb__.local_variable_set(var, val)
125
- }
126
- __newb__
127
- end
128
-
129
122
  def eval_binding
130
- if b = self.binding
123
+ if b = self.dupped_binding
131
124
  b
132
- elsif self.local_variables
133
- make_binding
125
+ else
126
+ b = self.binding || TOPLEVEL_BINDING
127
+ self.dupped_binding = b.dup
134
128
  end
135
129
  end
136
130
 
@@ -156,11 +150,11 @@ module DEBUGGER__
156
150
  local_variables[var]
157
151
  end
158
152
 
159
- def parameters_info(argc)
160
- vars = iseq.locals[0...argc]
153
+ def parameters_info
154
+ vars = iseq.parameters_symbols
161
155
  vars.map{|var|
162
156
  begin
163
- { name: var, value: DEBUGGER__.short_inspect(local_variable_get(var)) }
157
+ { name: var, value: DEBUGGER__.safe_inspect(local_variable_get(var), short: true) }
164
158
  rescue NameError, TypeError
165
159
  nil
166
160
  end
data/lib/debug/local.rb CHANGED
@@ -98,7 +98,7 @@ module DEBUGGER__
98
98
  # only check child process from its parent
99
99
  begin
100
100
  # wait for all child processes to keep terminal
101
- loop{ Process.waitpid }
101
+ Process.waitpid
102
102
  rescue Errno::ESRCH, Errno::ECHILD
103
103
  end
104
104
  end
data/lib/debug/prelude.rb CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  return if defined?(::DEBUGGER__)
4
4
 
5
+ # Put the following line in your login script (e.g. ~/.bash_profile) with modified path:
5
6
  #
6
- # put the following line in .bash_profile
7
- # export RUBYOPT="-r .../debug/prelude $(RUBYOPT)"
7
+ # export RUBYOPT="-r /path/to/debug/prelude $(RUBYOPT)"
8
8
  #
9
9
  module Kernel
10
10
  def debugger(*a, up_level: 0, **kw)