debug 1.4.0 → 1.9.2

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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +210 -6
  3. data/Gemfile +2 -0
  4. data/LICENSE.txt +0 -0
  5. data/README.md +161 -85
  6. data/Rakefile +33 -10
  7. data/TODO.md +8 -8
  8. data/debug.gemspec +9 -7
  9. data/exe/rdbg +23 -4
  10. data/ext/debug/debug.c +111 -21
  11. data/ext/debug/extconf.rb +23 -0
  12. data/ext/debug/iseq_collector.c +2 -0
  13. data/lib/debug/abbrev_command.rb +77 -0
  14. data/lib/debug/breakpoint.rb +102 -74
  15. data/lib/debug/client.rb +46 -12
  16. data/lib/debug/color.rb +0 -0
  17. data/lib/debug/config.rb +129 -36
  18. data/lib/debug/console.rb +46 -40
  19. data/lib/debug/dap_custom/traceInspector.rb +336 -0
  20. data/lib/debug/frame_info.rb +40 -25
  21. data/lib/debug/irb_integration.rb +37 -0
  22. data/lib/debug/local.rb +17 -11
  23. data/lib/debug/open.rb +0 -0
  24. data/lib/debug/open_nonstop.rb +0 -0
  25. data/lib/debug/prelude.rb +3 -2
  26. data/lib/debug/server.rb +126 -56
  27. data/lib/debug/server_cdp.rb +673 -248
  28. data/lib/debug/server_dap.rb +497 -261
  29. data/lib/debug/session.rb +899 -441
  30. data/lib/debug/source_repository.rb +122 -49
  31. data/lib/debug/start.rb +1 -1
  32. data/lib/debug/thread_client.rb +460 -155
  33. data/lib/debug/tracer.rb +10 -16
  34. data/lib/debug/version.rb +1 -1
  35. data/lib/debug.rb +7 -2
  36. data/misc/README.md.erb +106 -56
  37. metadata +14 -24
  38. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -24
  39. data/.github/ISSUE_TEMPLATE/custom.md +0 -10
  40. data/.github/ISSUE_TEMPLATE/feature_request.md +0 -14
  41. data/.github/pull_request_template.md +0 -9
  42. data/.github/workflows/ruby.yml +0 -34
  43. data/.gitignore +0 -12
  44. data/bin/console +0 -14
  45. data/bin/gentest +0 -30
  46. data/bin/setup +0 -8
  47. data/lib/debug/bp.vim +0 -68
data/lib/debug/config.rb CHANGED
@@ -7,46 +7,54 @@ module DEBUGGER__
7
7
  ERROR: 2,
8
8
  WARN: 3,
9
9
  INFO: 4,
10
+ DEBUG: 5
10
11
  }.freeze
11
12
 
