byebug 8.2.5 → 9.1.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 +77 -0
- data/CONTRIBUTING.md +6 -6
- data/GUIDE.md +26 -26
- data/README.md +18 -7
- data/bin/byebug +3 -1
- data/ext/byebug/breakpoint.c +3 -3
- data/ext/byebug/byebug.c +7 -4
- data/ext/byebug/byebug.h +0 -4
- data/ext/byebug/locker.c +1 -1
- data/ext/byebug/threads.c +2 -2
- data/lib/byebug/breakpoint.rb +2 -4
- data/lib/byebug/commands/catch.rb +1 -1
- data/lib/byebug/commands/delete.rb +4 -2
- data/lib/byebug/commands/edit.rb +1 -1
- data/lib/byebug/commands/enable/breakpoints.rb +1 -1
- data/lib/byebug/commands/finish.rb +1 -1
- data/lib/byebug/commands/info/breakpoints.rb +1 -1
- data/lib/byebug/commands/info/file.rb +2 -3
- data/lib/byebug/commands/irb.rb +8 -6
- data/lib/byebug/commands/kill.rb +1 -1
- data/lib/byebug/commands/pry.rb +3 -3
- data/lib/byebug/commands/restart.rb +22 -5
- data/lib/byebug/commands/save.rb +1 -1
- data/lib/byebug/core.rb +11 -4
- data/lib/byebug/frame.rb +6 -6
- data/lib/byebug/helpers/bin.rb +26 -0
- data/lib/byebug/helpers/file.rb +3 -3
- data/lib/byebug/helpers/parse.rb +1 -1
- data/lib/byebug/helpers/path.rb +7 -11
- data/lib/byebug/helpers/string.rb +11 -1
- data/lib/byebug/helpers/thread.rb +7 -5
- data/lib/byebug/helpers/toggle.rb +25 -24
- data/lib/byebug/helpers/var.rb +1 -1
- data/lib/byebug/history.rb +9 -2
- data/lib/byebug/interface.rb +3 -0
- data/lib/byebug/interfaces/local_interface.rb +5 -6
- data/lib/byebug/interfaces/script_interface.rb +4 -3
- data/lib/byebug/printers/base.rb +2 -1
- data/lib/byebug/printers/plain.rb +1 -2
- data/lib/byebug/printers/texts/base.yml +4 -0
- data/lib/byebug/printers/texts/plain.yml +1 -1
- data/lib/byebug/processors/command_processor.rb +15 -15
- data/lib/byebug/processors/script_processor.rb +6 -12
- data/lib/byebug/remote.rb +19 -19
- data/lib/byebug/runner.rb +65 -56
- data/lib/byebug/setting.rb +1 -1
- data/lib/byebug/settings/callstyle.rb +1 -0
- data/lib/byebug/version.rb +2 -1
- metadata +12 -13
data/lib/byebug/core.rb
CHANGED
|
@@ -47,13 +47,11 @@ module Byebug
|
|
|
47
47
|
# are debugging, in the directory where you invoke byebug.
|
|
48
48
|
#
|
|
49
49
|
def run_init_script
|
|
50
|
-
run_rc_file(
|
|
51
|
-
|
|
52
|
-
run_rc_file(Dir.pwd) unless Dir.pwd == ENV['HOME']
|
|
50
|
+
rc_dirs.each { |dir| run_rc_file(dir) }
|
|
53
51
|
end
|
|
54
52
|
|
|
55
53
|
def self.load_settings
|
|
56
|
-
Dir.glob(File.
|
|
54
|
+
Dir.glob(File.join(__dir__, 'settings', '*.rb')).each do |file|
|
|
57
55
|
require file
|
|
58
56
|
end
|
|
59
57
|
|
|
@@ -94,6 +92,15 @@ module Byebug
|
|
|
94
92
|
ensure
|
|
95
93
|
Context.interface = old_interface
|
|
96
94
|
end
|
|
95
|
+
|
|
96
|
+
#
|
|
97
|
+
# List of folders to load rc files from
|
|
98
|
+
#
|
|
99
|
+
# @note Files will be loaded in the order specified here.
|
|
100
|
+
#
|
|
101
|
+
def rc_dirs
|
|
102
|
+
[ENV['HOME'], Dir.pwd].compact.uniq
|
|
103
|
+
end
|
|
97
104
|
end
|
|
98
105
|
|
|
99
106
|
Byebug.load_settings
|
data/lib/byebug/frame.rb
CHANGED
|
@@ -47,13 +47,13 @@ module Byebug
|
|
|
47
47
|
#
|
|
48
48
|
# Gets local variables for the frame.
|
|
49
49
|
#
|
|
50
|
-
# TODO: Use brand new local_variable_get, local_variable_set and
|
|
51
|
-
# local_variable defined for rubies >= 2.1
|
|
52
|
-
#
|
|
53
50
|
def locals
|
|
54
51
|
return [] unless _binding
|
|
55
52
|
|
|
56
|
-
_binding.
|
|
53
|
+
_binding.local_variables.each_with_object({}) do |e, a|
|
|
54
|
+
a[e] = _binding.local_variable_get(e)
|
|
55
|
+
a
|
|
56
|
+
end
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
#
|
|
@@ -158,14 +158,14 @@ module Byebug
|
|
|
158
158
|
def c_args
|
|
159
159
|
return [] unless _self.to_s != 'main'
|
|
160
160
|
|
|
161
|
-
|
|
161
|
+
_class.instance_method(_method).parameters
|
|
162
162
|
end
|
|
163
163
|
|
|
164
164
|
def ruby_args
|
|
165
165
|
meth_name = _binding.eval('__method__')
|
|
166
166
|
return [] unless meth_name
|
|
167
167
|
|
|
168
|
-
meth_obj =
|
|
168
|
+
meth_obj = _class.instance_method(meth_name)
|
|
169
169
|
return [] unless meth_obj
|
|
170
170
|
|
|
171
171
|
meth_obj.parameters
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Byebug
|
|
2
|
+
module Helpers
|
|
3
|
+
#
|
|
4
|
+
# Utilities for interaction with executables
|
|
5
|
+
#
|
|
6
|
+
module BinHelper
|
|
7
|
+
#
|
|
8
|
+
# Cross-platform way of finding an executable in the $PATH.
|
|
9
|
+
# Borrowed from: http://stackoverflow.com/questions/2108727
|
|
10
|
+
#
|
|
11
|
+
def which(cmd)
|
|
12
|
+
return File.expand_path(cmd) if File.exist?(cmd)
|
|
13
|
+
|
|
14
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
|
15
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
|
16
|
+
exts.each do |ext|
|
|
17
|
+
exe = File.join(path, "#{cmd}#{ext}")
|
|
18
|
+
return exe if File.executable?(exe) && !File.directory?(exe)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
nil
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
data/lib/byebug/helpers/file.rb
CHANGED
|
@@ -8,7 +8,7 @@ module Byebug
|
|
|
8
8
|
# Reads lines of source file +filename+ into an array
|
|
9
9
|
#
|
|
10
10
|
def get_lines(filename)
|
|
11
|
-
File.foreach(filename).reduce([]) { |
|
|
11
|
+
File.foreach(filename).reduce([]) { |acc, elem| acc << elem.chomp }
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
#
|
|
@@ -26,7 +26,7 @@ module Byebug
|
|
|
26
26
|
# one-line-at-a-time way.
|
|
27
27
|
#
|
|
28
28
|
def n_lines(filename)
|
|
29
|
-
File.foreach(filename).reduce(0) { |
|
|
29
|
+
File.foreach(filename).reduce(0) { |acc, _elem| acc + 1 }
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
#
|
|
@@ -54,7 +54,7 @@ module Byebug
|
|
|
54
54
|
# True for special files like -e, false otherwise
|
|
55
55
|
#
|
|
56
56
|
def virtual_file?(name)
|
|
57
|
-
['(irb)', '-e', '(byebug)'].include?(name)
|
|
57
|
+
['(irb)', '-e', '(byebug)', '(eval)'].include?(name)
|
|
58
58
|
end
|
|
59
59
|
end
|
|
60
60
|
end
|
data/lib/byebug/helpers/parse.rb
CHANGED
|
@@ -9,7 +9,7 @@ module Byebug
|
|
|
9
9
|
#
|
|
10
10
|
# If either +min+ or +max+ is nil, that value has no bound.
|
|
11
11
|
#
|
|
12
|
-
#
|
|
12
|
+
# @todo Remove the `cmd` parameter. It has nothing to do with the method's
|
|
13
13
|
# purpose.
|
|
14
14
|
#
|
|
15
15
|
def get_int(str, cmd, min = nil, max = nil)
|
data/lib/byebug/helpers/path.rb
CHANGED
|
@@ -5,27 +5,23 @@ module Byebug
|
|
|
5
5
|
#
|
|
6
6
|
module PathHelper
|
|
7
7
|
def bin_file
|
|
8
|
-
@bin_file ||=
|
|
8
|
+
@bin_file ||= File.join(root_path, 'bin', 'byebug')
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def root_path
|
|
12
|
-
@root_path ||= File.expand_path('
|
|
12
|
+
@root_path ||= File.expand_path(File.join('..', '..', '..'), __dir__)
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def lib_files
|
|
16
|
-
@lib_files ||=
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def ext_files
|
|
20
|
-
@ext_files ||= expand_from_root('ext/**/*.{c,h,rb}')
|
|
16
|
+
@lib_files ||= glob_for('lib')
|
|
21
17
|
end
|
|
22
18
|
|
|
23
19
|
def test_files
|
|
24
|
-
@test_files ||=
|
|
20
|
+
@test_files ||= glob_for('test')
|
|
25
21
|
end
|
|
26
22
|
|
|
27
23
|
def gem_files
|
|
28
|
-
@gem_files ||= [bin_file] + lib_files
|
|
24
|
+
@gem_files ||= [bin_file] + lib_files
|
|
29
25
|
end
|
|
30
26
|
|
|
31
27
|
def all_files
|
|
@@ -34,8 +30,8 @@ module Byebug
|
|
|
34
30
|
|
|
35
31
|
private
|
|
36
32
|
|
|
37
|
-
def
|
|
38
|
-
Dir.glob(File.
|
|
33
|
+
def glob_for(dir)
|
|
34
|
+
Dir.glob(File.join(root_path, dir, '**', '*.rb'))
|
|
39
35
|
end
|
|
40
36
|
end
|
|
41
37
|
end
|
|
@@ -17,7 +17,17 @@ module Byebug
|
|
|
17
17
|
# command prompt.
|
|
18
18
|
#
|
|
19
19
|
def prettify(str)
|
|
20
|
-
"\n" + str
|
|
20
|
+
"\n" + deindent(str) + "\n"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
#
|
|
24
|
+
# Removes a number of leading whitespace for each input line.
|
|
25
|
+
#
|
|
26
|
+
# @note Might be unnecessary when Ruby 2.2 support is dropped and we can
|
|
27
|
+
# use squiggly heredoc's.
|
|
28
|
+
#
|
|
29
|
+
def deindent(str, leading_spaces: 6)
|
|
30
|
+
str.gsub(/^ {#{leading_spaces}}/, '')
|
|
21
31
|
end
|
|
22
32
|
end
|
|
23
33
|
end
|
|
@@ -28,10 +28,12 @@ module Byebug
|
|
|
28
28
|
def context_from_thread(thnum)
|
|
29
29
|
ctx = Byebug.contexts.find { |c| c.thnum.to_s == thnum }
|
|
30
30
|
|
|
31
|
-
err =
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
err = if ctx.nil?
|
|
32
|
+
pr('thread.errors.no_thread')
|
|
33
|
+
elsif ctx == context
|
|
34
|
+
pr('thread.errors.current_thread')
|
|
35
|
+
elsif ctx.ignored?
|
|
36
|
+
pr('thread.errors.ignored', arg: thnum)
|
|
35
37
|
end
|
|
36
38
|
|
|
37
39
|
[ctx, err]
|
|
@@ -39,7 +41,7 @@ module Byebug
|
|
|
39
41
|
|
|
40
42
|
private
|
|
41
43
|
|
|
42
|
-
#
|
|
44
|
+
# @todo Check whether it is Byebug.current_context or context
|
|
43
45
|
def location(ctx)
|
|
44
46
|
return context.location if ctx == Byebug.current_context
|
|
45
47
|
|
|
@@ -9,50 +9,51 @@ module Byebug
|
|
|
9
9
|
include ParseHelper
|
|
10
10
|
|
|
11
11
|
def enable_disable_breakpoints(is_enable, args)
|
|
12
|
-
|
|
12
|
+
raise pr('toggle.errors.no_breakpoints') if Breakpoint.none?
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
selected_breakpoints = all_breakpoints
|
|
17
|
-
else
|
|
18
|
-
selected_ids = []
|
|
19
|
-
args.split(/ +/).each do |pos|
|
|
20
|
-
last_id = all_breakpoints.last.id
|
|
21
|
-
pos, err = get_int(pos, "#{is_enable} breakpoints", 1, last_id)
|
|
22
|
-
return errmsg(err) unless pos
|
|
23
|
-
|
|
24
|
-
selected_ids << pos
|
|
25
|
-
end
|
|
26
|
-
selected_breakpoints = all_breakpoints.select do |b|
|
|
27
|
-
selected_ids.include?(b.id)
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
selected_breakpoints.each do |b|
|
|
32
|
-
enabled = ('enable' == is_enable)
|
|
14
|
+
select_breakpoints(is_enable, args).each do |b|
|
|
15
|
+
enabled = (is_enable == 'enable')
|
|
33
16
|
if enabled && !syntax_valid?(b.expr)
|
|
34
|
-
|
|
17
|
+
raise pr('toggle.errors.expression', expr: b.expr)
|
|
35
18
|
end
|
|
36
19
|
|
|
20
|
+
puts pr('toggle.messages.toggled', bpnum: b.id,
|
|
21
|
+
endis: enabled ? 'en' : 'dis')
|
|
37
22
|
b.enabled = enabled
|
|
38
23
|
end
|
|
39
24
|
end
|
|
40
25
|
|
|
41
26
|
def enable_disable_display(is_enable, args)
|
|
42
|
-
|
|
27
|
+
raise pr('toggle.errors.no_display') if n_displays.zero?
|
|
43
28
|
|
|
44
29
|
selected_displays = args ? args.split(/ +/) : [1..n_displays + 1]
|
|
45
30
|
|
|
46
31
|
selected_displays.each do |pos|
|
|
47
32
|
pos, err = get_int(pos, "#{is_enable} display", 1, n_displays)
|
|
48
|
-
|
|
33
|
+
raise err unless err.nil?
|
|
49
34
|
|
|
50
|
-
Byebug.displays[pos - 1][0] = ('enable'
|
|
35
|
+
Byebug.displays[pos - 1][0] = (is_enable == 'enable')
|
|
51
36
|
end
|
|
52
37
|
end
|
|
53
38
|
|
|
54
39
|
private
|
|
55
40
|
|
|
41
|
+
def select_breakpoints(is_enable, args)
|
|
42
|
+
all_breakpoints = Byebug.breakpoints.sort_by(&:id)
|
|
43
|
+
return all_breakpoints if args.nil?
|
|
44
|
+
|
|
45
|
+
selected_ids = []
|
|
46
|
+
args.split(/ +/).each do |pos|
|
|
47
|
+
last_id = all_breakpoints.last.id
|
|
48
|
+
pos, err = get_int(pos, "#{is_enable} breakpoints", 1, last_id)
|
|
49
|
+
raise(ArgumentError, err) unless pos
|
|
50
|
+
|
|
51
|
+
selected_ids << pos
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
all_breakpoints.select { |b| selected_ids.include?(b.id) }
|
|
55
|
+
end
|
|
56
|
+
|
|
56
57
|
def n_displays
|
|
57
58
|
Byebug.displays.size
|
|
58
59
|
end
|
data/lib/byebug/helpers/var.rb
CHANGED
data/lib/byebug/history.rb
CHANGED
|
@@ -21,6 +21,13 @@ module Byebug
|
|
|
21
21
|
self.size = 0
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
+
#
|
|
25
|
+
# Array holding the list of commands in history
|
|
26
|
+
#
|
|
27
|
+
def buffer
|
|
28
|
+
Readline::HISTORY.to_a
|
|
29
|
+
end
|
|
30
|
+
|
|
24
31
|
#
|
|
25
32
|
# Restores history from disk.
|
|
26
33
|
#
|
|
@@ -74,7 +81,7 @@ module Byebug
|
|
|
74
81
|
def to_s(n_cmds)
|
|
75
82
|
show_size = n_cmds ? specific_max_size(n_cmds) : default_max_size
|
|
76
83
|
|
|
77
|
-
commands =
|
|
84
|
+
commands = buffer.last(show_size)
|
|
78
85
|
|
|
79
86
|
last_ids(show_size).zip(commands).map do |l|
|
|
80
87
|
format('%5d %s', l[0], l[1])
|
|
@@ -115,7 +122,7 @@ module Byebug
|
|
|
115
122
|
return true if /^\s*$/ =~ buf
|
|
116
123
|
return false if Readline::HISTORY.empty?
|
|
117
124
|
|
|
118
|
-
|
|
125
|
+
buffer[Readline::HISTORY.length - 1] == buf
|
|
119
126
|
end
|
|
120
127
|
end
|
|
121
128
|
end
|
data/lib/byebug/interface.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
module Byebug
|
|
3
4
|
#
|
|
4
5
|
# Interface class for standard byebug use.
|
|
@@ -8,9 +9,9 @@ module Byebug
|
|
|
8
9
|
|
|
9
10
|
def initialize
|
|
10
11
|
super()
|
|
11
|
-
@input =
|
|
12
|
-
@output =
|
|
13
|
-
@error =
|
|
12
|
+
@input = $stdin
|
|
13
|
+
@output = $stdout
|
|
14
|
+
@error = $stderr
|
|
14
15
|
end
|
|
15
16
|
|
|
16
17
|
#
|
|
@@ -20,9 +21,7 @@ module Byebug
|
|
|
20
21
|
# @param prompt Prompt to be displayed.
|
|
21
22
|
#
|
|
22
23
|
def readline(prompt)
|
|
23
|
-
with_repl_like_sigint
|
|
24
|
-
Readline.readline(prompt, false) || EOF_ALIAS
|
|
25
|
-
end
|
|
24
|
+
with_repl_like_sigint { Readline.readline(prompt) || EOF_ALIAS }
|
|
26
25
|
end
|
|
27
26
|
|
|
28
27
|
#
|
|
@@ -5,9 +5,10 @@ module Byebug
|
|
|
5
5
|
class ScriptInterface < Interface
|
|
6
6
|
def initialize(file, verbose = false)
|
|
7
7
|
super()
|
|
8
|
+
@verbose = verbose
|
|
8
9
|
@input = File.open(file)
|
|
9
|
-
@output = verbose ?
|
|
10
|
-
@error =
|
|
10
|
+
@output = verbose ? $stdout : StringIO.new
|
|
11
|
+
@error = $stderr
|
|
11
12
|
end
|
|
12
13
|
|
|
13
14
|
def read_command(prompt)
|
|
@@ -20,7 +21,7 @@ module Byebug
|
|
|
20
21
|
|
|
21
22
|
def readline(*)
|
|
22
23
|
while (result = input.gets)
|
|
23
|
-
output.puts "+ #{result}"
|
|
24
|
+
output.puts "+ #{result}" if @verbose
|
|
24
25
|
next if result =~ /^\s*#/
|
|
25
26
|
return result.chomp
|
|
26
27
|
end
|
data/lib/byebug/printers/base.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
require 'yaml'
|
|
3
4
|
|
|
4
5
|
module Byebug
|
|
@@ -61,7 +62,7 @@ module Byebug
|
|
|
61
62
|
end
|
|
62
63
|
|
|
63
64
|
def contents_files
|
|
64
|
-
[File.
|
|
65
|
+
[File.join(__dir__, 'texts', 'base.yml')]
|
|
65
66
|
end
|
|
66
67
|
end
|
|
67
68
|
end
|
|
@@ -16,6 +16,8 @@ break:
|
|
|
16
16
|
not_changed: "Incorrect expression \"{expr}\", breakpoint not changed"
|
|
17
17
|
confirmations:
|
|
18
18
|
delete_all: "Delete all breakpoints?"
|
|
19
|
+
messages:
|
|
20
|
+
breakpoint_deleted: "Deleted breakpoint {pos}"
|
|
19
21
|
|
|
20
22
|
catch:
|
|
21
23
|
added: "Catching exception {exception}."
|
|
@@ -97,6 +99,8 @@ toggle:
|
|
|
97
99
|
no_display: "No display expressions have been set"
|
|
98
100
|
syntax: "\"{toggle}\" must be followed by \"display\", \"breakpoints\" or breakpoint ids"
|
|
99
101
|
expression: "Expression \"{expr}\" syntactically incorrect; breakpoint remains disabled."
|
|
102
|
+
messages:
|
|
103
|
+
toggled: "Breakpoint {bpnum} {endis}abled"
|
|
100
104
|
|
|
101
105
|
parse:
|
|
102
106
|
errors:
|
|
@@ -109,21 +109,6 @@ module Byebug
|
|
|
109
109
|
'(byebug) '
|
|
110
110
|
end
|
|
111
111
|
|
|
112
|
-
private
|
|
113
|
-
|
|
114
|
-
def auto_cmds_for(run_level)
|
|
115
|
-
command_list.select { |cmd| cmd.always_run >= run_level }
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
#
|
|
119
|
-
# Run permanent commands.
|
|
120
|
-
#
|
|
121
|
-
def run_auto_cmds(run_level)
|
|
122
|
-
safely do
|
|
123
|
-
auto_cmds_for(run_level).each { |cmd| cmd.new(self).execute }
|
|
124
|
-
end
|
|
125
|
-
end
|
|
126
|
-
|
|
127
112
|
def before_repl
|
|
128
113
|
@proceed = false
|
|
129
114
|
@prev_line = nil
|
|
@@ -150,6 +135,21 @@ module Byebug
|
|
|
150
135
|
end
|
|
151
136
|
end
|
|
152
137
|
|
|
138
|
+
private
|
|
139
|
+
|
|
140
|
+
def auto_cmds_for(run_level)
|
|
141
|
+
command_list.select { |cmd| cmd.always_run >= run_level }
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
#
|
|
145
|
+
# Run permanent commands.
|
|
146
|
+
#
|
|
147
|
+
def run_auto_cmds(run_level)
|
|
148
|
+
safely do
|
|
149
|
+
auto_cmds_for(run_level).each { |cmd| cmd.new(self).execute }
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
153
|
#
|
|
154
154
|
# Executes the received input
|
|
155
155
|
#
|
|
@@ -12,25 +12,19 @@ module Byebug
|
|
|
12
12
|
super.select(&:allow_in_control)
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
def
|
|
15
|
+
def repl
|
|
16
16
|
while (input = interface.read_command(prompt))
|
|
17
|
-
|
|
17
|
+
safely do
|
|
18
|
+
command = command_list.match(input)
|
|
19
|
+
raise CommandNotFound.new(input) unless command
|
|
18
20
|
|
|
19
|
-
if command
|
|
20
21
|
command.new(self, input).execute
|
|
21
|
-
else
|
|
22
|
-
errmsg('Unknown command')
|
|
23
22
|
end
|
|
24
23
|
end
|
|
24
|
+
end
|
|
25
25
|
|
|
26
|
+
def after_repl
|
|
26
27
|
interface.close
|
|
27
|
-
rescue IOError, SystemCallError
|
|
28
|
-
interface.close
|
|
29
|
-
rescue
|
|
30
|
-
without_exceptions do
|
|
31
|
-
puts "INTERNAL ERROR!!! #{$ERROR_INFO}"
|
|
32
|
-
puts $ERROR_INFO.backtrace.map { |l| " #{l}" }.join("\n")
|
|
33
|
-
end
|
|
34
28
|
end
|
|
35
29
|
|
|
36
30
|
#
|
data/lib/byebug/remote.rb
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
require 'socket'
|
|
2
|
+
require 'byebug/processors/control_processor'
|
|
2
3
|
|
|
3
4
|
#
|
|
4
5
|
# Remote debugging functionality.
|
|
5
6
|
#
|
|
6
|
-
#
|
|
7
|
+
# @todo Refactor & add tests
|
|
7
8
|
#
|
|
8
9
|
module Byebug
|
|
9
10
|
# Port number used for remote debugging
|
|
@@ -33,9 +34,7 @@ module Byebug
|
|
|
33
34
|
Context.interface = nil
|
|
34
35
|
start
|
|
35
36
|
|
|
36
|
-
start_control(host, port
|
|
37
|
-
|
|
38
|
-
yield if block_given?
|
|
37
|
+
start_control(host, port.zero? ? 0 : port + 1)
|
|
39
38
|
|
|
40
39
|
mutex = Mutex.new
|
|
41
40
|
proceed = ConditionVariable.new
|
|
@@ -43,6 +42,8 @@ module Byebug
|
|
|
43
42
|
server = TCPServer.new(host, port)
|
|
44
43
|
self.actual_port = server.addr[1]
|
|
45
44
|
|
|
45
|
+
yield if block_given?
|
|
46
|
+
|
|
46
47
|
@thread = DebugThread.new do
|
|
47
48
|
while (session = server.accept)
|
|
48
49
|
Context.interface = RemoteInterface.new(session)
|
|
@@ -73,27 +74,26 @@ module Byebug
|
|
|
73
74
|
# Connects to the remote byebug
|
|
74
75
|
#
|
|
75
76
|
def start_client(host = 'localhost', port = PORT)
|
|
76
|
-
|
|
77
|
+
interface = LocalInterface.new
|
|
77
78
|
puts 'Connecting to byebug server...'
|
|
78
79
|
socket = TCPSocket.new(host, port)
|
|
79
80
|
puts 'Connected.'
|
|
80
81
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
puts line
|
|
94
|
-
end
|
|
82
|
+
while (line = socket.gets)
|
|
83
|
+
case line
|
|
84
|
+
when /^PROMPT (.*)$/
|
|
85
|
+
input = interface.read_command(Regexp.last_match[1])
|
|
86
|
+
break unless input
|
|
87
|
+
socket.puts input
|
|
88
|
+
when /^CONFIRM (.*)$/
|
|
89
|
+
input = interface.readline(Regexp.last_match[1])
|
|
90
|
+
break unless input
|
|
91
|
+
socket.puts input
|
|
92
|
+
else
|
|
93
|
+
puts line
|
|
95
94
|
end
|
|
96
95
|
end
|
|
96
|
+
|
|
97
97
|
socket.close
|
|
98
98
|
end
|
|
99
99
|
|