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,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.