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,95 +1,143 @@
1
- require 'slop'
2
- require 'ostruct'
1
+ require 'optparse'
3
2
  require 'English'
4
3
  require 'byebug/core'
5
- require 'byebug/options'
6
4
 
7
5
  module Byebug
8
6
  #
9
7
  # Responsible for starting the debugger when started from the command line.
10
8
  #
11
9
  class Runner
12
- BYEBUG_SCRIPT = File.expand_path('../../../../bin/byebug')
13
- IGNORED_FILES << BYEBUG_SCRIPT
14
-
15
10
  #
16
- # Debug a script only if syntax checks okay.
11
+ # Special working modes that don't actually start the debugger.
17
12
  #
18
- def debug_program(options)
19
- unless File.executable?(Byebug.debugged_program)
20
- output = `ruby -c "#{Byebug.debugged_program}" 2>&1`
21
- if $CHILD_STATUS.exitstatus != 0
22
- Byebug.puts output
23
- exit $CHILD_STATUS.exitstatus
24
- end
25
- end
13
+ attr_accessor :help, :version, :remote
26
14
 
27
- status = Byebug.debug_load(Byebug.debugged_program, options[:stop])
28
- Byebug.puts "#{status}\n#{status.backtrace}" if status
15
+ #
16
+ # @param stop [Boolean] Whether the runner should stop right before
17
+ # starting the program.
18
+ #
19
+ # @param quit [Boolean] Whether the runner should quit right after
20
+ # finishing the program.
21
+ #
22
+ def initialize(stop = true, quit = true)
23
+ @stop, @quit = stop, quit
29
24
  end
30
25
 
31
- include MiscUtils
32
26
  #
33
- # Extracts path to program to be debugged from ARGV
27
+ # Usage banner.
34
28
  #
35
- # Used for restarts.
36
- #
37
- def debugged_program_from_argv
38
- abort_with_err('You must specify a program to debug...') if ARGV.empty?
29
+ def banner
30
+ <<-EOB.gsub(/^ {8}/, '')
39
31
 
40
- prog_script_try = which(ARGV.first)
41
- if prog_script_try == which('ruby')
42
- ARGV.shift
43
- return which(ARGV.first)
44
- end
32
+ byebug #{Byebug::VERSION}
33
+
34
+ Usage: byebug [options] <script.rb> -- <script.rb parameters>
35
+
36
+ EOB
37
+ end
38
+
39
+ #
40
+ # Debugs a script only if syntax checks okay.
41
+ #
42
+ def debug_program
43
+ check_syntax($PROGRAM_NAME)
45
44
 
46
- prog_script_try
45
+ status = Byebug.debug_load($PROGRAM_NAME, @stop)
46
+ Byebug.puts "#{status}\n#{status.backtrace}" if status
47
47
  end
48
48
 
49
- def abort_with_err(msg)
50
- Byebug.errmsg(msg)
51
- abort
49
+ #
50
+ # Exits and outputs error message if syntax of the given program is invalid.
51
+ #
52
+ def check_syntax(program_name)
53
+ output = `ruby -c "#{program_name}" 2>&1`
54
+ return unless $CHILD_STATUS.exitstatus != 0
55
+
56
+ Byebug.errmsg(output)
57
+ exit($CHILD_STATUS.exitstatus)
52
58
  end
53
59
 
54
60
  #
55
61
  # Starts byebug to debug a program
56
62
  #
57
63
  def run
58
- opts = Byebug::Options.parse
59
-
60
- return Byebug.puts("\n Running byebug #{VERSION}\n") if opts[:version]
61
- return Byebug.puts("#{opts.help}\n") if opts[:help]
64
+ prepare_options.order!($ARGV)
62
65
 
63
- if opts[:remote]
64
- port, host = opts[:remote].pop.to_i, opts[:remote].pop || 'localhost'
65
- Byebug.puts "Connecting to byebug server #{host}:#{port}..."
66
- Byebug.start_client(host, port)
66
+ if version
67
+ Byebug.puts("\n Running byebug #{version}\n")
67
68
  return
68
69
  end
69
70
 
70
- Byebug.debugged_program = debugged_program_from_argv
71
- abort_with_err("The script doesn't exist") unless Byebug.debugged_program
72
-
73
- # Set up trace hook for byebug
74
- Byebug.start
75
-
76
- # load initrc script (e.g. .byebugrc)
77
- Byebug.run_init_script(StringIO.new) if opts[:rc]
71
+ if help
72
+ Byebug.puts("#{help}\n")
73
+ return
74
+ end
78
75
 
79
- # Post Mortem mode status
80
- Byebug::Setting[:post_mortem] = opts[:'post-mortem']
76
+ if remote
77
+ Byebug.start_client(*remote)
78
+ return
79
+ end
81
80
 
82
- # Line Tracing Status
83
- Byebug::Setting[:linetrace] = opts[:trace]
81
+ Byebug.setup_cmd_line_args
84
82
 
