byebug 3.5.1 → 4.0.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.
Files changed (137) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -1
  3. data/.rubocop.yml +18 -1
  4. data/.travis.yml +21 -1
  5. data/CHANGELOG.md +356 -308
  6. data/CONTRIBUTING.md +31 -15
  7. data/GUIDE.md +859 -475
  8. data/Gemfile +8 -10
  9. data/LICENSE +1 -1
  10. data/README.md +41 -45
  11. data/Rakefile +30 -28
  12. data/byebug.gemspec +18 -18
  13. data/ext/byebug/breakpoint.c +88 -75
  14. data/ext/byebug/byebug.c +253 -252
  15. data/ext/byebug/byebug.h +53 -53
  16. data/ext/byebug/context.c +188 -159
  17. data/ext/byebug/extconf.rb +9 -6
  18. data/ext/byebug/locker.c +53 -11
  19. data/ext/byebug/threads.c +137 -39
  20. data/lib/byebug/attacher.rb +7 -2
  21. data/lib/byebug/breakpoint.rb +30 -0
  22. data/lib/byebug/command.rb +36 -32
  23. data/lib/byebug/commands/break.rb +49 -48
  24. data/lib/byebug/commands/catch.rb +64 -0
  25. data/lib/byebug/commands/condition.rb +13 -9
  26. data/lib/byebug/commands/continue.rb +8 -4
  27. data/lib/byebug/commands/delete.rb +10 -4
  28. data/lib/byebug/commands/display.rb +33 -25
  29. data/lib/byebug/commands/edit.rb +18 -13
  30. data/lib/byebug/commands/enable_disable.rb +26 -24
  31. data/lib/byebug/commands/eval.rb +77 -35
  32. data/lib/byebug/commands/finish.rb +9 -5
  33. data/lib/byebug/commands/frame.rb +66 -125
  34. data/lib/byebug/commands/help.rb +14 -21
  35. data/lib/byebug/commands/history.rb +5 -1
  36. data/lib/byebug/commands/info.rb +41 -106
  37. data/lib/byebug/commands/interrupt.rb +6 -2
  38. data/lib/byebug/commands/irb.rb +5 -2
  39. data/lib/byebug/commands/kill.rb +6 -2
  40. data/lib/byebug/commands/list.rb +21 -14
  41. data/lib/byebug/commands/method.rb +17 -9
  42. data/lib/byebug/commands/pry.rb +13 -3
  43. data/lib/byebug/commands/quit.rb +10 -5
  44. data/lib/byebug/commands/restart.rb +12 -19
  45. data/lib/byebug/commands/save.rb +10 -6
  46. data/lib/byebug/commands/set.rb +15 -14
  47. data/lib/byebug/commands/show.rb +8 -8
  48. data/lib/byebug/commands/source.rb +14 -8
  49. data/lib/byebug/commands/stepping.rb +15 -29
  50. data/lib/byebug/commands/threads.rb +73 -49
  51. data/lib/byebug/commands/tracevar.rb +56 -0
  52. data/lib/byebug/commands/undisplay.rb +8 -4
  53. data/lib/byebug/commands/untracevar.rb +38 -0
  54. data/lib/byebug/commands/var.rb +107 -0
  55. data/lib/byebug/context.rb +78 -42
  56. data/lib/byebug/core.rb +78 -40
  57. data/lib/byebug/helper.rb +58 -42
  58. data/lib/byebug/history.rb +12 -1
  59. data/lib/byebug/interface.rb +91 -11
  60. data/lib/byebug/interfaces/local_interface.rb +12 -19
  61. data/lib/byebug/interfaces/remote_interface.rb +12 -15
  62. data/lib/byebug/interfaces/script_interface.rb +14 -18
  63. data/lib/byebug/interfaces/test_interface.rb +54 -0
  64. data/lib/byebug/printers/base.rb +64 -0
  65. data/lib/byebug/printers/plain.rb +53 -0
  66. data/lib/byebug/processor.rb +20 -1
  67. data/lib/byebug/processors/command_processor.rb +57 -172
  68. data/lib/byebug/processors/control_command_processor.rb +16 -43
  69. data/lib/byebug/remote.rb +13 -7
  70. data/lib/byebug/runner.rb +102 -54
  71. data/lib/byebug/setting.rb +45 -68
  72. data/lib/byebug/settings/autoeval.rb +2 -0
  73. data/lib/byebug/settings/autoirb.rb +3 -0
  74. data/lib/byebug/settings/autolist.rb +3 -0
  75. data/lib/byebug/settings/autosave.rb +2 -0
  76. data/lib/byebug/settings/basename.rb +2 -0
  77. data/lib/byebug/settings/callstyle.rb +2 -0
  78. data/lib/byebug/settings/fullpath.rb +2 -0
  79. data/lib/byebug/settings/histfile.rb +2 -0
  80. data/lib/byebug/settings/histsize.rb +2 -0
  81. data/lib/byebug/settings/linetrace.rb +2 -0
  82. data/lib/byebug/settings/listsize.rb +2 -0
  83. data/lib/byebug/settings/post_mortem.rb +7 -2
  84. data/lib/byebug/settings/stack_on_error.rb +2 -0
  85. data/lib/byebug/settings/verbose.rb +2 -0
  86. data/lib/byebug/settings/width.rb +2 -0
  87. data/lib/byebug/state.rb +12 -0
  88. data/lib/byebug/states/control_state.rb +26 -0
  89. data/lib/byebug/states/regular_state.rb +178 -0
  90. data/lib/byebug/version.rb +1 -1
  91. metadata +24 -109
  92. data/lib/byebug/commands/catchpoint.rb +0 -53
  93. data/lib/byebug/commands/reload.rb +0 -29
  94. data/lib/byebug/commands/trace.rb +0 -50
  95. data/lib/byebug/commands/variables.rb +0 -206
  96. data/lib/byebug/options.rb +0 -46
  97. data/lib/byebug/settings/autoreload.rb +0 -12
  98. data/lib/byebug/settings/forcestep.rb +0 -14
  99. data/lib/byebug/settings/testing.rb +0 -12
  100. data/lib/byebug/settings/tracing_plus.rb +0 -11
  101. data/test/commands/break_test.rb +0 -364
  102. data/test/commands/condition_test.rb +0 -85
  103. data/test/commands/continue_test.rb +0 -47
  104. data/test/commands/delete_test.rb +0 -26
  105. data/test/commands/display_test.rb +0 -37
  106. data/test/commands/edit_test.rb +0 -52
  107. data/test/commands/eval_test.rb +0 -89
  108. data/test/commands/finish_test.rb +0 -74
  109. data/test/commands/frame_test.rb +0 -223
  110. data/test/commands/help_test.rb +0 -66
  111. data/test/commands/history_test.rb +0 -61
  112. data/test/commands/info_test.rb +0 -238
  113. data/test/commands/interrupt_test.rb +0 -45
  114. data/test/commands/irb_test.rb +0 -28
  115. data/test/commands/kill_test.rb +0 -50
  116. data/test/commands/list_test.rb +0 -174
  117. data/test/commands/method_test.rb +0 -52
  118. data/test/commands/post_mortem_test.rb +0 -71
  119. data/test/commands/pry_test.rb +0 -26
  120. data/test/commands/quit_test.rb +0 -53
  121. data/test/commands/reload_test.rb +0 -39
  122. data/test/commands/restart_test.rb +0 -46
  123. data/test/commands/save_test.rb +0 -67
  124. data/test/commands/set_test.rb +0 -140
  125. data/test/commands/show_test.rb +0 -76
  126. data/test/commands/source_test.rb +0 -46
  127. data/test/commands/stepping_test.rb +0 -192
  128. data/test/commands/thread_test.rb +0 -164
  129. data/test/commands/trace_test.rb +0 -71
  130. data/test/commands/undisplay_test.rb +0 -75
  131. data/test/commands/variables_test.rb +0 -105
  132. data/test/debugger_alias_test.rb +0 -7
  133. data/test/runner_test.rb +0 -150
  134. data/test/support/matchers.rb +0 -65
  135. data/test/support/test_interface.rb +0 -59
  136. data/test/support/utils.rb +0 -122
  137. data/test/test_helper.rb +0 -58
