byebug 3.2.0 → 3.3.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/.rubocop.yml +3 -0
- data/CHANGELOG.md +125 -99
- data/CONTRIBUTING.md +4 -6
- data/GUIDE.md +42 -20
- data/Gemfile +5 -3
- data/README.md +2 -3
- data/Rakefile +11 -7
- data/bin/byebug +2 -252
- data/byebug.gemspec +7 -4
- data/ext/byebug/byebug.c +17 -18
- data/ext/byebug/byebug.h +4 -5
- data/ext/byebug/context.c +37 -39
- data/ext/byebug/threads.c +39 -18
- data/lib/byebug.rb +2 -110
- data/lib/byebug/attacher.rb +23 -0
- data/lib/byebug/breakpoint.rb +60 -0
- data/lib/byebug/command.rb +62 -70
- data/lib/byebug/commands/break.rb +24 -24
- data/lib/byebug/commands/catchpoint.rb +18 -10
- data/lib/byebug/commands/condition.rb +18 -17
- data/lib/byebug/commands/continue.rb +17 -9
- data/lib/byebug/commands/delete.rb +19 -13
- data/lib/byebug/commands/display.rb +19 -53
- data/lib/byebug/commands/edit.rb +7 -4
- data/lib/byebug/commands/enable_disable.rb +130 -0
- data/lib/byebug/commands/eval.rb +40 -22
- data/lib/byebug/commands/finish.rb +13 -4
- data/lib/byebug/commands/frame.rb +65 -45
- data/lib/byebug/commands/help.rb +17 -18
- data/lib/byebug/commands/history.rb +14 -8
- data/lib/byebug/commands/info.rb +160 -182
- data/lib/byebug/commands/interrupt.rb +4 -1
- data/lib/byebug/commands/irb.rb +30 -0
- data/lib/byebug/commands/kill.rb +7 -8
- data/lib/byebug/commands/list.rb +71 -66
- data/lib/byebug/commands/method.rb +14 -6
- data/lib/byebug/commands/pry.rb +35 -0
- data/lib/byebug/commands/quit.rb +9 -6
- data/lib/byebug/commands/reload.rb +5 -2
- data/lib/byebug/commands/restart.rb +13 -9
- data/lib/byebug/commands/save.rb +17 -17
- data/lib/byebug/commands/set.rb +16 -15
- data/lib/byebug/commands/show.rb +10 -11
- data/lib/byebug/commands/source.rb +11 -5
- data/lib/byebug/commands/stepping.rb +38 -24
- data/lib/byebug/commands/threads.rb +45 -31
- data/lib/byebug/commands/trace.rb +22 -9
- data/lib/byebug/commands/undisplay.rb +45 -0
- data/lib/byebug/commands/variables.rb +83 -27
- data/lib/byebug/context.rb +25 -22
- data/lib/byebug/core.rb +82 -0
- data/lib/byebug/helper.rb +37 -28
- data/lib/byebug/history.rb +8 -4
- data/lib/byebug/interface.rb +12 -17
- data/lib/byebug/interfaces/local_interface.rb +11 -8
- data/lib/byebug/interfaces/remote_interface.rb +11 -8
- data/lib/byebug/interfaces/script_interface.rb +9 -6
- data/lib/byebug/options.rb +46 -0
- data/lib/byebug/processor.rb +7 -1
- data/lib/byebug/processors/command_processor.rb +135 -125
- data/lib/byebug/processors/control_command_processor.rb +23 -23
- data/lib/byebug/remote.rb +17 -26
- data/lib/byebug/runner.rb +100 -0
- data/lib/byebug/setting.rb +33 -8
- data/lib/byebug/settings/autoeval.rb +5 -15
- data/lib/byebug/settings/autoirb.rb +4 -1
- data/lib/byebug/settings/autolist.rb +5 -2
- data/lib/byebug/settings/autoreload.rb +5 -2
- data/lib/byebug/settings/autosave.rb +6 -2
- data/lib/byebug/settings/basename.rb +7 -2
- data/lib/byebug/settings/callstyle.rb +4 -1
- data/lib/byebug/settings/forcestep.rb +6 -3
- data/lib/byebug/settings/fullpath.rb +5 -2
- data/lib/byebug/settings/histfile.rb +5 -3
- data/lib/byebug/settings/histsize.rb +5 -3
- data/lib/byebug/settings/linetrace.rb +4 -1
- data/lib/byebug/settings/listsize.rb +5 -1
- data/lib/byebug/settings/post_mortem.rb +21 -13
- data/lib/byebug/settings/stack_on_error.rb +6 -2
- data/lib/byebug/settings/testing.rb +6 -1
- data/lib/byebug/settings/tracing_plus.rb +5 -1
- data/lib/byebug/settings/verbose.rb +13 -2
- data/lib/byebug/settings/width.rb +4 -1
- data/lib/byebug/version.rb +1 -1
- data/test/{break_test.rb → commands/break_test.rb} +41 -53
- data/test/{condition_test.rb → commands/condition_test.rb} +14 -14
- data/test/{continue_test.rb → commands/continue_test.rb} +0 -0
- data/test/{delete_test.rb → commands/delete_test.rb} +2 -2
- data/test/commands/display_test.rb +37 -0
- data/test/{edit_test.rb → commands/edit_test.rb} +0 -0
- data/test/{eval_test.rb → commands/eval_test.rb} +1 -0
- data/test/{finish_test.rb → commands/finish_test.rb} +11 -1
- data/test/{frame_test.rb → commands/frame_test.rb} +12 -16
- data/test/{help_test.rb → commands/help_test.rb} +21 -4
- data/test/{history_test.rb → commands/history_test.rb} +0 -0
- data/test/{info_test.rb → commands/info_test.rb} +5 -55
- data/test/{interrupt_test.rb → commands/interrupt_test.rb} +0 -0
- data/test/commands/irb_test.rb +28 -0
- data/test/{kill_test.rb → commands/kill_test.rb} +1 -1
- data/test/{list_test.rb → commands/list_test.rb} +1 -1
- data/test/{method_test.rb → commands/method_test.rb} +0 -0
- data/test/{post_mortem_test.rb → commands/post_mortem_test.rb} +6 -10
- data/test/{pry_test.rb → commands/pry_test.rb} +4 -13
- data/test/{quit_test.rb → commands/quit_test.rb} +4 -4
- data/test/{reload_test.rb → commands/reload_test.rb} +0 -0
- data/test/{restart_test.rb → commands/restart_test.rb} +6 -0
- data/test/{save_test.rb → commands/save_test.rb} +2 -2
- data/test/{set_test.rb → commands/set_test.rb} +9 -2
- data/test/{show_test.rb → commands/show_test.rb} +1 -1
- data/test/{source_test.rb → commands/source_test.rb} +3 -3
- data/test/{stepping_test.rb → commands/stepping_test.rb} +44 -35
- data/test/{thread_test.rb → commands/thread_test.rb} +0 -0
- data/test/{trace_test.rb → commands/trace_test.rb} +0 -0
- data/test/{display_test.rb → commands/undisplay_test.rb} +7 -45
- data/test/{variables_test.rb → commands/variables_test.rb} +10 -1
- data/test/debugger_alias_test.rb +2 -2
- data/test/runner_test.rb +127 -0
- data/test/support/matchers.rb +27 -25
- data/test/support/test_interface.rb +9 -5
- data/test/support/utils.rb +96 -101
- data/test/test_helper.rb +32 -20
- metadata +93 -68
- data/lib/byebug/commands/enable.rb +0 -154
- data/lib/byebug/commands/repl.rb +0 -126
- data/test/irb_test.rb +0 -47
- data/test/support/breakpoint.rb +0 -13
@@ -1,4 +1,7 @@
|
|
1
1
|
module Byebug
|
2
|
+
#
|
3
|
+
# Interrupting execution of current thread.
|
4
|
+
#
|
2
5
|
class InterruptCommand < Command
|
3
6
|
self.allow_in_control = true
|
4
7
|
self.allow_in_post_mortem = false
|
@@ -18,7 +21,7 @@ module Byebug
|
|
18
21
|
end
|
19
22
|
|
20
23
|
def description
|
21
|
-
%
|
24
|
+
%(i|nterrupt Interrupts the program.)
|
22
25
|
end
|
23
26
|
end
|
24
27
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'irb'
|
2
|
+
|
3
|
+
module Byebug
|
4
|
+
#
|
5
|
+
# Enter IRB from byebug's prompt
|
6
|
+
#
|
7
|
+
class IrbCommand < Command
|
8
|
+
def regexp
|
9
|
+
/^\s* irb \s*$/x
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute
|
13
|
+
unless @state.interface.is_a?(LocalInterface)
|
14
|
+
return errmsg('Command is available only in local mode.')
|
15
|
+
end
|
16
|
+
|
17
|
+
IRB.start(__FILE__)
|
18
|
+
end
|
19
|
+
|
20
|
+
class << self
|
21
|
+
def names
|
22
|
+
%w(irb)
|
23
|
+
end
|
24
|
+
|
25
|
+
def description
|
26
|
+
%{irb Starts an Interactive Ruby (IRB) session.}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/byebug/commands/kill.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
module Byebug
|
2
|
+
#
|
3
|
+
# Send custom signals to the debugged program.
|
4
|
+
#
|
2
5
|
class KillCommand < Command
|
3
6
|
self.allow_in_control = true
|
4
7
|
|
@@ -13,16 +16,12 @@ module Byebug
|
|
13
16
|
errmsg("signal name #{signame} is not a signal I know about\n")
|
14
17
|
return false
|
15
18
|
end
|
16
|
-
if 'KILL' == signame
|
17
|
-
@state.interface.close
|
18
|
-
end
|
19
|
+
@state.interface.close if 'KILL' == signame
|
19
20
|
else
|
20
|
-
|
21
|
-
|
22
|
-
else
|
23
|
-
signame = 'KILL'
|
24
|
-
end
|
21
|
+
return unless confirm('Really kill? (y/n) ')
|
22
|
+
signame = 'KILL'
|
25
23
|
end
|
24
|
+
|
26
25
|
Process.kill(signame, Process.pid)
|
27
26
|
end
|
28
27
|
|
data/lib/byebug/commands/list.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
module Byebug
|
2
|
+
#
|
3
|
+
# List parts of the source code.
|
4
|
+
#
|
2
5
|
class ListCommand < Command
|
3
6
|
def regexp
|
4
7
|
/^\s* l(?:ist)? (?:\s*([-=])|\s+(\S+))? \s*$/x
|
@@ -7,7 +10,8 @@ module Byebug
|
|
7
10
|
def execute
|
8
11
|
Byebug.source_reload if Setting[:autoreload]
|
9
12
|
|
10
|
-
|
13
|
+
lines = get_lines(@state.file)
|
14
|
+
unless lines
|
11
15
|
errmsg "No sourcefile available for #{@state.file}\n"
|
12
16
|
return @state.previous_line
|
13
17
|
end
|
@@ -15,7 +19,7 @@ module Byebug
|
|
15
19
|
b, e = set_line_range(Setting[:listsize], lines.size)
|
16
20
|
return @state.previous_line if b < 0
|
17
21
|
|
18
|
-
|
22
|
+
puts "\n[#{b}, #{e}] in #{@state.file}"
|
19
23
|
@state.previous_line = display_list(b, e, lines, @state.line)
|
20
24
|
end
|
21
25
|
|
@@ -25,84 +29,85 @@ module Byebug
|
|
25
29
|
end
|
26
30
|
|
27
31
|
def description
|
28
|
-
%
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
32
|
+
%(l[ist][[-=]][ nn-mm]
|
33
|
+
|
34
|
+
Lists lines of code forward from current line or from the place where
|
35
|
+
code was last listed. If "list-" is specified, lists backwards
|
36
|
+
instead. If "list=" is specified, lists from current line regardless
|
37
|
+
of where code was last listed. A line range can also be specified to
|
38
|
+
list specific sections of code.)
|
33
39
|
end
|
34
40
|
end
|
35
41
|
|
36
42
|
private
|
37
43
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
44
|
+
##
|
45
|
+
# Set line range to be printed by list
|
46
|
+
#
|
47
|
+
# @param listsize - number of lines to be printed
|
48
|
+
# @param maxline - max line number that can be printed
|
49
|
+
#
|
50
|
+
def set_line_range(listsize, maxline)
|
51
|
+
if !@match || !(@match[1] || @match[2])
|
52
|
+
b = if @state.previous_line
|
53
|
+
@state.previous_line + listsize
|
54
|
+
else
|
55
|
+
@state.line - (listsize / 2)
|
56
|
+
end
|
57
|
+
elsif @match[1] == '-'
|
58
|
+
b = if @state.previous_line
|
59
|
+
if @state.previous_line > 0
|
60
|
+
@state.previous_line - listsize
|
55
61
|
else
|
56
|
-
@state.
|
62
|
+
@state.previous_line
|
57
63
|
end
|
58
|
-
|
59
|
-
|
60
|
-
|
64
|
+
else
|
65
|
+
@state.line - (listsize / 2)
|
66
|
+
end
|
67
|
+
elsif @match[1] == '='
|
68
|
+
@state.previous_line = nil
|
69
|
+
b = @state.line - (listsize / 2)
|
70
|
+
else
|
71
|
+
b, e = @match[2].split(/[-,]/)
|
72
|
+
if e
|
73
|
+
b = b.to_i
|
74
|
+
e = e.to_i
|
61
75
|
else
|
62
|
-
b
|
63
|
-
if e
|
64
|
-
b = b.to_i
|
65
|
-
e = e.to_i
|
66
|
-
else
|
67
|
-
b = b.to_i - (listsize/2)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
if b > maxline
|
72
|
-
errmsg "Invalid line range"
|
73
|
-
return [ -1, -1 ]
|
76
|
+
b = b.to_i - (listsize / 2)
|
74
77
|
end
|
78
|
+
end
|
75
79
|
|
76
|
-
|
77
|
-
|
80
|
+
if b > maxline
|
81
|
+
errmsg 'Invalid line range'
|
82
|
+
return [-1, -1]
|
83
|
+
end
|
78
84
|
|
79
|
-
|
80
|
-
|
81
|
-
b = e - listsize + 1
|
82
|
-
b = [1, b].max
|
83
|
-
end
|
85
|
+
b = [1, b].max
|
86
|
+
e ||= b + listsize - 1
|
84
87
|
|
85
|
-
|
88
|
+
if e > maxline
|
89
|
+
e = maxline
|
90
|
+
b = e - listsize + 1
|
91
|
+
b = [1, b].max
|
86
92
|
end
|
87
93
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
end
|
104
|
-
print "\n"
|
105
|
-
return e == lines.size ? @state.previous_line : b
|
94
|
+
[b, e]
|
95
|
+
end
|
96
|
+
|
97
|
+
##
|
98
|
+
# Show file lines in LINES from line B to line E where CURRENT is the
|
99
|
+
# current line number. If we can show from B to E then we return B,
|
100
|
+
# otherwise we return the previous line @state.previous_line.
|
101
|
+
#
|
102
|
+
def display_list(b, e, lines, current)
|
103
|
+
width = e.to_s.size
|
104
|
+
b.upto(e) do |n|
|
105
|
+
next unless n > 0 && lines[n - 1]
|
106
|
+
line = n == current ? '=>' : ' '
|
107
|
+
line += format(" %#{width}d: %s", n, lines[n - 1].chomp)
|
108
|
+
puts(line)
|
106
109
|
end
|
110
|
+
e == lines.size ? @state.previous_line : b
|
111
|
+
end
|
107
112
|
end
|
108
113
|
end
|
@@ -1,4 +1,7 @@
|
|
1
1
|
module Byebug
|
2
|
+
#
|
3
|
+
# Show methods of specific classes/modules/objects.
|
4
|
+
#
|
2
5
|
class MethodCommand < Command
|
3
6
|
include Columnize
|
4
7
|
|
@@ -9,11 +12,11 @@ module Byebug
|
|
9
12
|
def execute
|
10
13
|
obj = bb_eval(@match.post_match)
|
11
14
|
if @match[1]
|
12
|
-
|
13
|
-
elsif !obj.
|
14
|
-
|
15
|
+
puts "#{columnize(obj.methods.sort, Setting[:width])}"
|
16
|
+
elsif !obj.is_a?(Module)
|
17
|
+
puts "Should be Class/Module: #{@match.post_match}"
|
15
18
|
else
|
16
|
-
|
19
|
+
puts "#{columnize(obj.instance_methods(false).sort, Setting[:width])}"
|
17
20
|
end
|
18
21
|
end
|
19
22
|
|
@@ -23,8 +26,13 @@ module Byebug
|
|
23
26
|
end
|
24
27
|
|
25
28
|
def description
|
26
|
-
%{m[ethod] i[nstance] <obj
|
27
|
-
|
29
|
+
%{m[ethod] (i[nstance][ <obj>]|<class|module>)
|
30
|
+
|
31
|
+
When invoked with "instance", shows instance methods of the object
|
32
|
+
specified as argument or of self no object was specified.
|
33
|
+
|
34
|
+
When invoked only with a class or module, shows class methods of the
|
35
|
+
class or module specified as argument.}
|
28
36
|
end
|
29
37
|
end
|
30
38
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
begin
|
2
|
+
require 'pry'
|
3
|
+
has_pry = true
|
4
|
+
rescue LoadError
|
5
|
+
has_pry = false
|
6
|
+
end
|
7
|
+
|
8
|
+
module Byebug
|
9
|
+
#
|
10
|
+
# Enter Pry from byebug's prompt
|
11
|
+
#
|
12
|
+
class PryCommand < Command
|
13
|
+
def regexp
|
14
|
+
/^\s* pry \s*$/x
|
15
|
+
end
|
16
|
+
|
17
|
+
def execute
|
18
|
+
unless @state.interface.is_a?(LocalInterface)
|
19
|
+
return errmsg('Command is available only in local mode.')
|
20
|
+
end
|
21
|
+
|
22
|
+
get_binding.pry
|
23
|
+
end
|
24
|
+
|
25
|
+
class << self
|
26
|
+
def names
|
27
|
+
%w(pry)
|
28
|
+
end
|
29
|
+
|
30
|
+
def description
|
31
|
+
%(pry Starts a Pry session.)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end if has_pry
|
data/lib/byebug/commands/quit.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
module Byebug
|
2
|
+
#
|
3
|
+
# Exit from byebug.
|
4
|
+
#
|
2
5
|
class QuitCommand < Command
|
3
6
|
self.allow_in_control = true
|
4
7
|
|
@@ -7,10 +10,10 @@ module Byebug
|
|
7
10
|
end
|
8
11
|
|
9
12
|
def execute
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
13
|
+
return unless @match[1] || confirm('Really quit? (y/n) ')
|
14
|
+
|
15
|
+
@state.interface.close
|
16
|
+
exit! # exit -> exit!: No graceful way to stop...
|
14
17
|
end
|
15
18
|
|
16
19
|
class << self
|
@@ -19,11 +22,11 @@ module Byebug
|
|
19
22
|
end
|
20
23
|
|
21
24
|
def description
|
22
|
-
%
|
25
|
+
%(q[uit]|exit [!|unconditionally] Exits from byebug.
|
23
26
|
|
24
27
|
Normally we prompt before exiting. However if the parameter
|
25
28
|
"unconditionally" is given or command is suffixed with !, we exit
|
26
|
-
without asking further questions.
|
29
|
+
without asking further questions.)
|
27
30
|
end
|
28
31
|
end
|
29
32
|
end
|
@@ -1,4 +1,7 @@
|
|
1
1
|
module Byebug
|
2
|
+
#
|
3
|
+
# Reload source code to pick up latest changes.
|
4
|
+
#
|
2
5
|
class ReloadCommand < Command
|
3
6
|
self.allow_in_control = true
|
4
7
|
self.allow_in_post_mortem = false
|
@@ -10,7 +13,7 @@ module Byebug
|
|
10
13
|
def execute
|
11
14
|
Byebug.source_reload
|
12
15
|
onoff = Setting[:autoreload] ? 'on' : 'off'
|
13
|
-
|
16
|
+
puts "Source code was reloaded. Automatic reloading is #{onoff}"
|
14
17
|
end
|
15
18
|
|
16
19
|
class << self
|
@@ -19,7 +22,7 @@ module Byebug
|
|
19
22
|
end
|
20
23
|
|
21
24
|
def description
|
22
|
-
%
|
25
|
+
%(r[eload] Forces source code reloading.)
|
23
26
|
end
|
24
27
|
end
|
25
28
|
end
|
@@ -1,4 +1,7 @@
|
|
1
1
|
module Byebug
|
2
|
+
#
|
3
|
+
# Restart debugged program from within byebug.
|
4
|
+
#
|
2
5
|
class RestartCommand < Command
|
3
6
|
self.allow_in_control = true
|
4
7
|
|
@@ -10,21 +13,22 @@ module Byebug
|
|
10
13
|
prog = PROG_SCRIPT if defined?(PROG_SCRIPT)
|
11
14
|
byebug_script = BYEBUG_SCRIPT if defined?(BYEBUG_SCRIPT)
|
12
15
|
|
13
|
-
return errmsg
|
16
|
+
return errmsg("Don't know name of debugged program") unless prog
|
14
17
|
|
15
18
|
unless File.exist?(File.expand_path(prog))
|
16
|
-
return errmsg
|
19
|
+
return errmsg("Ruby program #{prog} doesn't exist")
|
17
20
|
end
|
18
21
|
|
19
22
|
if byebug_script
|
20
23
|
cmd = "#{byebug_script} #{prog}"
|
21
24
|
else
|
22
|
-
|
25
|
+
puts 'Byebug was not called from the outset...'
|
23
26
|
if File.executable?(prog)
|
24
27
|
cmd = prog
|
25
28
|
else
|
26
|
-
|
27
|
-
|
29
|
+
puts "Ruby program #{prog} not executable... " \
|
30
|
+
"We'll wrap it in a ruby call"
|
31
|
+
cmd = "ruby -rbyebug -I#{$LOAD_PATH.join(' -I')} #{prog}"
|
28
32
|
end
|
29
33
|
end
|
30
34
|
|
@@ -36,10 +40,10 @@ module Byebug
|
|
36
40
|
end
|
37
41
|
|
38
42
|
# An execv would be preferable to the "exec" below.
|
39
|
-
|
43
|
+
puts "Re exec'ing:\n\t#{cmd}"
|
40
44
|
exec cmd
|
41
45
|
rescue Errno::EOPNOTSUPP
|
42
|
-
|
46
|
+
puts 'Restart command is not available at this time.'
|
43
47
|
end
|
44
48
|
|
45
49
|
class << self
|
@@ -48,10 +52,10 @@ module Byebug
|
|
48
52
|
end
|
49
53
|
|
50
54
|
def description
|
51
|
-
%
|
55
|
+
%(restart|R [args]
|
52
56
|
|
53
57
|
Restart the program. This is a re-exec - all byebug state
|
54
|
-
is lost. If command arguments are passed those are used.
|
58
|
+
is lost. If command arguments are passed those are used.)
|
55
59
|
end
|
56
60
|
end
|
57
61
|
end
|