85
83
  loop do
86
- debug_program(opts)
84
+ debug_program
87
85
 
88
- break if opts[:quit]
86
+ break if @quit
89
87
 
90
88
  processor = Byebug::ControlCommandProcessor.new
91
89
  processor.process_commands
92
90
  end
93
91
  end
92
+
93
+ def prepare_options
94
+ OptionParser.new(banner, 25) do |opts|
95
+ opts.banner = banner
96
+
97
+ opts.on '-d', '--debug', 'Set $DEBUG=true' do
98
+ $DEBUG = true
99
+ end
100
+
101
+ opts.on('-I', '--include list', 'Add to paths to $LOAD_PATH') do |list|
102
+ $LOAD_PATH.push(list.split(':')).flatten!
103
+ end
104
+
105
+ opts.on '-m', '--[no-]post-mortem', 'Use post-mortem mode' do |v|
106
+ Setting[:post_mortem] = v
107
+ end
108
+
109
+ opts.on '-q', '--[no-]quit', 'Quit when script finishes' do |v|
110
+ @quit = v
111
+ end
112
+
113
+ opts.on '-x', '--[no-]rc', 'Run byebug initialization file' do |v|
114
+ Byebug.run_init_script if v
115
+ end
116
+
117
+ opts.on '-s', '--[no-]stop', 'Stop when script is loaded' do |v|
118
+ @stop = v
119
+ end
120
+
121
+ opts.on '-r', '--require file', 'Require library before script' do |lib|
122
+ require lib
123
+ end
124
+
125
+ opts.on '-R', '--remote [host:]port', 'Remote debug [host:]port' do |p|
126
+ self.remote = Byebug.parse_host_and_port(p)
127
+ end
128
+
129
+ opts.on '-t', '--[no-]trace', 'Turn on line tracing' do |v|
130
+ Setting[:linetrace] = v
131
+ end
132
+
133
+ opts.on '-v', '--version', 'Print program version' do
134
+ self.version = VERSION
135
+ end
136
+
137
+ opts.on('-h', '--help', 'Display this message') do
138
+ self.help = opts.help
139
+ end
140
+ end
141
+ end
94
142
  end
95
143
  end
@@ -1,3 +1,5 @@
1
+ require 'byebug/helper'
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Parent class for all byebug settings.
@@ -11,27 +13,6 @@ module Byebug
11
13
  @value = self.class::DEFAULT
12
14
  end
13
15
 
14
- def self.settings
15
- @settings ||= {}
16
- end
17
-
18
- def self.[](name)
19
- settings[name].value
20
- end
21
-
22
- def self.[]=(name, value)
23
- settings[name].value = value
24
- end
25
-
26
- def self.boolean?(name)
27
- key = (name =~ /^no/ ? name[2..-1] : name).to_sym
28
- settings[key].boolean?
29
- end
30
-
31
- def self.integer?(name)
32
- settings[name.to_sym].integer?
33
- end
34
-
35
16
  def boolean?
36
17
  [true, false].include?(value)
37
18
  end
@@ -42,68 +23,64 @@ module Byebug
42
23
  false
43
24
  end
44
25
 
45
- def self.exists?(name)
46
- key = (name =~ /^no/ ? name[2..-1] : name).to_sym
47
- boolean?(key) ? settings.include?(key) : settings.include?(name.to_sym)
26
+ def help
27
+ "\n #{banner}.\n\n"
48
28
  end
49
29
 
50
- def self.load
51
- Dir.glob(File.expand_path('../settings/*.rb', __FILE__)).each do |file|
52
- require file
53
- end
54
- Byebug.constants.grep(/[a-z]Setting/).map do |name|
55
- setting = Byebug.const_get(name).new
56
- settings[setting.to_sym] = setting
57
- end
30
+ def to_sym
31
+ name = self.class.name.gsub(/^Byebug::/, '').gsub(/Setting$/, '')
32
+ name.gsub(/(.)([A-Z])/, '\1_\2').downcase.to_sym
58
33
  end
59
34
 
60
- def self.find(shortcut)
61
- abbr = shortcut =~ /^no/ ? shortcut[2..-1] : shortcut
62
- matches = settings.select do |key, value|
63
- value.boolean? ? key =~ /#{abbr}/ : key =~ /#{shortcut}/
64
- end
65
- matches.size == 1 ? matches.keys.first : nil
35
+ def to_s
36
+ "#{to_sym} is #{value ? 'on' : 'off'}\n"
66
37
  end
67
38
 
68
- def self.help_all
69
- output = " List of settings supported in byebug:\n --\n"
70
- width = settings.keys.max_by(&:size).size
71
- settings.values.each do |sett|
72
- output << format(" %-#{width}s -- %s\n", sett.to_sym, sett.banner)
39
+ class << self
40
+ include StringFunctions
41
+
42
+ def settings
43
+ @settings ||= {}
73
44
  end
74
- output + "\n"
75
- end
76
45
 