12
13
  CONFIG_SET = {
13
14
  # UI setting
14
- log_level: ['RUBY_DEBUG_LOG_LEVEL', "UI: Log level same as Logger (default: WARN)", :loglevel],
15
- show_src_lines: ['RUBY_DEBUG_SHOW_SRC_LINES', "UI: Show n lines source code on breakpoint (default: 10 lines)", :int],
16
- show_frames: ['RUBY_DEBUG_SHOW_FRAMES', "UI: Show n frames on breakpoint (default: 2 frames)", :int],
17
- use_short_path: ['RUBY_DEBUG_USE_SHORT_PATH', "UI: Show shorten PATH (like $(Gem)/foo.rb)", :bool],
18
- no_color: ['RUBY_DEBUG_NO_COLOR', "UI: Do not use colorize (default: false)", :bool],
19
- no_sigint_hook: ['RUBY_DEBUG_NO_SIGINT_HOOK', "UI: Do not suspend on SIGINT (default: false)", :bool],
20
- no_reline: ['RUBY_DEBUG_NO_RELINE', "UI: Do not use Reline library (default: false)", :bool],
15
+ log_level: ['RUBY_DEBUG_LOG_LEVEL', "UI: Log level same as Logger", :loglevel, "WARN"],
16
+ show_src_lines: ['RUBY_DEBUG_SHOW_SRC_LINES', "UI: Show n lines source code on breakpoint", :int, "10"],
17
+ show_evaledsrc: ['RUBY_DEBUG_SHOW_EVALEDSRC', "UI: Show actually evaluated source", :bool, "false"],
18
+ show_frames: ['RUBY_DEBUG_SHOW_FRAMES', "UI: Show n frames on breakpoint", :int, "2"],
19
+ use_short_path: ['RUBY_DEBUG_USE_SHORT_PATH', "UI: Show shorten PATH (like $(Gem)/foo.rb)", :bool, "false"],
20
+ no_color: ['RUBY_DEBUG_NO_COLOR', "UI: Do not use colorize", :bool, "false"],
21
+ no_sigint_hook: ['RUBY_DEBUG_NO_SIGINT_HOOK', "UI: Do not suspend on SIGINT", :bool, "false"],
22
+ no_reline: ['RUBY_DEBUG_NO_RELINE', "UI: Do not use Reline library", :bool, "false"],
23
+ no_hint: ['RUBY_DEBUG_NO_HINT', "UI: Do not show the hint on the REPL", :bool, "false"],
24
+ no_lineno: ['RUBY_DEBUG_NO_LINENO', "UI: Do not show line numbers", :bool, "false"],
25
+ irb_console: ["RUBY_DEBUG_IRB_CONSOLE", "UI: Use IRB as the console", :bool, "false"],
21
26
 
22
27
  # control setting
23
- skip_path: ['RUBY_DEBUG_SKIP_PATH', "CONTROL: Skip showing/entering frames for given paths (default: [])", :path],
24
- skip_nosrc: ['RUBY_DEBUG_SKIP_NOSRC', "CONTROL: Skip on no source code lines (default: false)", :bool],
25
- keep_alloc_site:['RUBY_DEBUG_KEEP_ALLOC_SITE',"CONTROL: Keep allocation site and p, pp shows it (default: false)", :bool],
26
- postmortem: ['RUBY_DEBUG_POSTMORTEM', "CONTROL: Enable postmortem debug (default: false)", :bool],
27
- fork_mode: ['RUBY_DEBUG_FORK_MODE', "CONTROL: Control which process activates a debugger after fork (both/parent/child) (default: both)", :forkmode],
28
- sigdump_sig: ['RUBY_DEBUG_SIGDUMP_SIG', "CONTROL: Sigdump signal (default: disabled)"],
28
+ skip_path: ['RUBY_DEBUG_SKIP_PATH', "CONTROL: Skip showing/entering frames for given paths", :path],
29
+ skip_nosrc: ['RUBY_DEBUG_SKIP_NOSRC', "CONTROL: Skip on no source code lines", :bool, "false"],
30
+ keep_alloc_site:['RUBY_DEBUG_KEEP_ALLOC_SITE',"CONTROL: Keep allocation site and p, pp shows it", :bool, "false"],
31
+ postmortem: ['RUBY_DEBUG_POSTMORTEM', "CONTROL: Enable postmortem debug", :bool, "false"],
32
+ fork_mode: ['RUBY_DEBUG_FORK_MODE', "CONTROL: Control which process activates a debugger after fork (both/parent/child)", :forkmode, "both"],
33
+ sigdump_sig: ['RUBY_DEBUG_SIGDUMP_SIG', "CONTROL: Sigdump signal", :bool, "false"],
29
34
 
30
35
  # boot setting
31
- nonstop: ['RUBY_DEBUG_NONSTOP', "BOOT: Nonstop mode", :bool],
32
- stop_at_load: ['RUBY_DEBUG_STOP_AT_LOAD',"BOOT: Stop at just loading location", :bool],
36
+ nonstop: ['RUBY_DEBUG_NONSTOP', "BOOT: Nonstop mode", :bool, "false"],
37
+ stop_at_load: ['RUBY_DEBUG_STOP_AT_LOAD',"BOOT: Stop at just loading location", :bool, "false"],
33
38
  init_script: ['RUBY_DEBUG_INIT_SCRIPT', "BOOT: debug command script path loaded at first stop"],
34
- commands: ['RUBY_DEBUG_COMMANDS', "BOOT: debug commands invoked at first stop. commands should be separated by ';;'"],
35
- no_rc: ['RUBY_DEBUG_NO_RC', "BOOT: ignore loading ~/.rdbgrc(.rb)", :bool],
36
- history_file: ['RUBY_DEBUG_HISTORY_FILE',"BOOT: history file (default: ~/.rdbg_history)"],
37
- save_history: ['RUBY_DEBUG_SAVE_HISTORY',"BOOT: maximum save history lines (default: 10,000)"],
39
+ commands: ['RUBY_DEBUG_COMMANDS', "BOOT: debug commands invoked at first stop. Commands should be separated by `;;`"],
40
+ no_rc: ['RUBY_DEBUG_NO_RC', "BOOT: ignore loading ~/.rdbgrc(.rb)", :bool, "false"],
41
+ history_file: ['RUBY_DEBUG_HISTORY_FILE',"BOOT: history file", :string, "~/.rdbg_history"],
42
+ save_history: ['RUBY_DEBUG_SAVE_HISTORY',"BOOT: maximum save history lines", :int, "10000"],
38
43
 
39
44
  # remote setting
45
+ open: ['RUBY_DEBUG_OPEN', "REMOTE: Open remote port (same as `rdbg --open` option)"],
40
46
  port: ['RUBY_DEBUG_PORT', "REMOTE: TCP/IP remote debugging: port"],
41
- host: ['RUBY_DEBUG_HOST', "REMOTE: TCP/IP remote debugging: host (localhost if not given)"],
47
+ host: ['RUBY_DEBUG_HOST', "REMOTE: TCP/IP remote debugging: host", :string, "127.0.0.1"],
42
48
  sock_path: ['RUBY_DEBUG_SOCK_PATH', "REMOTE: UNIX Domain Socket remote debugging: socket path"],
43
49
  sock_dir: ['RUBY_DEBUG_SOCK_DIR', "REMOTE: UNIX Domain Socket remote debugging: socket directory"],
50
+ local_fs_map: ['RUBY_DEBUG_LOCAL_FS_MAP', "REMOTE: Specify local fs map", :path_map],
51
+ skip_bp: ['RUBY_DEBUG_SKIP_BP', "REMOTE: Skip breakpoints if no clients are attached", :bool, 'false'],
44
52
  cookie: ['RUBY_DEBUG_COOKIE', "REMOTE: Cookie for negotiation"],
45
- open_frontend: ['RUBY_DEBUG_OPEN_FRONTEND',"REMOTE: frontend used by open command (vscode, chrome, default: rdbg)."],
53
+ session_name: ['RUBY_DEBUG_SESSION_NAME', "REMOTE: Session name for differentiating multiple sessions"],
46
54
  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))"],
