byebug 2.3.1 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|