byebug 2.5.0 → 2.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8dee4a41cee3ad39319608f90aa34ca73e6b3578
4
- data.tar.gz: e2434363c37285a549aaabbd236dd7c832f460e8
3
+ metadata.gz: d0bd29ed7fa0a4c5e980c3f90ea5187a0723d1ea
4
+ data.tar.gz: 177807eb3c0b4b5bf8befb1e196457dc7fbd89ad
5
5
  SHA512:
6
- metadata.gz: f2967314e28007dc029dca83fff42fad6b494483a4e14ebc6ffa4aa2f3b2433797cc113fb1f575db2cb52b7f14656dd047fef1f07550f3e772a68ffc2eb7da99
7
- data.tar.gz: f8c59999bfc524f43d8b925a092f7a26831b173b85d4c1d3ab80448be02bbb95707bc9ec7e82b1cba63851c089c7fd61e9a4224c9a92c4b469a263e21f10e81d
6
+ metadata.gz: 379441b4bb0d2ab10d3a547757f0c3921e2043cda11883c2449243d747bb17d5cc4c81093d6f476225801fe1d41494285bf5953f642458e581673f0bc77682c4
7
+ data.tar.gz: 9401628eaeae78d332c03bf97d2c2e61093b79cf7bb73b23fe3658130126f6ff3321eee3c4da141340f5e387a87f93b6b08f1f149bdd6aa0cc70a4fcd63e26f7
@@ -1,6 +1,7 @@
1
- before_script: rake compile
1
+ before_script: bundle exec rake compile
2
2
  rvm:
3
3
  - 2.0.0
4
+ - 2.1.0
4
5
  - ruby-head
5
6
  matrix:
6
7
  allow_failures:
@@ -1,3 +1,8 @@
1
+ # 2.6.0
2
+
3
+ * Fix circular dependency that was affecting `pry-byebug`, thanks @andreychernih
4
+
5
+
1
6
  # 2.5.0
2
7
 
3
8
  * Support for `sublime-debugger`
data/README.md CHANGED
@@ -1,7 +1,10 @@
1
- # Byebug [![Gem Version][1]][2] [![Build Status][3]][4] [![Code Climate][5]][6] [![Dependency Status][7]][8]
2
-
3
- <img src="https://raw.github.com/deivid-rodriguez/byebug/master/logo.png"
4
- alt="Byebug logo" align="right" style="margin-left: 10px" />
1
+ # Byebug
2
+ [![Version][VersionBadge]][VersionURL]
3
+ [![Build][TravisBadge]][TravisURL]
4
+ [![Climate][CodeClimateBadge]][CodeClimateURL]
5
+ [![Dependencies][GemnasiumBadge]][GemnasiumURL]
6
+ [![Coverage][CoverallsBadge]][CoverallsURL]
7
+ [![Gittip][GittipBadge]][GittipURL]
5
8
 
6
9
  _Debugging in Ruby 2_
7
10
 
@@ -148,14 +151,17 @@ software, specially:
148
151
  * Koichi Sasada, author of the new C debugging API for Ruby.