47
55
 
48
56
  # obsolete
49
- parent_on_fork: ['RUBY_DEBUG_PARENT_ON_FORK', "OBSOLETE: Keep debugging parent process on fork (default: false)", :bool],
57
+ parent_on_fork: ['RUBY_DEBUG_PARENT_ON_FORK', "OBSOLETE: Keep debugging parent process on fork", :bool, "false"],
50
58
  }.freeze
51
59
 
52
60
  CONFIG_MAP = CONFIG_SET.map{|k, (ev, _)| [k, ev]}.to_h.freeze
@@ -63,7 +71,17 @@ module DEBUGGER__
63
71
  raise 'Can not make multiple configurations in one process'
64
72
  end
65
73
 
66
- update self.class.parse_argv(argv)
74
+ config = self.class.parse_argv(argv)
75
+
76
+ # apply defaults
77
+ CONFIG_SET.each do |k, config_detail|
78
+ unless config.key?(k)
79
+ default_value = config_detail[3]
80
+ config[k] = parse_config_value(k, default_value)
81
+ end
82
+ end
83
+
84
+ update config
67
85
  end
68
86
 
69
87
  def inspect
@@ -114,11 +132,13 @@ module DEBUGGER__
114
132
  self.class.instance_variable_set(:@config, conf.freeze)
115
133
 
116
134
  # Post process
117
- if_updated old_conf, conf, :keep_alloc_site do |_, new|
135
+ if_updated old_conf, conf, :keep_alloc_site do |old, new|
118
136
  if new
119
137
  require 'objspace'
120
138
  ObjectSpace.trace_object_allocations_start
121
- else
139
+ end
140
+
141
+ if old && !new
122
142
  ObjectSpace.trace_object_allocations_stop
123
143
  end
124
144
  end
@@ -132,6 +152,28 @@ module DEBUGGER__
132
152
  if_updated old_conf, conf, :sigdump_sig do |old_sig, new_sig|
133
153
  setup_sigdump old_sig, new_sig
134
154
  end
155
+
156
+ if_updated old_conf, conf, :no_sigint_hook do |old, new|
157
+ if defined?(SESSION)
158
+ SESSION.set_no_sigint_hook old, new
159
+ end
160
+ end
161
+
162
+ if_updated old_conf, conf, :irb_console do |old, new|
163
+ if defined?(SESSION) && SESSION.active?
164
+ # irb_console is switched from true to false
165
+ if old
166
+ SESSION.deactivate_irb_integration
167
+ # irb_console is switched from false to true
168
+ else
169
+ if CONFIG[:open]
170
+ SESSION.instance_variable_get(:@ui).puts "\nIRB is not supported on the remote console."
171
+ else
172
+ SESSION.activate_irb_integration
173
+ end
174
+ end
175
+ end
176
+ end
135
177
  end
