byebug 5.0.0 → 6.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -1
- data/CONTRIBUTING.md +35 -13
- data/GUIDE.md +256 -198
- data/README.md +5 -11
- data/ext/byebug/byebug.c +5 -43
- data/ext/byebug/byebug.h +6 -1
- data/ext/byebug/context.c +4 -5
- data/lib/byebug/command.rb +64 -64
- data/lib/byebug/command_list.rb +32 -0
- data/lib/byebug/commands.rb +37 -0
- data/lib/byebug/commands/break.rb +45 -37
- data/lib/byebug/commands/catch.rb +52 -28
- data/lib/byebug/commands/condition.rb +19 -13
- data/lib/byebug/commands/continue.rb +15 -11
- data/lib/byebug/commands/delete.rb +18 -12
- data/lib/byebug/commands/disable.rb +9 -10
- data/lib/byebug/commands/disable/breakpoints.rb +13 -11
- data/lib/byebug/commands/disable/display.rb +13 -11
- data/lib/byebug/commands/display.rb +32 -24
- data/lib/byebug/commands/down.rb +18 -14
- data/lib/byebug/commands/edit.rb +42 -26
- data/lib/byebug/commands/enable.rb +9 -3
- data/lib/byebug/commands/enable/breakpoints.rb +13 -11
- data/lib/byebug/commands/enable/display.rb +13 -11
- data/lib/byebug/commands/finish.rb +23 -14
- data/lib/byebug/commands/frame.rb +21 -18
- data/lib/byebug/commands/help.rb +39 -16
- data/lib/byebug/commands/history.rb +16 -10
- data/lib/byebug/commands/info.rb +8 -5
- data/lib/byebug/commands/info/breakpoints.rb +16 -14
- data/lib/byebug/commands/info/display.rb +18 -18
- data/lib/byebug/commands/info/file.rb +22 -22
- data/lib/byebug/commands/info/line.rb +13 -11
- data/lib/byebug/commands/info/program.rb +13 -17
- data/lib/byebug/commands/interrupt.rb +13 -11
- data/lib/byebug/commands/irb.rb +16 -10
- data/lib/byebug/commands/kill.rb +19 -13
- data/lib/byebug/commands/list.rb +35 -24
- data/lib/byebug/commands/method.rb +25 -15
- data/lib/byebug/commands/next.rb +15 -13
- data/lib/byebug/commands/pry.rb +18 -11
- data/lib/byebug/commands/ps.rb +21 -23
- data/lib/byebug/commands/quit.rb +17 -11
- data/lib/byebug/commands/restart.rb +28 -24
- data/lib/byebug/commands/save.rb +23 -15
- data/lib/byebug/commands/set.rb +26 -19
- data/lib/byebug/commands/show.rb +20 -14
- data/lib/byebug/commands/source.rb +15 -14
- data/lib/byebug/commands/step.rb +15 -13
- data/lib/byebug/commands/thread.rb +8 -4
- data/lib/byebug/commands/thread/current.rb +11 -11
- data/lib/byebug/commands/thread/list.rb +14 -14
- data/lib/byebug/commands/thread/resume.rb +14 -14
- data/lib/byebug/commands/thread/stop.rb +14 -14
- data/lib/byebug/commands/thread/switch.rb +15 -14
- data/lib/byebug/commands/tracevar.rb +20 -16
- data/lib/byebug/commands/undisplay.rb +22 -18
- data/lib/byebug/commands/untracevar.rb +13 -11
- data/lib/byebug/commands/up.rb +18 -14
- data/lib/byebug/commands/var.rb +10 -3
- data/lib/byebug/commands/var/all.rb +15 -13
- data/lib/byebug/commands/var/args.rb +37 -0
- data/lib/byebug/commands/var/const.rb +25 -14
- data/lib/byebug/commands/var/global.rb +13 -11
- data/lib/byebug/commands/var/instance.rb +13 -11
- data/lib/byebug/commands/var/local.rb +13 -11
- data/lib/byebug/commands/where.rb +15 -11
- data/lib/byebug/context.rb +71 -73
- data/lib/byebug/core.rb +45 -26
- data/lib/byebug/errors.rb +27 -0
- data/lib/byebug/frame.rb +181 -0
- data/lib/byebug/helpers/eval.rb +67 -26
- data/lib/byebug/helpers/file.rb +18 -3
- data/lib/byebug/helpers/frame.rb +36 -39
- data/lib/byebug/helpers/parse.rb +15 -13
- data/lib/byebug/helpers/path.rb +21 -0
- data/lib/byebug/helpers/reflection.rb +17 -0
- data/lib/byebug/helpers/thread.rb +20 -14
- data/lib/byebug/helpers/toggle.rb +10 -5
- data/lib/byebug/helpers/var.rb +36 -15
- data/lib/byebug/interface.rb +27 -9
- data/lib/byebug/option_setter.rb +93 -0
- data/lib/byebug/printers/base.rb +3 -0
- data/lib/byebug/printers/plain.rb +4 -14
- data/lib/byebug/printers/texts/base.yml +2 -7
- data/lib/byebug/processors/command_processor.rb +101 -102
- data/lib/byebug/processors/control_processor.rb +20 -0
- data/lib/byebug/processors/post_mortem_processor.rb +16 -0
- data/lib/byebug/processors/script_processor.rb +49 -0
- data/lib/byebug/remote.rb +13 -7
- data/lib/byebug/runner.rb +39 -65
- data/lib/byebug/setting.rb +4 -1
- data/lib/byebug/settings/post_mortem.rb +0 -16
- data/lib/byebug/settings/savefile.rb +1 -4
- data/lib/byebug/subcommands.rb +27 -29
- data/lib/byebug/version.rb +4 -1
- metadata +14 -29
- data/lib/byebug/commands/eval.rb +0 -43
- data/lib/byebug/commands/info/args.rb +0 -39
- data/lib/byebug/commands/info/catch.rb +0 -39
- data/lib/byebug/commands/pp.rb +0 -41
- data/lib/byebug/commands/putl.rb +0 -43
- data/lib/byebug/processor.rb +0 -43
- data/lib/byebug/processors/control_command_processor.rb +0 -48
- data/lib/byebug/settings/verbose.rb +0 -20
- data/lib/byebug/state.rb +0 -12
- data/lib/byebug/states/control_state.rb +0 -26
- data/lib/byebug/states/regular_state.rb +0 -187
- data/lib/byebug/subcommand_list.rb +0 -33
@@ -0,0 +1,20 @@
|
|
1
|
+
module Byebug
|
2
|
+
#
|
3
|
+
# Processes commands when there's not program running
|
4
|
+
#
|
5
|
+
class ControlProcessor < CommandProcessor
|
6
|
+
#
|
7
|
+
# Available commands
|
8
|
+
#
|
9
|
+
def commands
|
10
|
+
super.select(&:allow_in_control)
|
11
|
+
end
|
12
|
+
|
13
|
+
#
|
14
|
+
# Prompt shown before reading a command.
|
15
|
+
#
|
16
|
+
def prompt
|
17
|
+
'(byebug:ctrl) '
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'byebug/processors/command_processor'
|
2
|
+
|
3
|
+
module Byebug
|
4
|
+
#
|
5
|
+
# Processes commands in post_mortem mode
|
6
|
+
#
|
7
|
+
class PostMortemProcessor < CommandProcessor
|
8
|
+
def commands
|
9
|
+
super.select(&:allow_in_post_mortem)
|
10
|
+
end
|
11
|
+
|
12
|
+
def prompt
|
13
|
+
'(byebug:post_mortem) '
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Byebug
|
2
|
+
#
|
3
|
+
# Processes commands from a file
|
4
|
+
#
|
5
|
+
class ScriptProcessor < CommandProcessor
|
6
|
+
#
|
7
|
+
# Available commands
|
8
|
+
#
|
9
|
+
def commands
|
10
|
+
super.select(&:allow_in_control)
|
11
|
+
end
|
12
|
+
|
13
|
+
def process_commands
|
14
|
+
while (input = interface.read_command(prompt))
|
15
|
+
command = command_list.match(input)
|
16
|
+
|
17
|
+
if command
|
18
|
+
command.new(self).execute
|
19
|
+
else
|
20
|
+
errmsg('Unknown command')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
interface.close
|
25
|
+
rescue IOError, SystemCallError
|
26
|
+
interface.close
|
27
|
+
rescue
|
28
|
+
without_exceptions do
|
29
|
+
puts "INTERNAL ERROR!!! #{$ERROR_INFO}"
|
30
|
+
puts $ERROR_INFO.backtrace.map { |l| "\t#{l}" }.join("\n")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# Prompt shown before reading a command.
|
36
|
+
#
|
37
|
+
def prompt
|
38
|
+
'(byebug:ctrl) '
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def without_exceptions
|
44
|
+
yield
|
45
|
+
rescue
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/byebug/remote.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
require 'socket'
|
2
2
|
|
3
|
+
#
|
4
|
+
# Remote debugging functionality.
|
5
|
+
#
|
6
|
+
# TODO: Refactor & add tests
|
7
|
+
#
|
3
8
|
module Byebug
|
4
9
|
# Port number used for remote debugging
|
5
10
|
PORT = 8989 unless defined?(PORT)
|
@@ -25,7 +30,7 @@ module Byebug
|
|
25
30
|
def start_server(host = nil, port = PORT)
|
26
31
|
return if @thread
|
27
32
|
|
28
|
-
|
33
|
+
Context.interface = nil
|
29
34
|
start
|
30
35
|
|
31
36
|
start_control(host, port == 0 ? 0 : port + 1)
|
@@ -40,7 +45,7 @@ module Byebug
|
|
40
45
|
|
41
46
|
@thread = DebugThread.new do
|
42
47
|
while (session = server.accept)
|
43
|
-
|
48
|
+
Context.interface = RemoteInterface.new(session)
|
44
49
|
mutex.synchronize { proceed.signal } if wait_connection
|
45
50
|
end
|
46
51
|
end
|
@@ -55,8 +60,9 @@ module Byebug
|
|
55
60
|
|
56
61
|
@control_thread = DebugThread.new do
|
57
62
|
while (session = server.accept)
|
58
|
-
|
59
|
-
|
63
|
+
Context.interface = RemoteInterface.new(session)
|
64
|
+
|
65
|
+
ControlCommandProcessor.new(Byebug.current_context).process_commands
|
60
66
|
end
|
61
67
|
end
|
62
68
|
|
@@ -67,7 +73,7 @@ module Byebug
|
|
67
73
|
# Connects to the remote byebug
|
68
74
|
#
|
69
75
|
def start_client(host = 'localhost', port = PORT)
|
70
|
-
|
76
|
+
Context.interface = LocalInterface.new
|
71
77
|
puts 'Connecting to byebug server...'
|
72
78
|
socket = TCPSocket.new(host, port)
|
73
79
|
puts 'Connected.'
|
@@ -76,11 +82,11 @@ module Byebug
|
|
76
82
|
while (line = socket.gets)
|
77
83
|
case line
|
78
84
|
when /^PROMPT (.*)$/
|
79
|
-
input =
|
85
|
+
input = Context.interface.read_command(Regexp.last_match[1])
|
80
86
|
throw :exit unless input
|
81
87
|
socket.puts input
|
82
88
|
when /^CONFIRM (.*)$/
|
83
|
-
input =
|
89
|
+
input = Context.interface.confirm(Regexp.last_match[1])
|
84
90
|
throw :exit unless input
|
85
91
|
socket.puts input
|
86
92
|
else
|
data/lib/byebug/runner.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
require 'optparse'
|
2
2
|
require 'English'
|
3
3
|
require 'byebug/core'
|
4
|
+
require 'byebug/version'
|
4
5
|
require 'byebug/helpers/parse'
|
6
|
+
require 'byebug/option_setter'
|
7
|
+
require 'byebug/processors/control_processor'
|
5
8
|
|
6
9
|
module Byebug
|
7
10
|
#
|
@@ -11,24 +14,29 @@ module Byebug
|
|
11
14
|
include Helpers::ParseHelper
|
12
15
|
|
13
16
|
#
|
14
|
-
# Error class signaling absence of a script to debug
|
17
|
+
# Error class signaling absence of a script to debug.
|
15
18
|
#
|
16
19
|
class NoScript < StandardError; end
|
17
20
|
|
18
21
|
#
|
19
|
-
# Error class signaling a non existent script to debug
|
22
|
+
# Error class signaling a non existent script to debug.
|
20
23
|
#
|
21
24
|
class NonExistentScript < StandardError; end
|
22
25
|
|
23
26
|
#
|
24
|
-
# Error class signaling a script with invalid Ruby syntax
|
27
|
+
# Error class signaling a script with invalid Ruby syntax.
|
25
28
|
#
|
26
29
|
class InvalidScript < StandardError; end
|
27
30
|
|
28
31
|
#
|
29
32
|
# Special working modes that don't actually start the debugger.
|
30
33
|
#
|
31
|
-
|
34
|
+
attr_reader :help, :version, :remote
|
35
|
+
|
36
|
+
#
|
37
|
+
# Signals that we should exit after the debugged program is finished.
|
38
|
+
#
|
39
|
+
attr_accessor :quit
|
32
40
|
|
33
41
|
#
|
34
42
|
# @param stop [Boolean] Whether the runner should stop right before
|
@@ -42,6 +50,22 @@ module Byebug
|
|
42
50
|
@quit = quit
|
43
51
|
end
|
44
52
|
|
53
|
+
def help=(text)
|
54
|
+
@help ||= text
|
55
|
+
|
56
|
+
interface.puts("\n#{text}\n")
|
57
|
+
end
|
58
|
+
|
59
|
+
def version=(number)
|
60
|
+
@version ||= number
|
61
|
+
|
62
|
+
interface.puts("\n Running byebug #{number}\n")
|
63
|
+
end
|
64
|
+
|
65
|
+
def remote=(host_and_port)
|
66
|
+
@remote ||= Byebug.parse_host_and_port(host_and_port)
|
67
|
+
end
|
68
|
+
|
45
69
|
#
|
46
70
|
# Usage banner.
|
47
71
|
#
|
@@ -56,20 +80,11 @@ module Byebug
|
|
56
80
|
end
|
57
81
|
|
58
82
|
#
|
59
|
-
# Starts byebug to debug a program
|
83
|
+
# Starts byebug to debug a program.
|
60
84
|
#
|
61
85
|
def run
|
62
86
|
prepare_options.order!($ARGV)
|
63
|
-
|
64
|
-
if version
|
65
|
-
Byebug.puts("\n Running byebug #{version}\n")
|
66
|
-
return
|
67
|
-
end
|
68
|
-
|
69
|
-
if help
|
70
|
-
Byebug.puts("#{help}\n")
|
71
|
-
return
|
72
|
-
end
|
87
|
+
return if version || help
|
73
88
|
|
74
89
|
if remote
|
75
90
|
Byebug.start_client(*remote)
|
@@ -81,70 +96,29 @@ module Byebug
|
|
81
96
|
loop do
|
82
97
|
debug_program
|
83
98
|
|
84
|
-
break if
|
99
|
+
break if quit
|
85
100
|
|
86
|
-
|
87
|
-
processor.process_commands
|
101
|
+
ControlProcessor.new.process_commands
|
88
102
|
end
|
89
103
|
end
|
90
104
|
|
91
|
-
|
105
|
+
def interface
|
106
|
+
@interface ||= LocalInterface.new
|
107
|
+
end
|
92
108
|
|
93
109
|
#
|
94
|
-
# Processes options passed from the command line
|
110
|
+
# Processes options passed from the command line.
|
95
111
|
#
|
96
112
|
def prepare_options
|
97
113
|
OptionParser.new(banner, 25) do |opts|
|
98
114
|
opts.banner = banner
|
99
115
|
|
100
|
-
|
101
|
-
$DEBUG = true
|
102
|
-
end
|
103
|
-
|
104
|
-
opts.on('-I', '--include list', 'Add to paths to $LOAD_PATH') do |list|
|
105
|
-
$LOAD_PATH.push(list.split(':')).flatten!
|
106
|
-
end
|
107
|
-
|
108
|
-
opts.on '-m', '--[no-]post-mortem', 'Use post-mortem mode' do |v|
|
109
|
-
Setting[:post_mortem] = v
|
110
|
-
end
|
111
|
-
|
112
|
-
opts.on '-q', '--[no-]quit', 'Quit when script finishes' do |v|
|
113
|
-
@quit = v
|
114
|
-
end
|
115
|
-
|
116
|
-
opts.on '-x', '--[no-]rc', 'Run byebug initialization file' do |v|
|
117
|
-
Byebug.run_init_script if v
|
118
|
-
end
|
119
|
-
|
120
|
-
opts.on '-s', '--[no-]stop', 'Stop when script is loaded' do |v|
|
121
|
-
@stop = v
|
122
|
-
end
|
123
|
-
|
124
|
-
opts.on '-r', '--require file', 'Require library before script' do |lib|
|
125
|
-
require lib
|
126
|
-
end
|
127
|
-
|
128
|
-
opts.on '-R', '--remote [host:]port', 'Remote debug [host:]port' do |p|
|
129
|
-
self.remote = Byebug.parse_host_and_port(p)
|
130
|
-
end
|
131
|
-
|
132
|
-
opts.on '-t', '--[no-]trace', 'Turn on line tracing' do |v|
|
133
|
-
Setting[:linetrace] = v
|
134
|
-
end
|
135
|
-
|
136
|
-
opts.on '-v', '--version', 'Print program version' do
|
137
|
-
self.version = VERSION
|
138
|
-
end
|
139
|
-
|
140
|
-
opts.on('-h', '--help', 'Display this message') do
|
141
|
-
self.help = opts.help
|
142
|
-
end
|
116
|
+
OptionSetter.new(self, opts).setup
|
143
117
|
end
|
144
118
|
end
|
145
119
|
|
146
120
|
#
|
147
|
-
# Extracts debugged program from command line args
|
121
|
+
# Extracts debugged program from command line args.
|
148
122
|
#
|
149
123
|
def setup_cmd_line_args
|
150
124
|
Byebug.mode = :standalone
|
@@ -166,7 +140,7 @@ module Byebug
|
|
166
140
|
fail(InvalidScript, 'The script has incorrect syntax') unless ok
|
167
141
|
|
168
142
|
error = Byebug.debug_load($PROGRAM_NAME, @stop)
|
169
|
-
|
143
|
+
puts "#{error}\n#{error.backtrace}" if error
|
170
144
|
end
|
171
145
|
|
172
146
|
#
|
data/lib/byebug/setting.rb
CHANGED
@@ -57,8 +57,11 @@ module Byebug
|
|
57
57
|
matches.size == 1 ? matches.values.first : nil
|
58
58
|
end
|
59
59
|
|
60
|
+
#
|
61
|
+
# TODO: DRY this up. Very similar code exists in the CommandList class
|
62
|
+
#
|
60
63
|
def help_all
|
61
|
-
output = " List of
|
64
|
+
output = " List of supported settings:\n\n"
|
62
65
|
width = settings.keys.max_by(&:size).size
|
63
66
|
settings.values.each do |sett|
|
64
67
|
output << format(" %-#{width}s -- %s\n", sett.to_sym, sett.banner)
|
@@ -22,20 +22,4 @@ module Byebug
|
|
22
22
|
Byebug.post_mortem?
|
23
23
|
end
|
24
24
|
end
|
25
|
-
|
26
|
-
#
|
27
|
-
# Saves information about the unhandled exception and gives a byebug
|
28
|
-
# prompt back to the user before program termination.
|
29
|
-
#
|
30
|
-
def self.handle_post_mortem
|
31
|
-
return unless Byebug.raised_exception
|
32
|
-
|
33
|
-
context = Byebug.raised_exception.__bb_context
|
34
|
-
file = Byebug.raised_exception.__bb_file
|
35
|
-
line = Byebug.raised_exception.__bb_line
|
36
|
-
|
37
|
-
Byebug.handler.at_line(context, file, line)
|
38
|
-
end
|
39
|
-
|
40
|
-
at_exit { Byebug.handle_post_mortem if Byebug.post_mortem? }
|
41
25
|
end
|
@@ -8,10 +8,7 @@ module Byebug
|
|
8
8
|
DEFAULT = File.expand_path("#{ENV['HOME'] || '.'}/.byebug_save")
|
9
9
|
|
10
10
|
def banner
|
11
|
-
|
12
|
-
File where save commands saves current settings to. Default:
|
13
|
-
~/.byebug_save
|
14
|
-
EOB
|
11
|
+
'File where settings are saved to. Default: ~/.byebug_save'
|
15
12
|
end
|
16
13
|
|
17
14
|
def to_s
|
data/lib/byebug/subcommands.rb
CHANGED
@@ -1,53 +1,51 @@
|
|
1
|
-
require '
|
2
|
-
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
require 'byebug/helpers/reflection'
|
4
|
+
require 'byebug/command_list'
|
3
5
|
|
4
6
|
module Byebug
|
5
7
|
#
|
6
8
|
# Subcommand additions.
|
7
9
|
#
|
8
10
|
module Subcommands
|
9
|
-
|
10
|
-
|
11
|
-
#
|
12
|
-
def short_description
|
13
|
-
fail(NotImplementedError, 'Your custom subcommand needs to define this')
|
11
|
+
def self.included(command)
|
12
|
+
command.extend(ClassMethods)
|
14
13
|
end
|
15
14
|
|
15
|
+
extend Forwardable
|
16
|
+
def_delegators :'self.class', :subcommand_list
|
17
|
+
|
16
18
|
#
|
17
19
|
# Delegates to subcommands or prints help if no subcommand specified.
|
18
20
|
#
|
19
21
|
def execute
|
20
22
|
return puts(help) unless @match[1]
|
21
23
|
|
22
|
-
subcmd =
|
23
|
-
|
24
|
+
subcmd = subcommand_list.match(@match[1])
|
25
|
+
fail CommandNotFound.new(@match[1], self.class) unless subcmd
|
24
26
|
|
25
|
-
subcmd.execute
|
27
|
+
subcmd.new(processor, arguments).execute
|
26
28
|
end
|
27
29
|
|
28
30
|
#
|
29
|
-
#
|
31
|
+
# Class methods added to subcommands
|
30
32
|
#
|
31
|
-
|
32
|
-
|
33
|
-
#{description}
|
34
|
-
|
35
|
-
List of "#{to_name}" subcommands:
|
33
|
+
module ClassMethods
|
34
|
+
include Helpers::ReflectionHelper
|
36
35
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
# Command's subcommands.
|
44
|
-
#
|
45
|
-
def subcommands
|
46
|
-
subcmd_klasses = self.class.subcommands
|
47
|
-
return nil unless subcmd_klasses.any?
|
36
|
+
#
|
37
|
+
# Default help text for a command with subcommands
|
38
|
+
#
|
39
|
+
def help
|
40
|
+
super + subcommand_list.to_s
|
41
|
+
end
|
48
42
|
|
49
|
-
|
50
|
-
|
43
|
+
#
|
44
|
+
# Command's subcommands.
|
45
|
+
#
|
46
|
+
def subcommand_list
|
47
|
+
@subcommand_list ||= CommandList.new(commands)
|
48
|
+
end
|
51
49
|
end
|
52
50
|
end
|
53
51
|
end
|