@@ -1,3 +1,5 @@
1
+ require 'byebug/command'
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Show methods of specific classes/modules/objects.
@@ -11,13 +13,17 @@ module Byebug
11
13
 
12
14
  def execute
13
15
  obj = bb_eval(@match.post_match)
14
- if @match[1]
15
- puts "#{columnize(obj.methods.sort, Setting[:width])}"
16
- elsif !obj.is_a?(Module)
17
- puts "Should be Class/Module: #{@match.post_match}"
18
- else
19
- puts "#{columnize(obj.instance_methods(false).sort, Setting[:width])}"
20
- end
16
+ result =
17
+ if @match[1]
18
+ prc('method.methods', obj.methods.sort) { |item, _| { name: item } }
19
+ elsif !obj.is_a?(Module)
20
+ pr('variable.errors.not_module', object: @match.post_match)
21
+ else
22
+ prc('method.methods', obj.instance_methods(false).sort) do |item, _|
23
+ { name: item }
24
+ end
25
+ end
26
+ puts result
21
27
  end
22
28
 
23
29
  class << self
@@ -26,13 +32,15 @@ module Byebug
26
32
  end
27
33
 
28
34
  def description
29
- %{m[ethod] (i[nstance][ <obj>]|<class|module>)
35
+ prettify <<-EOD
36
+ m[ethod] (i[nstance][ <obj>]|<class|module>)
30
37
 
31
38
  When invoked with "instance", shows instance methods of the object
32
39
  specified as argument or of self no object was specified.
33
40
 
34
41
  When invoked only with a class or module, shows class methods of the
35
- class or module specified as argument.}
42
+ class or module specified as argument.
43
+ EOD
36
44
  end