136
178
 
137
179
  private def if_updated old_conf, new_conf, key
@@ -215,6 +257,8 @@ module DEBUGGER__
215
257
  e
216
258
  end
217
259
  }
260
+ when :path_map
261
+ valstr.split(',').map{|e| e.split(':')}
218
262
  else
219
263
  valstr
220
264
  end
@@ -223,6 +267,7 @@ module DEBUGGER__
223
267
  def self.parse_argv argv
224
268
  config = {
225
269
  mode: :start,
270
+ no_color: (nc = ENV['NO_COLOR']) && !nc.empty?,
226
271
  }
227
272
  CONFIG_MAP.each{|key, evname|
228
273
  if val = ENV[evname]
@@ -239,6 +284,8 @@ module DEBUGGER__
239
284
  require 'optparse'
240
285
  require_relative 'version'
241
286
 
287
+ have_shown_version = false
288
+
242
289
  opt = OptionParser.new do |o|
243
290
  o.banner = "#{$0} [options] -- [debuggee options]"
244
291
  o.separator ''
@@ -279,8 +326,25 @@ module DEBUGGER__
279
326
  'If TCP/IP options are not given, a UNIX domain socket will be used.',
280
327
  'If FRONTEND is given, prepare for the FRONTEND.',
281
328
  'Now rdbg, vscode and chrome is supported.') do |f|
282
- config[:remote] = true
283
- config[:open_frontend] = f.downcase if f
329
+
330
+ case f # some format patterns are not documented yet
331
+ when nil
332
+ config[:open] = true
333
+ when /\A\d\z/
334
+ config[:open] = true
335
+ config[:port] = f.to_i
336
+ when /\A(\S+):(\d+)\z/
337
+ config[:open] = true
338
+ config[:host] = $1
339
+ config[:port] = $2.to_i
340
+ when 'tcp'
341
+ config[:open] = true
342
+ config[:port] ||= 0
343
+ when 'vscode', 'chrome', 'cdp'
344
+ config[:open] = f&.downcase
345
+ else
346
+ raise "Unknown option for --open: #{f}"
347
+ end
284
348
  end
285
349
  o.on('--sock-path=SOCK_PATH', 'UNIX Domain socket path') do |path|
286
350
  config[:sock_path] = path
@@ -294,6 +358,9 @@ module DEBUGGER__
294
358
  o.on('--cookie=COOKIE', 'Set a cookie for connection') do |c|
295
359
  config[:cookie] = c
296
360
  end
361
+ o.on('--session-name=NAME', 'Session name') do |name|
362
+ config[:session_name] = name
363
+ end
297
364
 
298
365
  rdbg = 'rdbg'
299
366
 
@@ -329,6 +396,16 @@ module DEBUGGER__
329
396
  o.separator ''
330
397
  o.separator 'Other options:'
331
398
 
399
+ o.on('-v', 'Show version number') do
400
+ puts o.ver
401
+ have_shown_version = true
402
+ end
403
+
404
+ o.on('--version', 'Show version number and exit') do
405
+ puts o.ver
406
+ exit
407
+ end
408
+
332
409
  o.on("-h", "--help", "Print help") do
333
410
  puts o
334
411
  exit
@@ -352,6 +429,13 @@ module DEBUGGER__
352
429
 
353
430
  opt.parse!(argv)
354
431
 
432
+ if argv.empty?
433
+ case
434
+ when have_shown_version && config[:mode] == :start
435
+ exit
436
+ end
437
+ end
438
+
355
439
  config
356
440
  end
357
441
 
@@ -361,6 +445,8 @@ module DEBUGGER__
361
445
  case CONFIG_SET[key][2]
362
446
  when :path
363
447
  valstr = config[key].map{|e| e.kind_of?(Regexp) ? e.inspect : e}.join(':')
448
+ when :path_map
449
+ valstr = config[key].map{|e| e.join(':')}.join(',')
364
450
  else
365
451
  valstr = config[key].to_s
366
452
  end
@@ -380,8 +466,9 @@ module DEBUGGER__
380
466
  unless (dir_uid = fs.uid) == (uid = Process.uid)