77
- def self.help(cmd, subcmd)
78
- if subcmd
79
- camelized = subcmd.split('_').map { |w| w.capitalize }.join
80
- setting = Byebug.const_get("#{camelized}Setting").new
81
- <<-EOH.gsub(/^ {8}/, '')
46
+ def [](name)
47
+ settings[name].value
48
+ end
82
49
 
83
- #{cmd} #{setting.to_sym} <value>
50
+ def []=(name, value)
51
+ settings[name].value = value
52
+ end
84
53
 
85
- #{setting.banner}.
54
+ def find(shortcut)
55
+ abbr = shortcut =~ /^no/ ? shortcut[2..-1] : shortcut
56
+ matches = settings.select do |key, value|
57
+ value.boolean? ? key =~ /#{abbr}/ : key =~ /#{shortcut}/
58
+ end
59
+ matches.size == 1 ? matches.values.first : nil
60
+ end
86
61
 
87
- EOH
88
- else
89
- command = Byebug.const_get("#{cmd.capitalize}Command")
90
- command.description + help_all
62
+ def help_all
63
+ output = " List of settings supported in byebug:\n --\n"
64
+ width = settings.keys.max_by(&:size).size
65
+ settings.values.each do |sett|
66
+ output << format(" %-#{width}s -- %s\n", sett.to_sym, sett.banner)
67
+ end
68
+ output + "\n"
91
69
  end
92
- end
93
70
 
94
- def help
95
- "\n #{banner}.\n\n"
96
- end
71
+ def help(cmd, subcmd)
72
+ unless subcmd
73
+ command = Byebug.const_get("#{cmd.capitalize}Command")
74
+ return command.description + help_all
75
+ end
97
76
 
98
- def to_sym
99
- name = self.class.name.gsub(/^Byebug::/, '').gsub(/Setting$/, '')
100
- name.gsub(/(.)([A-Z])/, '\1_\2').downcase.to_sym
101
- end
77
+ setting = find(subcmd)
78
+ prettify <<-EOS
79
+ #{cmd} #{setting.to_sym} <value>
102
80
 
103
- def to_s
104
- "#{to_sym} is #{value ? 'on' : 'off'}\n"
81
+ #{setting.banner}.
82
+ EOS
83
+ end
105
84
  end
106
85
  end
107
-
108
- Setting.load
109
86
  end
@@ -1,3 +1,5 @@
1
+ require 'byebug/setting'
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Setting for automatic evaluation of unknown commands.
@@ -1,3 +1,6 @@
1
+ require 'byebug/setting'
2
+ require 'byebug/commands/irb'
3
+
1
4
  module Byebug
2
5
  #
3
6
  # Setting for automatically invoking IRB on every stop.
@@ -1,3 +1,6 @@
1
+ require 'byebug/setting'
2
+ require 'byebug/commands/list'
3
+
1
4
  module Byebug
2
5
  #
3
6
  # Setting for automatically listing source code on every stop.
@@ -1,3 +1,5 @@
1
+ require 'byebug/setting'
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Setting for automatically saving previously entered commands to history
@@ -1,3 +1,5 @@
1
+ require 'byebug/setting'
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Command to display short paths in file names.
@@ -1,3 +1,5 @@
1
+ require 'byebug/setting'
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Setting to customize the verbosity level for stack frames.
@@ -1,3 +1,5 @@
1
+ require 'byebug/setting'
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Setting to display full paths in backtraces.
@@ -1,3 +1,5 @@
1
+ require 'byebug/setting'
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Setting to customize the file where byebug's history is saved.
@@ -1,3 +1,5 @@
1
+ require 'byebug/setting'
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Setting to customize the number of byebug commands to be saved in history.
@@ -1,3 +1,5 @@
1
+ require 'byebug/setting'
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Setting to enable/disable linetracing.
@@ -1,3 +1,5 @@
1
+ require 'byebug/setting'
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Setting to customize the number of source code lines to be displayed every
@@ -1,3 +1,5 @@
1
+ require 'byebug/setting'
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Setting to enable/disable post_mortem mode, i.e., a debugger prompt after
@@ -26,9 +28,12 @@ module Byebug
26
28
  # prompt back to the user before program termination.
27
29
  #
28
30
  def self.handle_post_mortem
31
+ return unless Byebug.raised_exception
32
+
29
33
  context = Byebug.raised_exception.__bb_context
30
- file = Byebug.raised_exception.__bb_file
31
- line = Byebug.raised_exception.__bb_line
34
+ file = Byebug.raised_exception.__bb_file
35
+ line = Byebug.raised_exception.__bb_line
36
+
32
37
  Byebug.handler.at_line(context, file, line)
33
38
  end
34
39
 
@@ -1,3 +1,5 @@
1
+ require 'byebug/setting'
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Setting to enable/disable the display of backtraces when evaluations raise
@@ -1,3 +1,5 @@
1
+ require 'byebug/setting'
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Setting to show verbose output about TracePoint API events.