149
152
  * Dennis Ushakov, author of [debase](https://github.com/denofevil/debase), the
150
153
  starting point of this.
151
- * Logo by [Ivlichev Victor Petrovich](http://www.aha-soft.com/)
152
154
  * @kevjames3 for testing, bug reports and the interest in the project.
153
155
 
154
- [1]: https://badge.fury.io/rb/byebug.png
155
- [2]: http://badge.fury.io/rb/byebug
156
- [3]: https://secure.travis-ci.org/deivid-rodriguez/byebug.png
157
- [4]: http://travis-ci.org/deivid-rodriguez/byebug
158
- [5]: https://codeclimate.com/github/deivid-rodriguez/byebug.png
159
- [6]: https://codeclimate.com/github/deivid-rodriguez/byebug
160
- [7]: https://gemnasium.com/deivid-rodriguez/byebug.png
161
- [8]: https://gemnasium.com/deivid-rodriguez/byebug
156
+ [VersionBadge]: https://badge.fury.io/rb/byebug.png
157
+ [VersionURL]: http://badge.fury.io/rb/byebug
158
+ [TravisBadge]: https://travis-ci.org/deivid-rodriguez/byebug.png
159
+ [TravisURL]: http://travis-ci.org/deivid-rodriguez/byebug
160
+ [CodeClimateBadge]: https://codeclimate.com/github/deivid-rodriguez/byebug.png
161
+ [CodeClimateURL]: https://codeclimate.com/github/deivid-rodriguez/byebug
162
+ [GemnasiumBadge]: https://gemnasium.com/deivid-rodriguez/byebug.png
163
+ [GemnasiumURL]: https://gemnasium.com/deivid-rodriguez/byebug
164
+ [CoverallsBadge]: https://coveralls.io/repos/deivid-rodriguez/byebug/badge.png
165
+ [CoverallsURL]: https://coveralls.io/r/deivid-rodriguez/byebug
166
+ [GittipBadge]: http://img.shields.io/gittip/deivid-rodriguez.png
167
+ [GittipURL]: https://www.gittip.com/deivid-rodriguez
@@ -23,11 +23,12 @@ Gem::Specification.new do |s|
23
23
  s.extra_rdoc_files = ['README.md']
24
24
  s.extensions = ['ext/byebug/extconf.rb']
25
25
 
26
- s.add_dependency "columnize", "~> 0.3.6"
27
- s.add_dependency "debugger-linecache", '~> 1.2.0'
26
+ s.add_dependency 'columnize', '~> 0.3'
27
+ s.add_dependency 'debugger-linecache', '~> 1.2'
28
28
 
29
- s.add_development_dependency 'rake', '~> 10.1.0'
30
- s.add_development_dependency 'rake-compiler', '~> 0.9.2'
31
- s.add_development_dependency 'mocha', '~> 0.14.0'
32
- s.add_development_dependency 'minitest', '~> 5.0.8'
29
+ s.add_development_dependency 'rake', '~> 10.1'
30
+ s.add_development_dependency 'rake-compiler', '~> 0.9'
31
+ s.add_development_dependency 'mocha', '~> 1.0'
32
+ s.add_development_dependency 'minitest', '~> 5.2'
33
+ s.add_development_dependency 'coveralls', '~> 0.7'
33
34
  end
@@ -11,7 +11,7 @@ static VALUE breakpoints = Qnil;
11
11
  static VALUE tracepoints = Qnil;
12
12
 
13
13
  /* Implements thread syncronization, we must stop threads when debugging */
14
- VALUE locker = Qnil;
14
+ VALUE locker = Qnil;
15
15
 
16
16
  /* Threads table */
17
17
  VALUE threads = Qnil;
@@ -38,7 +38,7 @@ typedef struct {
38
38
  int dest_frame;
39
39
  int lines; /* # of lines in dest_frame before stopping */
40
40
  int steps; /* # of steps before stopping */
41
- int after_frame; /* stop rigth after returning from this frame */
41
+ int after_frame; /* stop right after returning from this frame */
42
42
  int before_frame; /* stop right before returning from this frame */
43
43
 
44
44
  VALUE last_file;
@@ -2,6 +2,8 @@ require 'byebug/byebug'
2
2
  require 'byebug/version'
3
3
  require 'byebug/context'
4
4
  require 'byebug/processor'
5
+ require 'byebug/command_processor'
6
+ require 'byebug/control_command_processor'
5
7
  require 'byebug/remote'
6
8
  require 'stringio'
7
9
  require 'tracer'
@@ -10,8 +12,7 @@ require 'linecache19'
10
12
  module Byebug
11
13
 
12
14
  # List of files byebug will ignore while debugging
13
- IGNORED_FILES = Dir[Pathname.new(__FILE__) + "../**/*.rb"].map {
14
- |f| File.expand_path(f) }
15
+ IGNORED_FILES = Dir.glob('**/*.rb').map { |f| File.expand_path(f) }
15
16
 
16
17
  # Default options to Byebug.start
17
18
  DEFAULT_START_SETTINGS = {
@@ -0,0 +1,255 @@
1
+ require 'forwardable'
2
+ require_relative 'interface'
3
+ require_relative 'command'
4
+
5
+ module Byebug
6
+
7
+ class CommandProcessor < Processor
8
+ attr_reader :display
9
+
10
+ def initialize(interface = LocalInterface.new)
11
+ super(interface)
12
+
13
+ @display = []
14
+ @mutex = Mutex.new
15
+ @last_cmd = nil # To allow empty (just <RET>) commands
16
+ @last_file = nil # Filename the last time we stopped
17
+ @last_line = nil # Line number the last time we stopped
18
+ @context_was_dead = false # Assume we haven't started.
19
+ end
20
+
21
+ def interface=(interface)
22
+ @mutex.synchronize do
23
+ @interface.close if @interface
24
+ @interface = interface
25
+ end
26
+ end
27
+
28
+ require 'pathname' # For cleanpath
29
+
30
+ #
31
+ # Regularize file name.
32
+ #
33
+ # This is also used as a common funnel place if basename is desired or if we
34
+ # are working remotely and want to change the basename. Or we are eliding
35
+ # filenames.
36
+ def self.canonic_file(filename)
37
+ return filename if ['(irb)', '-e'].include?(filename)
38
+
39
+ # For now we want resolved filenames
40
+ if Command.settings[:basename]
41
+ File.basename(filename)
42
+ else
43
+ Pathname.new(filename).cleanpath.to_s
44
+ end
45
+ end
46
+
47
+ def self.protect(mname)
48
+ alias_method "__#{mname}", mname
49
+ module_eval <<-END, __FILE__, __LINE__+1
50
+ def #{mname}(*args)
51
+ @mutex.synchronize do
52
+ return unless @interface
53
+ __#{mname}(*args)
54
+ end
55
+ rescue IOError, Errno::EPIPE
56
+ self.interface = nil
57
+ rescue SignalException
58
+ raise
59
+ rescue Exception
60
+ print "INTERNAL ERROR!!! #\{$!\}\n" rescue nil
61
+ print $!.backtrace.map{|l| "\t#\{l\}"}.join("\n") rescue nil
62
+ end
63
+ END
64
+ end
65
+
66
+ def at_breakpoint(context, breakpoint)
67
+ n = Byebug.breakpoints.index(breakpoint) + 1
68
+ file = CommandProcessor.canonic_file(breakpoint.source)
69
+ line = breakpoint.pos
70
+ print "Stopped by breakpoint #{n} at #{file}:#{line}\n"
71
+ end
72
+ protect :at_breakpoint
73
+
74
+ def at_catchpoint(context, excpt)
75
+ file = CommandProcessor.canonic_file(context.frame_file(0))
76
+ line = context.frame_line(0)
77
+ print "Catchpoint at %s:%d: `%s' (%s)\n", file, line, excpt, excpt.class
78
+ end
79
+ protect :at_catchpoint
80
+
81
+ def at_tracing(context, file, line)
82
+ if file != @last_file || line != @last_line || Command.settings[:linetrace_plus]
83
+ @last_file, @last_line = file, line
84
+ print "Tracing: #{CommandProcessor.canonic_file(file)}:#{line} " \
85
+ "#{Byebug.line_at(file,line)}\n"
86
+ end
87
+ always_run(context, file, line, 2)
88
+ end
89
+ protect :at_tracing
90
+
91
+ def at_line(context, file, line)
92
+ Byebug.source_reload if Command.settings[:autoreload]
93
+ process_commands(context, file, line)
94
+ end
95
+ protect :at_line
96
+
97
+ def at_return(context, file, line)
98
+ process_commands(context, file, line)
99
+ end
100
+ protect :at_return
101
+
102
+ private
103
+ #
104
+ # Prompt shown before reading a command.
105
+ #
106
+ def prompt(context)
107
+ return "(byebug#{context.dead? ? ':post-mortem' : ''}) "
108
+ end
109
+
110
+ #
111
+ # Run commands everytime.
112
+ #
113
+ # For example display commands or possibly the list or irb in an
114
+ # "autolist" or "autoirb".
115
+ #
116
+ # @return List of commands acceptable to run bound to the current state
117
+ #
118
+ def always_run(context, file, line, run_level)
119
+ cmds = Command.commands
120
+
121
+ # Remove some commands in post-mortem
122
+ cmds = cmds.find_all { |cmd| cmd.allow_in_post_mortem } if context.dead?
123
+
124
+ state = State.new(cmds, context, @display, file, @interface, line)
125
+
126
+ # Change default when in irb or code included in command line
127
+ Command.settings[:autolist] = 0 if ['(irb)', '-e'].include?(file)
128
+
129
+ # Bind commands to the current state.
130
+ commands = cmds.map { |cmd| cmd.new(state) }
131
+
132
+ commands.select { |cmd| cmd.class.always_run >= run_level }
133
+ .each { |cmd| cmd.execute }
134
+
135
+ return state, commands
136
+ end
137
+
138
+ #
139
+ # Splits a command line of the form "cmd1 ; cmd2 ; ... ; cmdN" into an
140
+ # array of commands: [cmd1, cmd2, ..., cmdN]
141
+ #
142
+ def split_commands(cmd_line)
143
+ cmd_line.split(/;/).inject([]) do |m, v|
144
+ if m.empty?
145
+ m << v
146
+ else
147
+ if m.last[-1] == ?\\
148
+ m.last[-1,1] = ''
149
+ m.last << ';' << v
150
+ else
151
+ m << v
152
+ end
153
+ end
154
+ m
155
+ end
156
+ end
157
+
158
+ #
159
+ # Handle byebug commands.
160
+ #
161
+ def process_commands(context, file, line)
162
+ state, commands = always_run(context, file, line, 1)
163
+
164
+ if Command.settings[:testing]
165
+ Thread.current.thread_variable_set('state', state)
166
+ else
167
+ Thread.current.thread_variable_set('state', nil)
168
+ end
169
+
170
+ preloop(commands, context)
171
+ print state.location if Command.settings[:autolist] == 0
172
+
173
+ while !state.proceed?
174
+ input = @interface.command_queue.empty? ?
175
+ @interface.read_command(prompt(context)) :
176
+ @interface.command_queue.shift
177
+ break unless input
178
+ catch(:debug_error) do
179
+ if input == ""
180
+ next unless @last_cmd
181
+ input = @last_cmd
182
+ else
183
+ @last_cmd = input
184
+ end
185
+ split_commands(input).each do |cmd|
186
+ one_cmd(commands, context, cmd)
187
+ end
188
+ end
189
+ end
190
+ end
191
+
192
+ #
193
+ # Executes a single byebug command
194
+ #
195
+ def one_cmd(commands, context, input)
196
+ if cmd = commands.find { |c| c.match(input) }
197
+ if context.dead? && cmd.class.need_context
198
+ print "Command is unavailable\n"
199
+ else
200
+ cmd.execute
201
+ end
202
+ else
203
+ unknown_cmd = commands.find { |c| c.class.unknown }
204
+ if unknown_cmd
205
+ unknown_cmd.execute
206
+ else
207
+ errmsg "Unknown command: \"#{input}\". Try \"help\".\n"
208
+ end
209
+ end
210
+ end
211
+
212
+ #
213
+ # Tasks to do before processor loop
214
+ #
215
+ def preloop(commands, context)
216
+ @context_was_dead = true if context.dead? and not @context_was_dead
217
+
218
+ if @context_was_dead
219
+ print "The program finished.\n"
220
+ @context_was_dead = false
221
+ end
222
+ end
223
+
224
+ class State
225
+ attr_accessor :commands, :context, :display, :file, :frame_pos
226
+ attr_accessor :interface, :line, :previous_line
227
+
228
+ def initialize(commands, context, display, file, interface, line)
229
+ @commands, @context, @display = commands, context, display
230
+ @file, @interface, @line = file, interface, line
231
+ @frame_pos, @previous_line, @proceed = 0, nil, false
232
+ end
233
+
234
+ extend Forwardable
235
+ def_delegators :@interface, :errmsg, :print, :confirm
236
+
237
+ def proceed?
238
+ @proceed
239
+ end
240
+
241
+ def proceed
242
+ @proceed = true
243
+ end
244
+
245
+ def location
246
+ loc = "#{CommandProcessor.canonic_file(@file)} @ #{@line}\n"
247
+ loc += "#{Byebug.line_at(@file, @line)}\n" unless
248
+ ['(irb)', '-e'].include? @file
249
+ loc
250
+ end
251
+ end
252
+
253
+ end # class CommandProcessor
254
+
255
+ end
@@ -168,11 +168,11 @@ module Byebug
168
168
  def description
169
169
  %{w[here]|bt|backtrace\tdisplay stack frames
170
170
 
171
- Print the entire stack frame. Each frame is numbered, the most recent
172
- frame is 0. Frame number can be referred to in the "frame" command;
171
+ Print the entire stack frame. Each frame is numbered; the most recent
172
+ frame is 0. A frame number can be referred to in the "frame" command;
173
173
  "up" and "down" add or subtract respectively to frame numbers shown.
174
174
  The position of the current frame is marked with -->. C-frames hang
175
- from their most inmediate ruby frame to indicate that they are not
175
+ from their most immediate Ruby frame to indicate that they are not
176
176
  navigable}
177
177
  end
178
178
  end
@@ -6,7 +6,7 @@ module Byebug
6
6
  def stack_size
7
7
  if backtrace = Thread.current.backtrace_locations(0)
8
8
  backtrace.drop_while { |l| !ignored(l.path) }
9
- .drop_while { |l| ignored(l.path) || l.path == '(eval)' }
9
+ .drop_while { |l| ignored(l.path) }
10
10
  .take_while { |l| !ignored(l.path) }
11
11
  .size
12
12
  else
@@ -16,7 +16,7 @@ module Byebug
16
16
  end
17
17
 
18
18
  def real_stack_size
19
- if backtrace = Thread.current.backtrace_locations(1)
19
+ if backtrace = Thread.current.backtrace_locations(0)
20
20
  backtrace.size
21
21
  end
22
22
  end
@@ -75,15 +75,15 @@ module Byebug
75
75
  end
76
76
 
77
77
  def at_tracing(file, line)
78
- handler.at_tracing(self, file, line) unless IGNORED_FILES.include?(file)
78
+ handler.at_tracing(self, file, line)
79
79
  end
80
80
 
81
81
  def at_line(file, line)
82
- handler.at_line(self, file, line) unless IGNORED_FILES.include?(file)
82
+ handler.at_line(self, file, line)
83
83
  end
84
84
 
85
85
  def at_return(file, line)
86
- handler.at_return(self, file, line) unless IGNORED_FILES.include?(file)
86
+ handler.at_return(self, file, line)
87
87
  end
88
88
  end
89
89
  end
@@ -0,0 +1,79 @@
1
+ require 'forwardable'
2
+ require_relative 'interface'
3
+ require_relative 'command'
4
+
5
+ module Byebug
6
+
7
+ class ControlCommandProcessor < Processor
8
+ def initialize(interface)
9
+ super(interface)
10
+ @context_was_dead = false # Assume we haven't started.
11
+ end
12
+
13
+ def process_commands(verbose=false)
14
+ control_cmds = Command.commands.select do |cmd|
15
+ cmd.allow_in_control
16
+ end
17
+ state = State.new(@interface, control_cmds)
18
+ commands = control_cmds.map{|cmd| cmd.new(state) }
19
+
20
+ if @context_was_dead
21
+ print "The program finished.\n"
22
+ @context_was_dead = false
23
+ end
24
+
25
+ while input = @interface.read_command(prompt(nil))
26
+ print "+#{input}" if verbose
27
+ catch(:debug_error) do
28
+ if cmd = commands.find{|c| c.match(input) }
29
+ cmd.execute
30
+ else
31
+ errmsg "Unknown command\n"
32
+ end
33
+ end
34
+ end
35
+ rescue IOError, Errno::EPIPE
36
+ rescue Exception
37
+ print "INTERNAL ERROR!!! #{$!}\n" rescue nil
38
+ print $!.backtrace.map{|l| "\t#{l}"}.join("\n") rescue nil
39
+ ensure
40
+ @interface.close
41
+ end
42
+
43
+ #
44
+ # Prompt shown before reading a command.
45
+ #
46
+ def prompt(context)
47
+ return '(byebug:ctrl) '
48
+ end
49
+
50
+ class State
51
+ attr_reader :commands, :interface
52
+
53
+ def initialize(interface, commands)
54
+ @interface = interface
55
+ @commands = commands
56
+ end
57
+
58
+ def proceed
59
+ end
60
+
61
+ extend Forwardable
62
+ def_delegators :@interface, :errmsg, :print
63
+
64
+ def confirm(*args)
65
+ 'y'
66
+ end
67
+
68
+ def context
69
+ nil
70
+ end
71
+
72
+ def file
73
+ errmsg "No filename given.\n"
74
+ throw :debug_error
75
+ end
76
+ end
77
+ end
78
+
79
+ end
@@ -1,6 +1,5 @@
1
1
  require 'forwardable'
2
2
  require_relative 'interface'
3
- require_relative 'command'
4
3
 
5
4
  module Byebug
6
5
 
@@ -16,324 +15,4 @@ module Byebug
16
15
  end
17
16
  end
18
17
 
19
- class CommandProcessor < Processor
20
- attr_reader :display
21
-
22
- def initialize(interface = LocalInterface.new)
23
- super(interface)
24
-
25
- @display = []
26
- @mutex = Mutex.new
27
- @last_cmd = nil # To allow empty (just <RET>) commands
28
- @last_file = nil # Filename the last time we stopped
29
- @last_line = nil # Line number the last time we stopped
30
- @context_was_dead = false # Assume we haven't started.
31
- end
32
-
33
- def interface=(interface)
34
- @mutex.synchronize do
35
- @interface.close if @interface
36
- @interface = interface
37
- end
38
- end
39
-
40
- require 'pathname' # For cleanpath
41
-
42
- #
43
- # Regularize file name.
44
- #
45
- # This is also used as a common funnel place if basename is desired or if we
46
- # are working remotely and want to change the basename. Or we are eliding
47
- # filenames.
48
- def self.canonic_file(filename)
49
- return filename if ['(irb)', '-e'].include?(filename)
50
-
51
- # For now we want resolved filenames
52
- if Command.settings[:basename]
53
- File.basename(filename)
54
- else
55
- Pathname.new(filename).cleanpath.to_s
56
- end
57
- end
58
-
59
- def self.protect(mname)
60
- alias_method "__#{mname}", mname
61
- module_eval <<-END, __FILE__, __LINE__+1
62
- def #{mname}(*args)
63
- @mutex.synchronize do
64
- return unless @interface
65
- __#{mname}(*args)
66
- end
67
- rescue IOError, Errno::EPIPE
68
- self.interface = nil
69
- rescue SignalException
70
- raise
71
- rescue Exception
72
- print "INTERNAL ERROR!!! #\{$!\}\n" rescue nil
73
- print $!.backtrace.map{|l| "\t#\{l\}"}.join("\n") rescue nil
74
- end
75
- END
76
- end
77
-
78
- def at_breakpoint(context, breakpoint)
79
- n = Byebug.breakpoints.index(breakpoint) + 1
80
- file = CommandProcessor.canonic_file(breakpoint.source)
81
- line = breakpoint.pos
82
- print "Stopped by breakpoint #{n} at #{file}:#{line}\n"
83
- end
84
- protect :at_breakpoint
85
-
86
- def at_catchpoint(context, excpt)
87
- file = CommandProcessor.canonic_file(context.frame_file(0))
88
- line = context.frame_line(0)
89
- print "Catchpoint at %s:%d: `%s' (%s)\n", file, line, excpt, excpt.class
90
- end
91
- protect :at_catchpoint
92
-
93
- def at_tracing(context, file, line)
94
- if file != @last_file || line != @last_line || Command.settings[:linetrace_plus]
95
- @last_file, @last_line = file, line
96
- print "Tracing: #{CommandProcessor.canonic_file(file)}:#{line} " \
97
- "#{Byebug.line_at(file,line)}\n"
98
- end
99
- always_run(context, file, line, 2)
100
- end
101
- protect :at_tracing
102
-
103
- def at_line(context, file, line)
104
- Byebug.source_reload if Command.settings[:autoreload]
105
- process_commands(context, file, line)
106
- end
107
- protect :at_line
108
-
109
- def at_return(context, file, line)
110
- process_commands(context, file, line)
111
- end
112
- protect :at_return
113
-
114
- private
115
- #
116
- # Prompt shown before reading a command.
117
- #
118
- def prompt(context)
119
- return "(byebug#{context.dead? ? ':post-mortem' : ''}) "
120
- end
121
-
122
- #
123
- # Run commands everytime.
124
- #
125
- # For example display commands or possibly the list or irb in an
126
- # "autolist" or "autoirb".
127
- #
128
- # @return List of commands acceptable to run bound to the current state
129
- #
130
- def always_run(context, file, line, run_level)
131
- cmds = Command.commands
132
-
133
- # Remove some commands in post-mortem
134
- cmds = cmds.find_all { |cmd| cmd.allow_in_post_mortem } if context.dead?
135
-
136
- state = State.new(cmds, context, @display, file, @interface, line)
137
-
138
- # Change default when in irb or code included in command line
139
- Command.settings[:autolist] = 0 if ['(irb)', '-e'].include?(file)
140
-
141
- # Bind commands to the current state.
142
- commands = cmds.map { |cmd| cmd.new(state) }
143
-
144
- commands.select { |cmd| cmd.class.always_run >= run_level }
145
- .each { |cmd| cmd.execute }
146
-
147
- return state, commands
148
- end
149
-
150
- #
151
- # Splits a command line of the form "cmd1 ; cmd2 ; ... ; cmdN" into an
152
- # array of commands: [cmd1, cmd2, ..., cmdN]
153
- #
154
- def split_commands(cmd_line)
155
- cmd_line.split(/;/).inject([]) do |m, v|
156
- if m.empty?
157
- m << v
158
- else
159
- if m.last[-1] == ?\\
160
- m.last[-1,1] = ''
161
- m.last << ';' << v
162
- else
163
- m << v
164
- end
165
- end
166
- m
167
- end
168
- end
169
-
170
- #
171
- # Handle byebug commands.
172
- #
173
- def process_commands(context, file, line)
174
- state, commands = always_run(context, file, line, 1)
175
-
176
- if Command.settings[:testing]
177
- Thread.current.thread_variable_set('state', state)
178
- else
179
- Thread.current.thread_variable_set('state', nil)
180
- end
181
-
182
- preloop(commands, context)
183
- print state.location if Command.settings[:autolist] == 0
184
-
185
- while !state.proceed?
186
- input = @interface.command_queue.empty? ?
187
- @interface.read_command(prompt(context)) :
188
- @interface.command_queue.shift
189
- break unless input
190
- catch(:debug_error) do
191
- if input == ""
192
- next unless @last_cmd
193
- input = @last_cmd
194
- else
195
- @last_cmd = input
196
- end
197
- split_commands(input).each do |cmd|
198
- one_cmd(commands, context, cmd)
199
- end
200
- end
201
- end
202
- end
203
-
204
- #
205
- # Executes a single byebug command
206
- #
207
- def one_cmd(commands, context, input)
208
- if cmd = commands.find { |c| c.match(input) }
209
- if context.dead? && cmd.class.need_context
210
- print "Command is unavailable\n"
211
- else
212
- cmd.execute
213
- end
214
- else
215
- unknown_cmd = commands.find { |c| c.class.unknown }
216
- if unknown_cmd
217
- unknown_cmd.execute
218
- else
219
- errmsg "Unknown command: \"#{input}\". Try \"help\".\n"
220
- end
221
- end
222
- end
223
-
224
- #
225
- # Tasks to do before processor loop
226
- #
227
- def preloop(commands, context)
228
- @context_was_dead = true if context.dead? and not @context_was_dead
229
-
230
- if @context_was_dead
231
- print "The program finished.\n"
232
- @context_was_dead = false
233
- end
234
- end
235
-
236
- class State
237
- attr_accessor :commands, :context, :display, :file, :frame_pos
238
- attr_accessor :interface, :line, :previous_line
239
-
240
- def initialize(commands, context, display, file, interface, line)
241
- @commands, @context, @display = commands, context, display
242
- @file, @interface, @line = file, interface, line
243
- @frame_pos, @previous_line, @proceed = 0, nil, false
244
- end
245
-
246
- extend Forwardable
247
- def_delegators :@interface, :errmsg, :print, :confirm
248
-
249
- def proceed?
250
- @proceed
251
- end
252
-
253
- def proceed
254
- @proceed = true
255
- end
256
-
257
- def location
258
- loc = "#{CommandProcessor.canonic_file(@file)} @ #{@line}\n"
259
- loc += "#{Byebug.line_at(@file, @line)}\n" unless
260
- ['(irb)', '-e'].include? @file
261
- loc
262
- end
263
- end
264
-
265
- end # class CommandProcessor
266
-
267
-
268
- class ControlCommandProcessor < Processor
269
- def initialize(interface)
270
- super(interface)
271
- @context_was_dead = false # Assume we haven't started.
272
- end
273
-
274
- def process_commands(verbose=false)
275
- control_cmds = Command.commands.select do |cmd|
276
- cmd.allow_in_control
277
- end
278
- state = State.new(@interface, control_cmds)
279
- commands = control_cmds.map{|cmd| cmd.new(state) }
280
-
281
- if @context_was_dead
282
- print "The program finished.\n"
283
- @context_was_dead = false
284
- end
285
-
286
- while input = @interface.read_command(prompt(nil))
287
- print "+#{input}" if verbose
288
- catch(:debug_error) do
289
- if cmd = commands.find{|c| c.match(input) }
290
- cmd.execute
291
- else
292
- errmsg "Unknown command\n"
293
- end
294
- end
295
- end
296
- rescue IOError, Errno::EPIPE
297
- rescue Exception
298
- print "INTERNAL ERROR!!! #{$!}\n" rescue nil
299
- print $!.backtrace.map{|l| "\t#{l}"}.join("\n") rescue nil
300
- ensure
301
- @interface.close
302
- end
303
-
304
- #
305
- # Prompt shown before reading a command.
306
- #
307
- def prompt(context)
308
- return '(byebug:ctrl) '
309
- end
310
-
311
- class State
312
- attr_reader :commands, :interface
313
-
314
- def initialize(interface, commands)
315
- @interface = interface
316
- @commands = commands
317
- end
318
-
319
- def proceed
320
- end
321
-
322
- extend Forwardable
323
- def_delegators :@interface, :errmsg, :print
324
-
325
- def confirm(*args)
326
- 'y'
327
- end
328
-
329
- def context
330
- nil
331
- end
332
-
333
- def file
334
- errmsg "No filename given.\n"
335
- throw :debug_error
336
- end
337
- end
338
- end
339
18
  end
@@ -1,3 +1,3 @@
1
1
  module Byebug
2
- VERSION = '2.5.0'
2
+ VERSION = '2.6.0'
3
3
  end
@@ -0,0 +1,3 @@
1
+ byebug
2
+
3
+ SteppingRaiseFromCMethodExample.new.a
@@ -0,0 +1,3 @@
1
+ byebug
2
+
3
+ SteppingRaiseFromRubyMethodExample.new.a
@@ -86,7 +86,7 @@ class TestFrame < TestDsl::TestCase
86
86
 
87
87
  it 'must set frame to the last one' do
88
88
  enter 'frame -1'
89
- debug_file('frame') { File.basename(state.file).must_equal 'test_helper.rb' }
89
+ debug_file('frame') { File.basename(state.file).must_equal 'minitest.rb' }
90
90
  end
91
91
 
92
92
  it 'must not set frame if the frame number is too low' do
@@ -15,7 +15,40 @@ class SteppingExample
15
15
  end
16
16
  end
17
17
 
18
+ class SteppingRaiseFromRubyMethodExample
19
+ def a
20
+ b
21
+ rescue
22
+ 1
23
+ end
24
+
25
+ def b
26
+ c
27
+ end
28
+
29
+ def c
30
+ raise 'bang'
31
+ end
32
+ end
33
+
34
+ class SteppingRaiseFromCMethodExample
35
+ def a
36
+ b
37
+ rescue NameError
38
+ 1
39
+ end
40
+
41
+ def b
42
+ c
43
+ end
44
+
45
+ def c
46
+ d
47
+ end
48
+ end
49
+
18
50
  class TestStepping < TestDsl::TestCase
51
+
19
52
  describe 'Next Command' do
20
53
 
21
54
  describe 'method call behaviour' do
@@ -77,6 +110,26 @@ class TestStepping < TestDsl::TestCase
77
110
  debug_file('stepping') { state.line.must_equal 8 }
78
111
  end
79
112
  end
113
+
114
+ describe 'raise/rescue behaviour' do
115
+ describe 'from c method' do
116
+ before { enter "break #{__FILE__}:36", 'cont' }
117
+
118
+ it 'must step over rescue' do
119
+ enter 'next'
120
+ debug_file('stepping_raise_from_c_method') { state.line.must_equal 38 }
121
+ end
122
+ end
123
+
124
+ describe 'from ruby method' do
125
+ before { enter "break #{__FILE__}:20", 'cont' }
126
+
127
+ it 'must step over rescue' do
128
+ enter 'next'
129
+ debug_file('stepping_raise_from_ruby_method') { state.line.must_equal 22 }
130
+ end
131
+ end
132
+ end
80
133
  end
81
134
 
82
135
  describe 'Step Command' do
@@ -1,7 +1,14 @@
1
+ if ENV['CI']
2
+ require 'coveralls'
3
+ Coveralls.wear! do
4
+ add_filter 'test'
5
+ end
6
+ end
7
+
1
8
  require 'minitest'
2
9
  require 'minitest/spec'
3
10
  require 'pathname'
4
- require 'mocha/setup'
11
+ require 'mocha/mini_test'
5
12
  require 'byebug'
6
13
 
7
14
  Dir.glob(File.expand_path("../support/*.rb", __FILE__)).each { |f| require f }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: byebug
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.0
4
+ version: 2.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Rodriguez
@@ -10,92 +10,106 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-12-14 00:00:00.000000000 Z
13
+ date: 2014-02-08 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: columnize
17
17
  requirement: !ruby/object:Gem::Requirement
18
18
  requirements:
19
- - - ~>
19
+ - - "~>"
20
20
  - !ruby/object:Gem::Version
21
- version: 0.3.6
21
+ version: '0.3'
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
- - - ~>
26
+ - - "~>"
27
27
  - !ruby/object:Gem::Version
28
- version: 0.3.6
28
+ version: '0.3'
29
29
  - !ruby/object:Gem::Dependency
30
30
  name: debugger-linecache
31
31
  requirement: !ruby/object:Gem::Requirement
32
32
  requirements:
33
- - - ~>
33
+ - - "~>"
34
34
  - !ruby/object:Gem::Version
35
- version: 1.2.0
35
+ version: '1.2'
36
36
  type: :runtime
37
37
  prerelease: false
38
38
  version_requirements: !ruby/object:Gem::Requirement
39
39
  requirements:
40
- - - ~>
40
+ - - "~>"
41
41
  - !ruby/object:Gem::Version
42
- version: 1.2.0
42
+ version: '1.2'
43
43
  - !ruby/object:Gem::Dependency
44
44
  name: rake
45
45
  requirement: !ruby/object:Gem::Requirement
46
46
  requirements:
47
- - - ~>
47
+ - - "~>"
48
48
  - !ruby/object:Gem::Version
49
- version: 10.1.0
49
+ version: '10.1'
50
50
  type: :development
51
51
  prerelease: false
52
52
  version_requirements: !ruby/object:Gem::Requirement
53
53
  requirements:
54
- - - ~>
54
+ - - "~>"
55
55
  - !ruby/object:Gem::Version
56
- version: 10.1.0
56
+ version: '10.1'
57
57
  - !ruby/object:Gem::Dependency
58
58
  name: rake-compiler
59
59
  requirement: !ruby/object:Gem::Requirement
60
60
  requirements:
61
- - - ~>
61
+ - - "~>"
62
62
  - !ruby/object:Gem::Version
63
- version: 0.9.2
63
+ version: '0.9'
64
64
  type: :development
65
65
  prerelease: false
66
66
  version_requirements: !ruby/object:Gem::Requirement
67
67
  requirements:
68
- - - ~>
68
+ - - "~>"
69
69
  - !ruby/object:Gem::Version
70
- version: 0.9.2
70
+ version: '0.9'
71
71
  - !ruby/object:Gem::Dependency
72
72
  name: mocha
73
73
  requirement: !ruby/object:Gem::Requirement
74
74
  requirements:
75
- - - ~>
75
+ - - "~>"
76
76
  - !ruby/object:Gem::Version
77
- version: 0.14.0
77
+ version: '1.0'
78
78
  type: :development
79
79
  prerelease: false
80
80
  version_requirements: !ruby/object:Gem::Requirement
81
81
  requirements:
82
- - - ~>
82
+ - - "~>"
83
83
  - !ruby/object:Gem::Version
84
- version: 0.14.0
84
+ version: '1.0'
85
85
  - !ruby/object:Gem::Dependency
86
86
  name: minitest
87
87
  requirement: !ruby/object:Gem::Requirement
88
88
  requirements:
89
- - - ~>
89
+ - - "~>"
90
90
  - !ruby/object:Gem::Version
91
- version: 5.0.8
91
+ version: '5.2'
92
92
  type: :development
93
93
  prerelease: false
94
94
  version_requirements: !ruby/object:Gem::Requirement
95
95
  requirements:
96
- - - ~>
96
+ - - "~>"
97
97
  - !ruby/object:Gem::Version
98
- version: 5.0.8
98
+ version: '5.2'
99
+ - !ruby/object:Gem::Dependency
100
+ name: coveralls
101
+ requirement: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - "~>"
104
+ - !ruby/object:Gem::Version
105
+ version: '0.7'
106
+ type: :development
107
+ prerelease: false
108
+ version_requirements: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - "~>"
111
+ - !ruby/object:Gem::Version
112
+ version: '0.7'
99
113
  description: |-
100
114
  Byebug is a Ruby 2 debugger. It's implemented using the
101
115
  Ruby 2 TracePoint C API for execution control and the Debug Inspector C API
@@ -111,8 +125,8 @@ extensions:
111
125
  extra_rdoc_files:
112
126
  - README.md
113
127
  files:
114
- - .gitignore
115
- - .travis.yml
128
+ - ".gitignore"
129
+ - ".travis.yml"
116
130
  - CHANGELOG.md
117
131
  - CONTRIBUTING.md
118
132
  - GUIDE.md
@@ -131,6 +145,7 @@ files:
131
145
  - ext/byebug/threads.c
132
146
  - lib/byebug.rb
133
147
  - lib/byebug/command.rb
148
+ - lib/byebug/command_processor.rb
134
149
  - lib/byebug/commands/breakpoints.rb
135
150
  - lib/byebug/commands/catchpoint.rb
136
151
  - lib/byebug/commands/condition.rb
@@ -160,6 +175,7 @@ files:
160
175
  - lib/byebug/commands/trace.rb
161
176
  - lib/byebug/commands/variables.rb
162
177
  - lib/byebug/context.rb
178
+ - lib/byebug/control_command_processor.rb
163
179
  - lib/byebug/helper.rb
164
180
  - lib/byebug/interface.rb
165
181
  - lib/byebug/interfaces/local_interface.rb
@@ -168,7 +184,6 @@ files:
168
184
  - lib/byebug/processor.rb
169
185
  - lib/byebug/remote.rb
170
186
  - lib/byebug/version.rb
171
- - logo.png
172
187
  - test/breakpoints_test.rb
173
188
  - test/conditions_test.rb
174
189
  - test/continue_test.rb
@@ -207,6 +222,8 @@ files:
207
222
  - test/examples/show.rb
208
223
  - test/examples/source.rb
209
224
  - test/examples/stepping.rb
225
+ - test/examples/stepping_raise_from_c_method.rb
226
+ - test/examples/stepping_raise_from_ruby_method.rb
210
227
  - test/examples/test-triangle.rb
211
228
  - test/examples/thread.rb
212
229
  - test/examples/tmate.rb
@@ -250,17 +267,17 @@ require_paths:
250
267
  - lib
251
268
  required_ruby_version: !ruby/object:Gem::Requirement
252
269
  requirements:
253
- - - '>='
270
+ - - ">="
254
271
  - !ruby/object:Gem::Version
255
272
  version: 2.0.0
256
273
  required_rubygems_version: !ruby/object:Gem::Requirement
257
274
  requirements:
258
- - - '>='
275
+ - - ">="
259
276
  - !ruby/object:Gem::Version
260
277
  version: '0'
261
278
  requirements: []
262
279
  rubyforge_project:
263
- rubygems_version: 2.1.11
280
+ rubygems_version: 2.2.1
264
281
  signing_key:
265
282
  specification_version: 4
266
283
  summary: Ruby 2.0 fast debugger - base + cli
@@ -303,6 +320,8 @@ test_files:
303
320
  - test/examples/show.rb
304
321
  - test/examples/source.rb
305
322
  - test/examples/stepping.rb
323
+ - test/examples/stepping_raise_from_c_method.rb
324
+ - test/examples/stepping_raise_from_ruby_method.rb
306
325
  - test/examples/test-triangle.rb
307
326
  - test/examples/thread.rb
308
327
  - test/examples/tmate.rb
@@ -336,4 +355,3 @@ test_files:
336
355
  - test/thread_test.rb
337
356
  - test/trace_test.rb
338
357
  - test/variables_test.rb
339
- has_rdoc:
data/logo.png DELETED
Binary file