381
467
  raise "#{path} uid is #{dir_uid}, but Process.uid is #{uid}"
382
468
  end
383
- unless (dir_mode = fs.mode) == 040700 # 4: dir, 7:rwx
384
- raise "#{path}'s mode is #{dir_mode.to_s(8)} (should be 040700)"
469
+
470
+ if fs.world_writable? && !fs.sticky?
471
+ raise "#{path} is world writable but not sticky"
385
472
  end
386
473
 
387
474
  path
@@ -391,7 +478,7 @@ module DEBUGGER__
391
478
  require 'tmpdir'
392
479
 
393
480
  if tmpdir = Dir.tmpdir
394
- path = File.join(tmpdir, "ruby-debug-sock-#{Process.uid}")
481
+ path = File.join(tmpdir, "rdbg-#{Process.uid}")
395
482
 
396
483
  unless File.exist?(path)
397
484
  d = Dir.mktmpdir
@@ -404,7 +491,7 @@ module DEBUGGER__
404
491
 
405
492
  def self.unix_domain_socket_homedir
406
493
  if home = ENV['HOME']
407
- path = File.join(home, '.ruby-debug-sock')
494
+ path = File.join(home, '.rdbg-sock')
408
495
 
409
496
  unless File.exist?(path)
410
497
  Dir.mkdir(path, 0700)
@@ -428,12 +515,14 @@ module DEBUGGER__
428
515
  end
429
516
 
430
517
  def self.create_unix_domain_socket_name_prefix(base_dir = unix_domain_socket_dir)
431
- user = ENV['USER'] || 'ruby-debug'
432
- File.join(base_dir, "ruby-debug-#{user}")
518
+ File.join(base_dir, "rdbg")
433
519
  end
434
520
 
435
521
  def self.create_unix_domain_socket_name(base_dir = unix_domain_socket_dir)
436
- create_unix_domain_socket_name_prefix(base_dir) + "-#{Process.pid}"
522
+ suffix = "-#{Process.pid}"
523
+ name = CONFIG[:session_name]
524
+ suffix << "-#{name}" if name
525
+ create_unix_domain_socket_name_prefix(base_dir) + suffix
437
526
  end
438
527
 
439
528
  ## Help
@@ -448,10 +537,14 @@ module DEBUGGER__
448
537
  when /\A\s*### (.+)/
449
538
  cat = $1
450
539
  break if $1 == 'END'
451
- when /\A when (.+)/
540
+ when /\A register_command (.+)/
452
541
  next unless cat
453
542
  next unless desc
454
- ws = $1.split(/,\s*/).map{|e| e.gsub('\'', '')}
543
+
544
+ ws = []
545
+ $1.gsub(/'([a-z]+)'/){|w|
546
+ ws << $1
547
+ }
455
548
  helps[cat] << [ws, desc]
456
549
  desc = nil
457
550
  max_w = ws.max_by{|w| w.length}
data/lib/debug/console.rb CHANGED
@@ -5,30 +5,21 @@ module DEBUGGER__
5
5
  raise LoadError if CONFIG[:no_reline]
6
6
  require 'reline'
7
7
 
8
- # reline 0.2.7 or later is required.
9
- raise LoadError if Reline::VERSION < '0.2.7'
10
-
11
8
  require_relative 'color'
12
- include Color
13
9
 
14
- begin
15
- prev = trap(:SIGWINCH, nil)
16
- trap(:SIGWINCH, prev)
17
- SIGWINCH_SUPPORTED = true
18
- rescue ArgumentError
19
- SIGWINCH_SUPPORTED = false
20
- end
10
+ include Color
21
11
 
22
- # 0.2.7 has SIGWINCH issue on non-main thread
23
- class ::Reline::LineEditor
24
- m = Module.new do
25
- def reset(prompt = '', encoding:)
26
- super
27
- Signal.trap(:SIGWINCH, nil)
28
- end
12
+ def parse_input buff, commands
13
+ c, rest = get_command buff
14
+ case
15
+ when commands.keys.include?(c)
16
+ :command
17
+ when !rest && /\A\s*[a-z]*\z/ =~ c
18
+ nil
19
+ else
20
+ :ruby
29
21
  end
30
- prepend m
31
- end if SIGWINCH_SUPPORTED
22
+ end
32
23
 
33
24
  def readline_setup prompt
34
25
  load_history_if_not_loaded
