byebug 2.3.1 → 2.4.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 +15 -0
- data/README.md +3 -11
- data/Rakefile +10 -3
- data/bin/byebug +16 -2
- data/byebug.gemspec +1 -0
- data/ext/byebug/byebug.c +0 -54
- data/ext/byebug/byebug.h +3 -4
- data/ext/byebug/extconf.rb +1 -1
- data/lib/byebug.rb +15 -42
- data/lib/byebug/command.rb +12 -28
- data/lib/byebug/commands/breakpoints.rb +2 -0
- data/lib/byebug/commands/catchpoint.rb +1 -1
- data/lib/byebug/commands/condition.rb +1 -0
- data/lib/byebug/commands/display.rb +6 -0
- data/lib/byebug/commands/frame.rb +10 -3
- data/lib/byebug/commands/info.rb +5 -3
- data/lib/byebug/commands/reload.rb +1 -0
- data/lib/byebug/commands/set.rb +5 -1
- data/lib/byebug/commands/threads.rb +5 -4
- data/lib/byebug/commands/trace.rb +5 -5
- data/lib/byebug/context.rb +3 -3
- data/lib/byebug/interface.rb +3 -187
- data/lib/byebug/interfaces/local_interface.rb +88 -0
- data/lib/byebug/interfaces/remote_interface.rb +55 -0
- data/lib/byebug/interfaces/script_interface.rb +45 -0
- data/lib/byebug/processor.rb +15 -13
- data/lib/byebug/version.rb +1 -1
- data/test/breakpoints_test.rb +23 -25
- data/test/conditions_test.rb +6 -8
- data/test/continue_test.rb +4 -6
- data/test/debugger_alias_test.rb +5 -0
- data/test/display_test.rb +9 -11
- data/test/edit_test.rb +0 -2
- data/test/eval_test.rb +1 -3
- data/test/finish_test.rb +12 -12
- data/test/frame_test.rb +38 -40
- data/test/help_test.rb +1 -3
- data/test/info_test.rb +12 -14
- data/test/kill_test.rb +0 -2
- data/test/list_test.rb +1 -3
- data/test/method_test.rb +0 -2
- data/test/post_mortem_test.rb +77 -96
- data/test/quit_test.rb +0 -2
- data/test/reload_test.rb +0 -2
- data/test/repl_test.rb +3 -5
- data/test/restart_test.rb +0 -2
- data/test/save_test.rb +1 -3
- data/test/set_test.rb +3 -5
- data/test/show_test.rb +0 -2
- data/test/source_test.rb +0 -2
- data/test/stepping_test.rb +17 -19
- data/test/support/test_dsl.rb +21 -13
- data/test/test_helper.rb +23 -1
- data/test/thread_test.rb +19 -21
- data/test/trace_test.rb +12 -14
- data/test/variables_test.rb +6 -6
- metadata +22 -3
@@ -102,10 +102,17 @@ module Byebug
|
|
102
102
|
realsize = Context.stack_size
|
103
103
|
calcedsize = @state.context.calced_stack_size
|
104
104
|
if calcedsize != realsize
|
105
|
-
|
106
|
-
|
105
|
+
if Byebug.post_mortem?
|
106
|
+
stacksize = calcedsize
|
107
|
+
else
|
108
|
+
errmsg "Byebug's stacksize (#{calcedsize}) should be #{realsize}. " \
|
109
|
+
"This might be a bug in byebug or ruby's debugging API's\n"
|
110
|
+
stacksize = realsize
|
111
|
+
end
|
112
|
+
else
|
113
|
+
stacksize = calcedsize
|
107
114
|
end
|
108
|
-
(0...
|
115
|
+
(0...stacksize).each do |idx|
|
109
116
|
print_frame(idx)
|
110
117
|
end
|
111
118
|
end
|
data/lib/byebug/commands/info.rb
CHANGED
@@ -240,9 +240,11 @@ module Byebug
|
|
240
240
|
private :info_stop_reason
|
241
241
|
|
242
242
|
def info_program(*args)
|
243
|
-
|
244
|
-
|
245
|
-
|
243
|
+
if @state.context.dead?
|
244
|
+
print "The program crashed.\n"
|
245
|
+
print "Exception: #{Byebug.last_exception.inspect}\n" if Byebug.last_exception
|
246
|
+
return
|
247
|
+
end
|
246
248
|
|
247
249
|
print "Program stopped. "
|
248
250
|
info_stop_reason @state.context.stop_reason
|
data/lib/byebug/commands/set.rb
CHANGED
@@ -51,7 +51,11 @@ module Byebug
|
|
51
51
|
return unless width = get_int(setting_args[0], "Set width", 10, nil, 80)
|
52
52
|
Command.settings[:width] = width
|
53
53
|
when /^post_mortem$/
|
54
|
-
|
54
|
+
if setting_value == true
|
55
|
+
Byebug.post_mortem
|
56
|
+
else
|
57
|
+
return print 'Sorry... not implemented yet. Restart byebug'
|
58
|
+
end
|
55
59
|
when /^autoeval|autoreload|basename|forcestep|fullpath|linetrace_plus|
|
56
60
|
testing|stack_on_error$/x
|
57
61
|
Command.settings[setting_name.to_sym] = setting_value
|
@@ -14,9 +14,9 @@ module Byebug
|
|
14
14
|
end
|
15
15
|
debug_flag = context.ignored? ? '!' : ' '
|
16
16
|
if should_show_top_frame
|
17
|
-
if context.thread == Thread.current
|
18
|
-
file =
|
19
|
-
line =
|
17
|
+
if context.thread == Thread.current && !context.dead?
|
18
|
+
file = context.frame_file(0)
|
19
|
+
line = context.frame_line(0)
|
20
20
|
else
|
21
21
|
if context.thread.backtrace_locations &&
|
22
22
|
context.thread.backtrace_locations[0]
|
@@ -72,7 +72,8 @@ module Byebug
|
|
72
72
|
end
|
73
73
|
|
74
74
|
def execute
|
75
|
-
Byebug.contexts.
|
75
|
+
Byebug.contexts.select { |c| Thread.list.include?(c.thread) }
|
76
|
+
.sort_by(&:thnum).each { |c| display_context(c) }
|
76
77
|
end
|
77
78
|
|
78
79
|
class << self
|
@@ -15,19 +15,19 @@ module Byebug
|
|
15
15
|
print "#{show_setting('linetrace')}\n"
|
16
16
|
elsif @match[1] =~ /var(?:iable)?/
|
17
17
|
varname = @match[2]
|
18
|
-
if
|
18
|
+
if global_variables.include?("$#{varname}".to_sym)
|
19
19
|
if @match[3] && @match[3] !~ /(:?no)?stop/
|
20
20
|
errmsg "expecting \"stop\" or \"nostop\"; got \"#{@match[3]}\"\n"
|
21
21
|
else
|
22
22
|
dbg_cmd = (@match[3] && @match[3] !~ /nostop/) ? 'byebug(1,0)' : ''
|
23
23
|
end
|
24
|
-
eval("trace_var(:\"
|
25
|
-
print \"traced variable
|
24
|
+
eval("trace_var(:\"\$#{varname}\") do |val|
|
25
|
+
print \"traced global variable '#{varname}' has value '\#{val}'\"\n
|
26
26
|
#{dbg_cmd}
|
27
27
|
end")
|
28
|
-
print "Tracing variable \"#{varname}\".\n"
|
28
|
+
print "Tracing global variable \"#{varname}\".\n"
|
29
29
|
else
|
30
|
-
errmsg "#{varname} is not a global variable.\n"
|
30
|
+
errmsg "'#{varname}' is not a global variable.\n"
|
31
31
|
end
|
32
32
|
else
|
33
33
|
errmsg "expecting \"on\", \"off\", \"var\" or \"variable\"; got: " \
|
data/lib/byebug/context.rb
CHANGED
@@ -4,18 +4,18 @@ module Byebug
|
|
4
4
|
|
5
5
|
class << self
|
6
6
|
def stack_size
|
7
|
-
if backtrace = Thread.current.backtrace_locations
|
7
|
+
if backtrace = Thread.current.backtrace_locations(1)
|
8
8
|
backtrace.drop_while { |l| ignored(l.path) || l.path == '(eval)' }
|
9
9
|
.take_while { |l| !ignored(l.path) }
|
10
10
|
.size
|
11
11
|
else
|
12
12
|
print 'No backtrace available!!'
|
13
|
-
|
13
|
+
0
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
def real_stack_size
|
18
|
-
if backtrace = Thread.current.backtrace_locations
|
18
|
+
if backtrace = Thread.current.backtrace_locations(1)
|
19
19
|
backtrace.size
|
20
20
|
end
|
21
21
|
end
|
data/lib/byebug/interface.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
module Byebug
|
2
|
-
|
3
2
|
class Interface
|
4
3
|
attr_writer :have_readline
|
5
4
|
|
@@ -29,190 +28,7 @@ module Byebug
|
|
29
28
|
end
|
30
29
|
end
|
31
30
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
FILE_HISTORY = ".byebug_hist" unless defined?(FILE_HISTORY)
|
37
|
-
|
38
|
-
def initialize()
|
39
|
-
super
|
40
|
-
@command_queue = []
|
41
|
-
@have_readline = false
|
42
|
-
@history_save = true
|
43
|
-
@history_length = ENV["HISTSIZE"] ? ENV["HISTSIZE"].to_i : 256
|
44
|
-
@histfile = File.join(ENV["HOME"]||ENV["HOMEPATH"]||".", FILE_HISTORY)
|
45
|
-
open(@histfile, 'r') do |file|
|
46
|
-
file.each do |line|
|
47
|
-
line.chomp!
|
48
|
-
Readline::HISTORY << line
|
49
|
-
end
|
50
|
-
end if File.exist?(@histfile)
|
51
|
-
@restart_file = nil
|
52
|
-
end
|
53
|
-
|
54
|
-
def read_command(prompt)
|
55
|
-
readline(prompt, true)
|
56
|
-
end
|
57
|
-
|
58
|
-
def confirm(prompt)
|
59
|
-
readline(prompt, false)
|
60
|
-
end
|
61
|
-
|
62
|
-
def print(*args)
|
63
|
-
STDOUT.printf(escape(format(*args)))
|
64
|
-
end
|
65
|
-
|
66
|
-
def close
|
67
|
-
end
|
68
|
-
|
69
|
-
# Things to do before quitting
|
70
|
-
def finalize
|
71
|
-
if Byebug.respond_to?(:save_history)
|
72
|
-
Byebug.save_history
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
def readline_support?
|
77
|
-
@have_readline
|
78
|
-
end
|
79
|
-
|
80
|
-
private
|
81
|
-
|
82
|
-
begin
|
83
|
-
require 'readline'
|
84
|
-
class << Byebug
|
85
|
-
@have_readline = true
|
86
|
-
define_method(:save_history) do
|
87
|
-
iface = self.handler.interface
|
88
|
-
iface.histfile ||= File.join(ENV["HOME"]||ENV["HOMEPATH"]||".",
|
89
|
-
FILE_HISTORY)
|
90
|
-
open(iface.histfile, 'w') do |file|
|
91
|
-
Readline::HISTORY.to_a.last(iface.history_length).each do |line|
|
92
|
-
file.puts line unless line.strip.empty?
|
93
|
-
end if defined?(iface.history_save) and iface.history_save
|
94
|
-
end rescue nil
|
95
|
-
end
|
96
|
-
public :save_history
|
97
|
-
end
|
98
|
-
|
99
|
-
def readline(prompt, hist)
|
100
|
-
Readline::readline(prompt, hist)
|
101
|
-
rescue Interrupt
|
102
|
-
print "^C\n"
|
103
|
-
retry
|
104
|
-
end
|
105
|
-
rescue LoadError
|
106
|
-
def readline(prompt, hist)
|
107
|
-
@histfile = ''
|
108
|
-
@hist_save = false
|
109
|
-
STDOUT.print prompt
|
110
|
-
STDOUT.flush
|
111
|
-
line = STDIN.gets
|
112
|
-
exit unless line
|
113
|
-
line.chomp!
|
114
|
-
line
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
class RemoteInterface < Interface
|
120
|
-
attr_accessor :command_queue, :history_length, :history_save, :histfile
|
121
|
-
attr_accessor :restart_file
|
122
|
-
|
123
|
-
def initialize(socket)
|
124
|
-
@command_queue = []
|
125
|
-
@socket = socket
|
126
|
-
@history_save = false
|
127
|
-
@history_length = 256
|
128
|
-
@histfile = ''
|
129
|
-
# Do we read the histfile?
|
130
|
-
# open(@histfile, 'r') do |file|
|
131
|
-
# file.each do |line|
|
132
|
-
# line.chomp!
|
133
|
-
# Readline::HISTORY << line
|
134
|
-
# end
|
135
|
-
# end if File.exist?(@histfile)
|
136
|
-
@restart_file = nil
|
137
|
-
end
|
138
|
-
|
139
|
-
def close
|
140
|
-
@socket.close
|
141
|
-
rescue Exception
|
142
|
-
end
|
143
|
-
|
144
|
-
def confirm(prompt)
|
145
|
-
send_command "CONFIRM #{prompt}"
|
146
|
-
end
|
147
|
-
|
148
|
-
def finalize
|
149
|
-
end
|
150
|
-
|
151
|
-
def read_command(prompt)
|
152
|
-
send_command "PROMPT #{prompt}"
|
153
|
-
end
|
154
|
-
|
155
|
-
def readline_support?
|
156
|
-
false
|
157
|
-
end
|
158
|
-
|
159
|
-
def print(*args)
|
160
|
-
@socket.printf(escape(format(*args)))
|
161
|
-
end
|
162
|
-
|
163
|
-
private
|
164
|
-
|
165
|
-
def send_command(msg)
|
166
|
-
@socket.puts msg
|
167
|
-
result = @socket.gets
|
168
|
-
raise IOError unless result
|
169
|
-
result.chomp
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
class ScriptInterface < Interface
|
174
|
-
attr_accessor :command_queue, :history_length, :history_save, :histfile
|
175
|
-
attr_accessor :restart_file
|
176
|
-
|
177
|
-
def initialize(file, out, verbose=false)
|
178
|
-
super()
|
179
|
-
@command_queue = []
|
180
|
-
@file = file.respond_to?(:gets) ? file : open(file)
|
181
|
-
@out = out
|
182
|
-
@verbose = verbose
|
183
|
-
@history_save = false
|
184
|
-
@history_length = 256
|
185
|
-
@histfile = ''
|
186
|
-
end
|
187
|
-
|
188
|
-
def finalize
|
189
|
-
end
|
190
|
-
|
191
|
-
def read_command(prompt)
|
192
|
-
while result = @file.gets
|
193
|
-
puts "# #{result}" if @verbose
|
194
|
-
next if result =~ /^\s*#/
|
195
|
-
next if result.strip.empty?
|
196
|
-
break
|
197
|
-
end
|
198
|
-
raise IOError unless result
|
199
|
-
result.chomp!
|
200
|
-
end
|
201
|
-
|
202
|
-
def readline_support?
|
203
|
-
false
|
204
|
-
end
|
205
|
-
|
206
|
-
def confirm(prompt)
|
207
|
-
'y'
|
208
|
-
end
|
209
|
-
|
210
|
-
def print(*args)
|
211
|
-
@out.printf(*args)
|
212
|
-
end
|
213
|
-
|
214
|
-
def close
|
215
|
-
@file.close
|
216
|
-
end
|
217
|
-
end
|
31
|
+
require_relative 'interfaces/local_interface'
|
32
|
+
require_relative 'interfaces/script_interface'
|
33
|
+
require_relative 'interfaces/remote_interface'
|
218
34
|
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Byebug
|
2
|
+
class LocalInterface < Interface
|
3
|
+
attr_accessor :command_queue, :history_length, :history_save, :histfile
|
4
|
+
attr_accessor :restart_file
|
5
|
+
|
6
|
+
FILE_HISTORY = ".byebug_hist" unless defined?(FILE_HISTORY)
|
7
|
+
|
8
|
+
def initialize()
|
9
|
+
super
|
10
|
+
@command_queue = []
|
11
|
+
@have_readline = false
|
12
|
+
@history_save = true
|
13
|
+
@history_length = ENV["HISTSIZE"] ? ENV["HISTSIZE"].to_i : 256
|
14
|
+
@histfile = File.join(ENV["HOME"]||ENV["HOMEPATH"]||".", FILE_HISTORY)
|
15
|
+
open(@histfile, 'r') do |file|
|
16
|
+
file.each do |line|
|
17
|
+
line.chomp!
|
18
|
+
Readline::HISTORY << line
|
19
|
+
end
|
20
|
+
end if File.exist?(@histfile)
|
21
|
+
@restart_file = nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def read_command(prompt)
|
25
|
+
readline(prompt, true)
|
26
|
+
end
|
27
|
+
|
28
|
+
def confirm(prompt)
|
29
|
+
readline(prompt, false)
|
30
|
+
end
|
31
|
+
|
32
|
+
def print(*args)
|
33
|
+
STDOUT.printf(escape(format(*args)))
|
34
|
+
end
|
35
|
+
|
36
|
+
def close
|
37
|
+
end
|
38
|
+
|
39
|
+
# Things to do before quitting
|
40
|
+
def finalize
|
41
|
+
if Byebug.respond_to?(:save_history)
|
42
|
+
Byebug.save_history
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def readline_support?
|
47
|
+
@have_readline
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
begin
|
53
|
+
require 'readline'
|
54
|
+
class << Byebug
|
55
|
+
@have_readline = true
|
56
|
+
define_method(:save_history) do
|
57
|
+
iface = self.handler.interface
|
58
|
+
iface.histfile ||= File.join(ENV["HOME"]||ENV["HOMEPATH"]||".",
|
59
|
+
FILE_HISTORY)
|
60
|
+
open(iface.histfile, 'w') do |file|
|
61
|
+
Readline::HISTORY.to_a.last(iface.history_length).each do |line|
|
62
|
+
file.puts line unless line.strip.empty?
|
63
|
+
end if defined?(iface.history_save) and iface.history_save
|
64
|
+
end rescue nil
|
65
|
+
end
|
66
|
+
public :save_history
|
67
|
+
end
|
68
|
+
|
69
|
+
def readline(prompt, hist)
|
70
|
+
Readline::readline(prompt, hist)
|
71
|
+
rescue Interrupt
|
72
|
+
print "^C\n"
|
73
|
+
retry
|
74
|
+
end
|
75
|
+
rescue LoadError
|
76
|
+
def readline(prompt, hist)
|
77
|
+
@histfile = ''
|
78
|
+
@hist_save = false
|
79
|
+
STDOUT.print prompt
|
80
|
+
STDOUT.flush
|
81
|
+
line = STDIN.gets
|
82
|
+
exit unless line
|
83
|
+
line.chomp!
|
84
|
+
line
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Byebug
|
2
|
+
class RemoteInterface < Interface
|
3
|
+
attr_accessor :command_queue, :history_length, :history_save, :histfile
|
4
|
+
attr_accessor :restart_file
|
5
|
+
|
6
|
+
def initialize(socket)
|
7
|
+
@command_queue = []
|
8
|
+
@socket = socket
|
9
|
+
@history_save = false
|
10
|
+
@history_length = 256
|
11
|
+
@histfile = ''
|
12
|
+
# Do we read the histfile?
|
13
|
+
# open(@histfile, 'r') do |file|
|
14
|
+
# file.each do |line|
|
15
|
+
# line.chomp!
|
16
|
+
# Readline::HISTORY << line
|
17
|
+
# end
|
18
|
+
# end if File.exist?(@histfile)
|
19
|
+
@restart_file = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def close
|
23
|
+
@socket.close
|
24
|
+
rescue Exception
|
25
|
+
end
|
26
|
+
|
27
|
+
def confirm(prompt)
|
28
|
+
send_command "CONFIRM #{prompt}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def finalize
|
32
|
+
end
|
33
|
+
|
34
|
+
def read_command(prompt)
|
35
|
+
send_command "PROMPT #{prompt}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def readline_support?
|
39
|
+
false
|
40
|
+
end
|
41
|
+
|
42
|
+
def print(*args)
|
43
|
+
@socket.printf(escape(format(*args)))
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def send_command(msg)
|
49
|
+
@socket.puts msg
|
50
|
+
result = @socket.gets
|
51
|
+
raise IOError unless result
|
52
|
+
result.chomp
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|