37
45
  end
38
46
  end
@@ -1,3 +1,5 @@
1
+ require 'byebug/command'
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Enter Pry from byebug's prompt
@@ -9,7 +11,13 @@ module Byebug
9
11
 
10
12
  def execute
11
13
  unless @state.interface.is_a?(LocalInterface)
12
- return errmsg('Command is available only in local mode.')
14
+ return errmsg(pr('base.errors.only_local'))
15
+ end
16
+
17
+ begin
18
+ require 'pry'
19
+ rescue LoadError
20
+ errmsg(pr('pry.errors.not_installed'))
13
21
  end
14
22
 
15
23
  get_binding.pry
@@ -21,8 +29,10 @@ module Byebug
21
29
  end
22
30
 
23
31
  def description
24
- %(pry Starts a Pry session.)
32
+ prettify <<-EOD
33
+ pry Starts a Pry session.
34
+ EOD
25
35
  end
26
36
  end
27
37
  end
28
- end if defined?(Pry)
38
+ end
@@ -1,3 +1,5 @@
1
+ require 'byebug/command'
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Exit from byebug.
@@ -6,27 +8,30 @@ module Byebug
6
8
  self.allow_in_control = true
7
9
 
8
10
  def regexp
9
- /^\s* (?:q(?:uit)?|exit) \s* (!|\s+unconditionally)? \s*$/x
11
+ /^\s* q(?:uit)? \s* (?:(!|\s+unconditionally))? \s*$/x
10
12
  end
11
13
 
12
14
  def execute
13
- return unless @match[1] || confirm('Really quit? (y/n) ')
15
+ return unless @match[1] || confirm(pr('quit.confirmations.really'))
14
16
 
17
+ @state.interface.autosave
15
18
  @state.interface.close
16
19
  exit! # exit -> exit!: No graceful way to stop...
17
20
  end
18
21
 
19
22
  class << self
20
23
  def names
21
- %w(quit exit)
24
+ %w(quit)
22
25
  end
23
26
 
24
27
  def description
25
- %(q[uit]|exit [!|unconditionally] Exits from byebug.
28
+ prettify <<-EOD
29
+ q[uit] [!|unconditionally] Exits from byebug.
26
30
 
27
31
  Normally we prompt before exiting. However if the parameter
28
32
  "unconditionally" is given or command is suffixed with !, we exit
29
- without asking further questions.)
33
+ without asking further questions.
34
+ EOD
30
35
  end
31
36
  end