@@ -38,7 +29,17 @@ module DEBUGGER__
38
29
  prev_output_modifier_proc = Reline.output_modifier_proc
39
30
  prev_prompt_proc = Reline.prompt_proc
40
31
 
41
- Reline.prompt_proc = nil
32
+ # prompt state
33
+ state = nil # :command, :ruby, nil (unknown)
34
+
35
+ Reline.prompt_proc = -> args, *kw do
36
+ case state = parse_input(args.first, commands)
37
+ when nil, :command
38
+ [prompt]
39
+ when :ruby
40
+ [prompt.sub('rdbg'){colorize('ruby', [:RED])}]
41
+ end * args.size
42
+ end
42
43
 
43
44
  Reline.completion_proc = -> given do
44
45
  buff = Reline.line_buffer
@@ -52,17 +53,16 @@ module DEBUGGER__
52
53
  end
53
54
  files
54
55
  else
55
- commands.keys.grep(/\A#{given}/)
56
+ commands.keys.grep(/\A#{Regexp.escape(given)}/)
56
57
  end
57
58
  end
58
59
 
59
60
  Reline.output_modifier_proc = -> buff, **kw do
60
61
  c, rest = get_command buff
61
62
 
62
- case
63
- when commands.keys.include?(c = c.strip)
64
- # [:DIM, :CYAN, :BLUE, :CLEAR, :UNDERLINE, :REVERSE, :RED, :GREEN, :MAGENTA, :BOLD, :YELLOW]
65
- cmd = colorize(c.strip, [:CYAN, :UNDERLINE])
63
+ case state
64
+ when :command
65
+ cmd = colorize(c, [:CYAN, :UNDERLINE])
66
66
 
67
67
  if commands[c] == c
68
68
  rprompt = colorize(" # command", [:DIM])
@@ -70,14 +70,14 @@ module DEBUGGER__
70
70
  rprompt = colorize(" # #{commands[c]} command", [:DIM])
71
71
  end
72
72
 
73
- rest = (rest ? colorize_code(rest) : '') + rprompt
74
- cmd + rest
75
- when !rest && /\A\s*[a-z]*\z/ =~ c
73
+ rest = rest ? colorize_code(rest) : ''
74
+ cmd + rest + rprompt
75
+ when nil
76
76
  buff
77
- else
78
- colorize_code(buff.chomp) + colorize(" # ruby", [:DIM])
77
+ when :ruby
78
+ colorize_code(buff)
79
79
  end
80
- end
80
+ end unless CONFIG[:no_hint]
81
81
 
82
82
  yield
83
83
 
@@ -90,9 +90,9 @@ module DEBUGGER__
90
90
  private def get_command line
91
91
  case line.chomp
92
92
  when /\A(\s*[a-z]+)(\s.*)?\z$/
93
- return $1, $2
93
+ return $1.strip, $2
94
94
  else
95
- line.chomp
95
+ line.strip
96
96
  end
97
97
  end
98
98
 
@@ -143,7 +143,7 @@ module DEBUGGER__
143
143
  rescue LoadError
144
144
  def readline prompt
145
145
  print prompt
146
- gets
146
+ $stdin.gets
147
147
  end
148
148
 
149
149
  def history
@@ -153,7 +153,13 @@ module DEBUGGER__
153
153
  end
154
154
 
155
155
  def history_file
156
- CONFIG[:history_file] || File.expand_path("~/.rdbg_history")
156
+ history_file = CONFIG[:history_file]
157
+
158
+ if !history_file.empty?
159
+ File.expand_path(history_file)
160
+ else
161
+ history_file
162
+ end
157
163
  end
158
164
 
159
165
  FH = "# Today's OMIKUJI: "
@@ -181,7 +187,7 @@ module DEBUGGER__
181
187
  if history && @init_history_lines
182
188
  added_records = history.to_a[@init_history_lines .. -1]
183
189
  path = history_file
184
- max = CONFIG[:save_history] || 10_000
190
+ max = CONFIG[:save_history]
185
191
 
186
192
  if !added_records.empty? && !path.empty?
187
193
  orig_records = read_history_file
@@ -197,11 +203,11 @@ module DEBUGGER__
197
203
  end
198
204
 
199
205
  def load_history
200
- read_history_file.count{|line|
206
+ read_history_file.each{|line|
201
207
  line.strip!
202
208
  history << line unless line.empty?
203
- }
209
+ } if history.empty?
210
+ history.count
204
211
  end
205
212
  end # class Console
206
213
  end
207
-