byebug 3.5.1 → 4.0.0

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