32
37
  end
@@ -1,3 +1,5 @@
1
+ require 'byebug/command'
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Restart debugged program from within byebug.
@@ -10,32 +12,21 @@ module Byebug
10
12
  end
11
13
 
12
14
  def execute
13
- prog = Byebug.debugged_program
14
-
15
- if defined?(BYEBUG_SCRIPT)
16
- cmd = "#{BYEBUG_SCRIPT} #{prog}"
15
+ if Byebug.mode == :standalone
16
+ cmd = "#{Gem.bin_path('byebug', 'byebug')} #{$PROGRAM_NAME}"
17
17
  else
18
- puts 'Byebug was not called from the outset...'
19
- if File.executable?(prog)
20
- cmd = prog
21
- else
22
- puts "Program #{prog} not executable... Wrapping it in a ruby call"
23
- cmd = "ruby -rbyebug -I#{$LOAD_PATH.join(' -I')} #{prog}"
24
- end
18
+ cmd = $PROGRAM_NAME
25
19
  end
26
20
 
27
21
  if @match[:args]
28
22
  cmd += " #{@match[:args]}"
29
23
  else
30
24
  require 'shellwords'
31
- cmd += " #{ARGV.compact.shelljoin}"
25
+ cmd += " #{$ARGV.compact.shelljoin}"
32
26
  end
33
27
 
34
- # An execv would be preferable to the "exec" below.
35
- puts "Re exec'ing:\n\t#{cmd}"
36
- exec cmd
37
- rescue Errno::EOPNOTSUPP
38
- puts 'Restart command is not available at this time.'
28
+ puts pr('restart.success', cmd: cmd)
29
+ exec(cmd)
39
30
  end
40
31
 
41
32
  class << self
@@ -44,10 +35,12 @@ module Byebug
44
35
  end
45
36
 
46
37
  def description
47
- %(restart|R [args]
38
+ prettify <<-EOD
39
+ restart|R [args]
48
40
 
49
41
  Restart the program. This is a re-exec - all byebug state
50
- is lost. If command arguments are passed those are used.)
42
+ is lost. If command arguments are passed those are used.
43
+ EOD
51
44
  end
52
45
  end
53
46
  end
@@ -1,8 +1,10 @@
1
+ require 'byebug/command'
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Default file where commands are saved
4
6
  #
5
- RESTART_FILE = '.byebug-save' unless defined?(RESTART_FILE)
7
+ RESTART_FILE = '.byebug-save'
6
8
 
7
9
  #
8
10
  # Save current settings to use them in another debug session.
@@ -27,7 +29,7 @@ module Byebug
27
29
  end
28
30
 
29
31
  def save_settings(file)
30
- %w(autoeval autoirb autolist basename testing).each do |setting|
32
+ %w(autoeval autoirb autolist basename).each do |setting|
31
33
  file.puts "set #{setting} #{Setting[setting.to_sym]}"
32
34
  end
33
35
  end
@@ -37,14 +39,14 @@ module Byebug
37
39
  end
38
40
 
39
41
  def execute
40
- file = open(@match[1] || RESTART_FILE, 'w')
42
+ file = File.open(@match[1] || RESTART_FILE, 'w')
41
43
 
42
44
  save_breakpoints(file)
43
45
  save_catchpoints(file)
44
46
  save_displays(file)
45
47
  save_settings(file)
46
48
 
47
- puts "Saved to '#{file.path}'"
49
+ print pr('save.messages.done', path: file.path)
48
50
  file.close
49
51
  end
50
52
 
@@ -54,13 +56,15 @@ module Byebug
54
56
  end
55
57
 
56
58
  def description
57
- %(save[ FILE]
59
+ prettify <<-EOD
60
+ save[ FILE]
58
61
 
59
62
  Saves current byebug state to FILE as a script file. This includes
60
63
  breakpoints, catchpoints, display expressions and some settings. If
61
64
  no filename is given, we will fabricate one.
62
65
 
63
- Use the "source" command in another debug session to restore them.)
66
+ Use the "source" command in another debug session to restore them.
67
+ EOD
64
68
  end
65
69
  end
66
70
  end
