byebug 2.3.1 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/README.md +3 -11
  4. data/Rakefile +10 -3
  5. data/bin/byebug +16 -2
  6. data/byebug.gemspec +1 -0
  7. data/ext/byebug/byebug.c +0 -54
  8. data/ext/byebug/byebug.h +3 -4
  9. data/ext/byebug/extconf.rb +1 -1
  10. data/lib/byebug.rb +15 -42
  11. data/lib/byebug/command.rb +12 -28
  12. data/lib/byebug/commands/breakpoints.rb +2 -0
  13. data/lib/byebug/commands/catchpoint.rb +1 -1
  14. data/lib/byebug/commands/condition.rb +1 -0
  15. data/lib/byebug/commands/display.rb +6 -0
  16. data/lib/byebug/commands/frame.rb +10 -3
  17. data/lib/byebug/commands/info.rb +5 -3
  18. data/lib/byebug/commands/reload.rb +1 -0
  19. data/lib/byebug/commands/set.rb +5 -1
  20. data/lib/byebug/commands/threads.rb +5 -4
  21. data/lib/byebug/commands/trace.rb +5 -5
  22. data/lib/byebug/context.rb +3 -3
  23. data/lib/byebug/interface.rb +3 -187
  24. data/lib/byebug/interfaces/local_interface.rb +88 -0
  25. data/lib/byebug/interfaces/remote_interface.rb +55 -0
  26. data/lib/byebug/interfaces/script_interface.rb +45 -0
  27. data/lib/byebug/processor.rb +15 -13
  28. data/lib/byebug/version.rb +1 -1
  29. data/test/breakpoints_test.rb +23 -25
  30. data/test/conditions_test.rb +6 -8
  31. data/test/continue_test.rb +4 -6
  32. data/test/debugger_alias_test.rb +5 -0
  33. data/test/display_test.rb +9 -11
  34. data/test/edit_test.rb +0 -2
  35. data/test/eval_test.rb +1 -3
  36. data/test/finish_test.rb +12 -12
  37. data/test/frame_test.rb +38 -40
  38. data/test/help_test.rb +1 -3
  39. data/test/info_test.rb +12 -14
  40. data/test/kill_test.rb +0 -2
  41. data/test/list_test.rb +1 -3
  42. data/test/method_test.rb +0 -2
  43. data/test/post_mortem_test.rb +77 -96
  44. data/test/quit_test.rb +0 -2
  45. data/test/reload_test.rb +0 -2
  46. data/test/repl_test.rb +3 -5
  47. data/test/restart_test.rb +0 -2
  48. data/test/save_test.rb +1 -3
  49. data/test/set_test.rb +3 -5
  50. data/test/show_test.rb +0 -2
  51. data/test/source_test.rb +0 -2
  52. data/test/stepping_test.rb +17 -19
  53. data/test/support/test_dsl.rb +21 -13
  54. data/test/test_helper.rb +23 -1
  55. data/test/thread_test.rb +19 -21
  56. data/test/trace_test.rb +12 -14
  57. data/test/variables_test.rb +6 -6
  58. 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
- errmsg "Byebug's stacksize (#{calcedsize}) should be #{realsize}. " \
106
- "This might be a bug in byebug or ruby's debugging API's\n"
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...realsize).each do |idx|
115
+ (0...stacksize).each do |idx|
109
116
  print_frame(idx)
110
117
  end
111
118
  end
@@ -240,9 +240,11 @@ module Byebug
240
240
  private :info_stop_reason
241
241
 
242
242
  def info_program(*args)
243
- return print "The program crashed.\n" + Byebug.last_exception ?
244
- "Exception: #{Byebug.last_exception.inspect}" : "" + "\n" if
245
- @state.context.dead?
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
@@ -14,6 +14,7 @@ module Byebug
14
14
  # Implements byebug "reload" command.
15
15
  class ReloadCommand < Command
16
16
  self.allow_in_control = true
17
+ self.allow_in_post_mortem = false
17
18
 
18
19
  register_setting_get(:autoreload) do
19
20
  Byebug.class_variable_get(:@@autoreload)
@@ -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
- Byebug.post_mortem = setting_value
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 = @state.context.frame_file(0)
19
- line = @state.context.frame_line(0)
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.sort_by(&:thnum).each { |c| display_context(c) }
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 bb_eval("defined?(#{varname})")
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(:\"#{varname}\") do |val|
25
- print \"traced variable \#{varname} has value \#{val}\n\"
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: " \
@@ -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
- return 0
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
@@ -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
- class LocalInterface < Interface
33
- attr_accessor :command_queue, :history_length, :history_save, :histfile
34
- attr_accessor :restart_file
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