@@ -1,3 +1,5 @@
1
+ require 'byebug/command'
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Change byebug settings.
@@ -13,21 +15,21 @@ module Byebug
13
15
  key, value = @match[:setting], @match[:value]
14
16
  return puts(SetCommand.help) if key.nil? && value.nil?
15
17
 
16
- full_key = Setting.find(key)
17
- return errmsg("Unknown setting :#{key}") unless full_key
18
+ setting = Setting.find(key)
19
+ return errmsg(pr('set.errors.unknown_setting', key: key)) unless setting
18
20
 
19
- if !Setting.boolean?(full_key) && value.nil?
20
- value, err = nil, "You must specify a value for setting :#{key}"
21
- elsif Setting.boolean?(full_key)
21
+ if !setting.boolean? && value.nil?
22
+ value, err = nil, pr('set.errors.must_specify_value', key: key)
23
+ elsif setting.boolean?
22
24
  value, err = get_onoff(value, key =~ /^no/ ? false : true)
23
- elsif Setting.integer?(full_key)
24
- value, err = get_int(value, full_key, 1)
25
+ elsif setting.integer?
26
+ value, err = get_int(value, setting.to_sym, 1)
25
27
  end
26
28
  return errmsg(err) if value.nil?
27
29
 
28
- Setting[full_key.to_sym] = value
30
+ setting.value = value
29
31
 
30
- puts Setting.settings[full_key.to_sym].to_s
32
+ puts setting.to_s
31
33
  end
32
34
 
33
35
  def get_onoff(arg, default)
@@ -39,7 +41,7 @@ module Byebug
39
41
  when '0', 'off', 'false'
40
42
  false
41
43
  else
42
- [nil, "Expecting 'on', 1, true, 'off', 0, false. Got: #{arg}.\n"]
44
+ [nil, pr('set.errors.on_off', arg: arg)]
43
45
  end
44
46
  end
45
47
 
@@ -49,8 +51,7 @@ module Byebug
49
51
  end
50
52
 
51
53
  def description
52
- <<-EOD.gsub(/^ /, '')
53
-
54
+ prettify <<-EOD
54
55
  set <setting> <value>
55
56
 
56
57
  Modifies parts of byebug environment.
@@ -63,8 +64,8 @@ module Byebug
63
64
  EOD
64
65
  end
65
66
 
66
- def help(subcmds = [])
67
- Setting.help('set', subcmds.first)
67
+ def help(subcmd = nil)
68
+ Setting.help('set', subcmd)
68
69
  end
69
70
  end
70
71
  end
@@ -1,3 +1,5 @@
1
+ require 'byebug/command'
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Show byebug settings.
@@ -13,10 +15,10 @@ module Byebug
13
15
  key = @match[:setting]
14
16
  return puts(self.class.help) if key.nil?
15
17
 
16
- full_key = Setting.find(key)
17
- return errmsg("Unknown setting :#{key}") unless full_key
18
+ setting = Setting.find(key)
19
+ return errmsg(pr('show.errors.unknown_setting', key: key)) unless setting
18
20
 
19
- puts Setting.settings[full_key.to_sym].to_s
21
+ puts Setting.settings[setting.to_sym]
20
22
  end
21
23
 
22
24
  class << self
@@ -25,18 +27,16 @@ module Byebug
25
27
  end
26
28
 
27
29
  def description
28
- <<-EOD.gsub(/^ {8}/, '')
29
-
30
+ prettify <<-EOD
30
31
  show <setting> <value>
31
32
 
32
33
  Generic command for showing byebug settings. You can change them with
33
34
  the "set" command.
34
-
35
35
  EOD
36
36
  end
37
37
 
38
- def help(subcmds = [])
39
- Setting.help('show', subcmds.first)
38
+ def help(subcmd = nil)
39
+ Setting.help('show', subcmd)
40
40
  end
41
41
  end
42
42
  end
@@ -1,3 +1,5 @@
1
+ require 'byebug/command'
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Execute a file containing byebug commands.
@@ -14,14 +16,16 @@ module Byebug
14
16
  def execute
15
17
  return puts(self.class.help) if self.class.names.include?(@match[0])
16
18
 
17
- file = File.expand_path(@match[1]).strip
18
- return errmsg("File \"#{file}\" not found") unless File.exist?(file)
19
+ unless @state && @state.interface
20
+ return errmsg(pr('source.errors.not_available'))
21
+ end
19
22
 
20
- if @state && @state.interface
21
- @state.interface.command_queue += File.open(file).readlines
22
- else
23
- Byebug.run_script(file, @state)
23
+ file = File.expand_path(@match[1]).strip
24
+ unless File.exist?(file)
25
+ return errmsg(pr('source.errors.not_found', file: file))
24
26
  end
27
+
28
+ @state.interface.read_file(file)
25
29
  end
26
30
 
27
31
  class << self
@@ -30,9 +34,11 @@ module Byebug
30
34
  end
31
35
 
32
36
  def description
33
- %(source <file>
37
+ prettify <<-EOD
38
+ source <file>
34
39
 
35
- Executes file <file> containing byebug commands.)
40
+ Executes file <file> containing byebug commands.
41
+ EOD
36
42
  end
37
43
  end
38
44
  end
@@ -1,20 +1,6 @@
1
- module Byebug
2
- #
3
- # Mixin to assist command parsing
4
- #
5
- module SteppingFunctions
6
- def parse_force(str)
7
- return Setting[:forcestep] unless str
8
-
9
- case str
10
- when '+' then
11
- true
12
- when '-' then
13
- false
14
- end
15
- end
16
- end
1
+ require 'byebug/command'
17
2
 
3
+ module Byebug
18
4
  #
19
5
  # Implements the next functionality.
20
6
  #
@@ -25,14 +11,14 @@ module Byebug
25
11
  self.allow_in_post_mortem = false
26
12
 
27
13
  def regexp
28
- /^\s* n(?:ext)?([+-])? (?:\s+(\S+))? \s*$/x
14
+ /^\s* n(?:ext)? (?:\s+(\S+))? \s*$/x
29
15
  end
30
16
 
31
17
  def execute
32
- steps, err = parse_steps(@match[2], 'Next')
18
+ steps, err = parse_steps(@match[1], 'Next')
33
19
  return errmsg(err) unless steps
34
20
 
35
- @state.context.step_over(steps, @state.frame_pos, parse_force(@match[1]))
21
+ @state.context.step_over(steps, @state.frame)
36
22
  @state.proceed
37
23
  end
38
24
 
@@ -42,11 +28,11 @@ module Byebug
42
28
  end
43
29
 
44
30
  def description
45
- %(n[ext][+-]?[ nnn]
31
+ prettify <<-EOD
32
+ n[ext][ nnn]
46
33
 
47
- Steps over once or nnn times.
48
- '+' forces to move to another line.
49
- '-' is the opposite of '+' and disables the :forcestep setting.)
34
+ Steps over once or nnn times.
35
+ EOD
50
36
  end
51
37
  end
52
38
  end
@@ -61,14 +47,14 @@ module Byebug
61
47
  self.allow_in_post_mortem = false
62
48
 
63
49
  def regexp
64
- /^\s* s(?:tep)?([+-]) ?(?:\s+(\S+))? \s*$/x
50
+ /^\s* s(?:tep)? (?:\s+(\S+))? \s*$/x
65
51
  end
66
52
 
67
53
  def execute
68
- steps, err = parse_steps(@match[2], 'Steps')
54
+ steps, err = parse_steps(@match[1], 'Steps')
69
55
  return errmsg(err) unless steps
70
56
 
71
- @state.context.step_into(steps, parse_force(@match[1]))
57
+ @state.context.step_into(steps, @state.frame)
72
58
  @state.proceed
73
59
  end
74
60
 
@@ -78,11 +64,11 @@ module Byebug
78
64
  end
79
65
 
80
66
  def description
81
- %{s[tep][+-]?[ nnn]
67
+ prettify <<-EOD
68
+ s[tep][ nnn]
82
69
 
83
70
  Steps (into methods) once or nnn times.
84
- '+' forces to move to another line.
85
- '-' is the opposite of '+' and disables the :forcestep setting.}
71
+ EOD
86
72
  end
87
73
  end
88
74
  end