byebug 1.0.3 → 1.1.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 +5 -0
- data/README.md +13 -11
- data/Rakefile +0 -6
- data/bin/byebug +83 -136
- data/ext/byebug/byebug.c +182 -96
- data/ext/byebug/byebug.h +5 -7
- data/ext/byebug/context.c +52 -40
- data/lib/byebug.rb +81 -81
- data/lib/byebug/command.rb +18 -35
- data/lib/byebug/commands/control.rb +1 -1
- data/lib/byebug/commands/display.rb +0 -2
- data/lib/byebug/commands/enable.rb +4 -16
- data/lib/byebug/commands/eval.rb +5 -3
- data/lib/byebug/commands/frame.rb +68 -69
- data/lib/byebug/commands/help.rb +2 -1
- data/lib/byebug/commands/info.rb +43 -42
- data/lib/byebug/commands/method.rb +4 -3
- data/lib/byebug/commands/set.rb +10 -19
- data/lib/byebug/commands/show.rb +6 -13
- data/lib/byebug/interface.rb +1 -1
- data/lib/byebug/processor.rb +14 -17
- data/lib/byebug/version.rb +1 -2
- data/old_doc/byebug.texi +576 -847
- data/test/breakpoints_test.rb +0 -1
- data/test/conditions_test.rb +35 -33
- data/test/display_test.rb +14 -13
- data/test/edit_test.rb +28 -25
- data/test/eval_test.rb +0 -2
- data/test/finish_test.rb +4 -3
- data/test/frame_test.rb +20 -21
- data/test/help_test.rb +26 -23
- data/test/info_test.rb +105 -108
- data/test/irb_test.rb +26 -25
- data/test/kill_test.rb +19 -19
- data/test/list_test.rb +140 -156
- data/test/method_test.rb +21 -22
- data/test/post_mortem_test.rb +2 -5
- data/test/quit_test.rb +16 -17
- data/test/reload_test.rb +2 -2
- data/test/restart_test.rb +0 -1
- data/test/save_test.rb +31 -32
- data/test/set_test.rb +50 -47
- data/test/show_test.rb +67 -66
- data/test/source_test.rb +31 -34
- data/test/stepping_test.rb +32 -34
- data/test/support/test_dsl.rb +1 -1
- data/test/trace_test.rb +1 -2
- data/test/variables_test.rb +36 -34
- metadata +2 -4
- data/lib/byebug/commands/tmate.rb +0 -36
- data/test/tmate_test.rb +0 -44
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc04cc8b68063ec31b6318a54bd88e1d4ee354be
|
4
|
+
data.tar.gz: 070611b0dbc7fcc7f6fa276b588b32297c5d5588
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1434e8a81a8f62b6af39ba73ba527c44b77c9219d06760ac36cc392d98de069f007d3a3b65f56c3f4db6b6ae3fcd3034fc660d8d9fa01781f677a53df2538bac
|
7
|
+
data.tar.gz: e679189a446359f9d98b18f086472129826218f57d1e1cc0c8d71fa186c146a917b0efafed1c4cc9a991d88f2390fff41c36d160a8f3a4ab2fb23f1ceacd1b90
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -5,24 +5,26 @@ A Ruby 2.0 debugger.
|
|
5
5
|
|
6
6
|
## Install
|
7
7
|
|
8
|
-
Just type
|
8
|
+
Just type `gem install byebug` or drop `gem 'byebug'` in your Gemfile and run
|
9
|
+
`bundle install`.
|
9
10
|
|
10
|
-
$ gem install byebug
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
gem 'byebug'
|
15
|
-
|
16
|
-
in your Gemfile
|
12
|
+
## Usage
|
17
13
|
|
14
|
+
Simply drop `byebug` wherever you want to start debugging and the execution
|
15
|
+
stop there. If you are debugging rails, start the server in normal mode with
|
16
|
+
`rails server` and once the execution get to your `byebug` command you will get
|
17
|
+
a debugging terminal.
|
18
18
|
|
19
|
-
## Usage
|
20
19
|
|
21
|
-
|
20
|
+
## Configuration
|
22
21
|
|
23
|
-
|
22
|
+
You can automatically load some configurations at startup by dropping them in
|
23
|
+
the startup file `.byebugrc`, for example, `set listsize 20`. If you are coming
|
24
|
+
from [debugger](https://github.com/cldwalker/debugger), notice however that you
|
25
|
+
no longer need `set autolist`, `set autoreload` and `set autoeval` because they
|
26
|
+
are default options in byebug.
|
24
27
|
|
25
|
-
and the execution will stop and allow you to start debugging.
|
26
28
|
|
27
29
|
## Credits
|
28
30
|
|
data/Rakefile
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# -*- Ruby -*-
|
2
2
|
require 'rake/testtask'
|
3
3
|
require 'rake/extensiontask'
|
4
|
-
require 'rubygems/package_task'
|
5
4
|
require 'bundler/gem_tasks'
|
6
5
|
|
7
6
|
Rake::ExtensionTask.new('byebug')
|
@@ -18,9 +17,4 @@ end
|
|
18
17
|
|
19
18
|
base_spec = eval(File.read('byebug.gemspec'), binding, 'byebug.gemspec')
|
20
19
|
|
21
|
-
# Rake task to build the default package
|
22
|
-
Gem::PackageTask.new(base_spec) do |pkg|
|
23
|
-
pkg.need_tar = true
|
24
|
-
end
|
25
|
-
|
26
20
|
task :default => :test
|
data/bin/byebug
CHANGED
@@ -13,14 +13,15 @@
|
|
13
13
|
#=== Options
|
14
14
|
#
|
15
15
|
#<tt>-A | --annotate</tt> <i>level</i>::
|
16
|
-
# Set gdb-style annotation to <i>level</i>, a number. Additional
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
16
|
+
# Set gdb-style annotation to <i>level</i>, a number. Additional information
|
17
|
+
# is output automatically when program state is changed. This can be used by
|
18
|
+
# front-ends such as GNU Emacs to post this updated information without
|
19
|
+
# having to poll for it.
|
20
20
|
#
|
21
21
|
#<tt>--client</tt>::
|
22
22
|
# Connect to a remote byebug. Used with another byebug invocation using
|
23
|
-
# <tt>--server</tt>. See also <tt>--host</tt
|
23
|
+
# <tt>--server</tt>. See also <tt>--host</tt>, <tt>--port</tt> and
|
24
|
+
# <tt>--cport</tt> options.
|
24
25
|
#
|
25
26
|
#<tt>--cport=</tt><i>port</i>::
|
26
27
|
# Use port <i>port</i> for access to byebug control.
|
@@ -28,75 +29,65 @@
|
|
28
29
|
#<tt>-d | --debug</tt>::
|
29
30
|
# Set $DEBUG true.
|
30
31
|
#
|
31
|
-
#<tt>--emacs</tt>::
|
32
|
-
# Activates full GNU Emacs mode. Is the equivalent of setting the options
|
33
|
-
# <tt>--emacs-basic --annotate=3 --no-stop --no-control --post-mortem</tt>.
|
34
|
-
#
|
35
|
-
#<tt>--emacs-basic</tt>::
|
36
|
-
# Activates GNU Emacs mode. Byebug prompts are prefaced with two octal 032
|
37
|
-
# characters.
|
38
|
-
#
|
39
32
|
#<tt>-h | --host=</tt><i>host</i>::
|
40
|
-
#
|
33
|
+
# Use host name <i>host</i> for remote debugging.
|
34
|
+
#
|
35
|
+
#<tt>--help</tt>::
|
36
|
+
# Show invocation help and exit.
|
41
37
|
#
|
42
38
|
#<tt>-I | --include</tt> <i>path</i>
|
43
|
-
#
|
39
|
+
# Add <i>path</i> to <tt>$LOAD_PATH</tt>
|
40
|
+
#
|
41
|
+
#<tt>--keep-frame-binding</tt>::
|
42
|
+
# Keep frame bindings.
|
44
43
|
#
|
45
44
|
#<tt>-m | --post-mortem</tt>::
|
46
|
-
#
|
45
|
+
# Activate post-mortem mode.
|
47
46
|
#
|
48
47
|
#<tt>--no-control</tt>::
|
49
|
-
#
|
48
|
+
# Do not automatically start control thread.
|
49
|
+
#
|
50
|
+
#<tt>--no-quit</tt>::
|
51
|
+
# Do not quit when script terminates. Instead rerun the program.
|
50
52
|
#
|
51
53
|
#<tt>--no-stop</tt>::
|
52
|
-
#
|
54
|
+
# Do not stop when script is loaded.
|
55
|
+
#
|
56
|
+
#<tt>--nx</tt>::
|
57
|
+
# Don’t execute commands found in any initialization files like
|
58
|
+
# <tt>.byebugrc</tt>.
|
53
59
|
#
|
54
60
|
#<tt>-p | --port=PORT</tt>::
|
55
|
-
#
|
61
|
+
# Use port <i>port</i> for remote debugging.
|
56
62
|
#
|
57
63
|
#<tt>-r | --require</tt><i>script</i>::
|
58
|
-
#
|
59
|
-
#
|
60
|
-
#<tt>--script</tt> <i>file</i>::
|
61
|
-
# Run byebug script file <i>file</i>
|
62
|
-
#
|
63
|
-
#<tt>-x | --trace</tt>::
|
64
|
-
# Show lines before executing them.
|
64
|
+
# Require the library, before executing your script.
|
65
65
|
#
|
66
|
-
#<tt
|
67
|
-
#
|
66
|
+
#<tt>-s | --server</tt>::
|
67
|
+
# Listen for remote connections. Another byebug session accesses using the
|
68
|
+
# <tt>--client</tt> option. See also the <tt>--host</tt>, <tt>--port</tt>
|
69
|
+
# and <tt>--cport</tt> options
|
68
70
|
#
|
69
|
-
#<tt>--
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#<tt>--verbose</tt>::
|
73
|
-
# Turn on verbose mode.
|
71
|
+
#<tt>--script</tt>=<i>file</i>::
|
72
|
+
# Run script file <i>file</i>
|
74
73
|
#
|
75
74
|
#<tt>--v</tt>::
|
76
|
-
#
|
77
|
-
#
|
78
|
-
#
|
79
|
-
#
|
80
|
-
#<tt>--nx</tt>::
|
81
|
-
# Don’t execute commands found in any initialization files like
|
82
|
-
# <tt>.byebugrc</tt>.
|
75
|
+
# Print the version number, then turn on verbose mode if a script name is
|
76
|
+
# given. If no script name is given just exit after printing the version
|
77
|
+
# number.
|
83
78
|
#
|
84
|
-
#<tt>--
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#<tt>--script=</tt><i>file</i>::
|
88
|
-
# Name of the script file to run.
|
79
|
+
#<tt>--verbose</tt>::
|
80
|
+
# Turn on verbose mode.
|
89
81
|
#
|
90
|
-
#<tt
|
91
|
-
#
|
92
|
-
# <tt>--client</tt> option. See also the <tt>--host</tt>, <tt>--port</tt>
|
93
|
-
# and <tt>--cport</tt> options
|
82
|
+
#<tt>--version</tt>::
|
83
|
+
# Show the version number and exit.
|
94
84
|
#
|
95
85
|
#<tt>-w | --wait</tt>::
|
96
86
|
# Wait for a client connection; implies <tt>-s</tt> option.
|
97
87
|
#
|
98
|
-
#<tt
|
99
|
-
#
|
88
|
+
#<tt>-x | --trace</tt>::
|
89
|
+
# Show lines before executing them.
|
90
|
+
#
|
100
91
|
|
101
92
|
require 'optparse'
|
102
93
|
require 'ostruct'
|
@@ -140,9 +131,9 @@ end
|
|
140
131
|
options = OpenStruct.new(
|
141
132
|
'annotate' => Byebug.annotate,
|
142
133
|
'client' => false,
|
143
|
-
'control' => true,
|
144
134
|
'cport' => Byebug::PORT + 1,
|
145
135
|
'host' => nil,
|
136
|
+
'control' => true,
|
146
137
|
'quit' => true,
|
147
138
|
'no_rewrite_program' => false,
|
148
139
|
'stop' => true,
|
@@ -165,67 +156,37 @@ Usage: #{program} [options] <script.rb> -- <script.rb parameters>
|
|
165
156
|
EOB
|
166
157
|
opts.separator ""
|
167
158
|
opts.separator "Options:"
|
168
|
-
opts.on("-A", "--annotate LEVEL", Integer, "Set annotation level")
|
169
|
-
|annotate|
|
170
|
-
|
171
|
-
|
172
|
-
opts.on("
|
173
|
-
options.
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
options.
|
178
|
-
|
179
|
-
|
180
|
-
opts.on(
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
options.
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
opts.on('-
|
193
|
-
|
|
194
|
-
|
195
|
-
end
|
196
|
-
opts.on('-I', '--include PATH', String, 'Add PATH to $LOAD_PATH') do |path|
|
197
|
-
$LOAD_PATH.unshift(path)
|
198
|
-
end
|
199
|
-
opts.on('--no-control', 'Do not automatically start control thread') do
|
200
|
-
options.control = false
|
201
|
-
end
|
202
|
-
opts.on('--no-quit', 'Do not quit when script finishes') do
|
203
|
-
options.quit = false
|
204
|
-
end
|
205
|
-
opts.on('--no-rewrite-program',
|
206
|
-
'Do not set $0 to the program being debugged') do
|
207
|
-
options.no_rewrite_program = true
|
208
|
-
end
|
209
|
-
opts.on('--no-stop', 'Do not stop when script is loaded') do
|
210
|
-
options.stop = false
|
211
|
-
end
|
212
|
-
opts.on('-nx', 'Not run byebug initialization files (e.g. .byebugrc') do
|
213
|
-
options.nx = true
|
214
|
-
end
|
215
|
-
opts.on('-p', '--port PORT', Integer, 'Port used for remote debugging') do
|
216
|
-
|port|
|
217
|
-
options.port = port
|
218
|
-
end
|
219
|
-
opts.on('-r', '--require SCRIPT', String,
|
220
|
-
'Require the library, before executing your script') do |name|
|
221
|
-
if name == 'debug'
|
222
|
-
puts "byebug is not compatible with Ruby's 'debug' library. This option is ignored."
|
159
|
+
opts.on("-A", "--annotate LEVEL", Integer, "Set annotation level") {
|
160
|
+
|annotate| Byebug.annotate = annotate }
|
161
|
+
opts.on("-c", "--client", "Connect to remote byebug") {
|
162
|
+
options.client = true }
|
163
|
+
opts.on("--cport PORT", Integer, "Port used for control commands") {
|
164
|
+
|cport| options.cport = cport }
|
165
|
+
opts.on("-d", "--debug", "Set $DEBUG=true") {
|
166
|
+
$DEBUG = true }
|
167
|
+
opts.on('-h', '--host HOST', 'Host name used for remote debugging') {
|
168
|
+
|host| options.host = host }
|
169
|
+
opts.on('-I', '--include PATH', String, 'Add PATH to $LOAD_PATH') {
|
170
|
+
|path| $LOAD_PATH.unshift(path) }
|
171
|
+
opts.on('--no-control', 'Do not automatically start control thread') {
|
172
|
+
options.control = false }
|
173
|
+
opts.on('--no-quit', 'Do not quit when script finishes') {
|
174
|
+
options.quit = false }
|
175
|
+
opts.on('--no-rewrite-program', 'Don\'t set $0 to the program debugged') {
|
176
|
+
options.no_rewrite_program = true }
|
177
|
+
opts.on('--no-stop', 'Do not stop when script is loaded') {
|
178
|
+
options.stop = false }
|
179
|
+
opts.on('-nx', 'Don\'t run any byebug initialization files') {
|
180
|
+
options.nx = true }
|
181
|
+
opts.on('-p', '--port PORT', Integer, 'Port used for remote debugging') {
|
182
|
+
|port| options.port = port }
|
183
|
+
opts.on('-r', '--require SCRIPT', String, 'Require library before script') {
|
184
|
+
|name| if name == 'debug'
|
185
|
+
puts 'byebug not compatible with Ruby\'s \'debug\' lib, option ignored'
|
223
186
|
else
|
224
187
|
require name
|
225
|
-
end
|
226
|
-
|
227
|
-
opts.on('--restart-script FILE', String,
|
228
|
-
'Name of the script file to run. Erased after read') do
|
188
|
+
end }
|
189
|
+
opts.on('--restart-script FILE', String, 'Name of the script file to run. Erased after read') do
|
229
190
|
|restart_script|
|
230
191
|
options.restart_script = restart_script
|
231
192
|
unless File.exists?(options.restart_script)
|
@@ -241,21 +202,19 @@ EOB
|
|
241
202
|
exit
|
242
203
|
end
|
243
204
|
end
|
244
|
-
opts.on('-s', '--server', 'Listen for remote connections')
|
245
|
-
options.server = true
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
opts.on('-x', '--trace', 'Turn on line tracing') {options.tracing = true}
|
205
|
+
opts.on('-s', '--server', 'Listen for remote connections') {
|
206
|
+
options.server = true }
|
207
|
+
opts.on('-w', '--wait', 'Wait for a client connection, implies -s option') {
|
208
|
+
options.wait = true }
|
209
|
+
opts.on('-x', '--trace', 'Turn on line tracing') {
|
210
|
+
options.tracing = true }
|
251
211
|
opts.separator ''
|
252
212
|
opts.separator 'Common options:'
|
253
213
|
opts.on_tail('--help', 'Show this message') do
|
254
214
|
puts opts
|
255
215
|
exit
|
256
216
|
end
|
257
|
-
opts.on_tail('--version',
|
258
|
-
'Print the version') do
|
217
|
+
opts.on_tail('--version', 'Print program version') do
|
259
218
|
puts "byebug #{Byebug::VERSION}"
|
260
219
|
exit
|
261
220
|
end
|
@@ -263,8 +222,7 @@ EOB
|
|
263
222
|
$VERBOSE = true
|
264
223
|
options.verbose_long = true
|
265
224
|
end
|
266
|
-
opts.on_tail('-v',
|
267
|
-
'Print version number, then turn on verbose mode') do
|
225
|
+
opts.on_tail('-v', 'Print version number, then turn on verbose mode') do
|
268
226
|
puts "byebug #{Byebug::VERSION}"
|
269
227
|
$VERBOSE = true
|
270
228
|
end
|
@@ -274,16 +232,10 @@ end
|
|
274
232
|
|
275
233
|
# What file is used for byebug startup commands.
|
276
234
|
unless defined?(OPTS_INITFILE)
|
277
|
-
|
278
|
-
|
279
|
-
OPTS_INITFILE = 'rdbopt.ini'
|
280
|
-
HOME_DIR = (ENV['HOME'] ||
|
281
|
-
ENV['HOMEDRIVE'].to_s + ENV['HOMEPATH'].to_s).to_s
|
282
|
-
else
|
283
|
-
OPTS_INITFILE = '.rdboptrc'
|
284
|
-
HOME_DIR = ENV['HOME'].to_s
|
285
|
-
end
|
235
|
+
OPTS_INITFILE = '.byebugoptrc'
|
236
|
+
HOME_DIR = ENV['HOME'].to_s
|
286
237
|
end
|
238
|
+
|
287
239
|
begin
|
288
240
|
initfile = File.join(HOME_DIR, OPTS_INITFILE)
|
289
241
|
eval(File.read(initfile)) if File.exist?(initfile)
|
@@ -294,9 +246,6 @@ opts = process_options(options)
|
|
294
246
|
begin
|
295
247
|
Byebug::ARGV = ARGV.clone if not defined? Byebug::ARGV
|
296
248
|
byebug_path = File.expand_path($0)
|
297
|
-
if RUBY_PLATFORM =~ /mswin/
|
298
|
-
byebug_path += '.cmd' unless byebug_path =~ /\.cmd$/i
|
299
|
-
end
|
300
249
|
Byebug::BYEBUG_SCRIPT = byebug_path
|
301
250
|
Byebug::INITIAL_DIR = Dir.pwd
|
302
251
|
opts.parse! ARGV
|
@@ -330,9 +279,7 @@ else
|
|
330
279
|
Byebug.wait_connection = options.wait
|
331
280
|
|
332
281
|
if options.server
|
333
|
-
# start remote mode
|
334
282
|
Byebug.start_remote(options.host, [options.port, options.cport]) do
|
335
|
-
# load initrc script
|
336
283
|
Byebug.run_init_script(StringIO.new) unless options.nx
|
337
284
|
end
|
338
285
|
debug_program(options)
|
data/ext/byebug/byebug.c
CHANGED
@@ -4,9 +4,10 @@ static VALUE mByebug; /* Ruby Byebug Module object */
|
|
4
4
|
static VALUE cContext;
|
5
5
|
static VALUE cDebugThread;
|
6
6
|
|
7
|
-
static VALUE tracing
|
8
|
-
static VALUE
|
9
|
-
static VALUE
|
7
|
+
static VALUE tracing = Qfalse;
|
8
|
+
static VALUE post_mortem = Qfalse;
|
9
|
+
static VALUE debug = Qfalse;
|
10
|
+
static VALUE locker = Qnil;
|
10
11
|
|
11
12
|
static VALUE contexts;
|
12
13
|
static VALUE catchpoints;
|
@@ -14,11 +15,11 @@ static VALUE breakpoints;
|
|
14
15
|
|
15
16
|
static VALUE tpLine;
|
16
17
|
static VALUE tpCall;
|
18
|
+
static VALUE tpCCall;
|
17
19
|
static VALUE tpReturn;
|
20
|
+
static VALUE tpCReturn;
|
18
21
|
static VALUE tpRaise;
|
19
22
|
|
20
|
-
static VALUE idAlive;
|
21
|
-
|
22
23
|
static VALUE
|
23
24
|
tp_inspect(VALUE trace_point) {
|
24
25
|
rb_trace_arg_t *trace_arg = rb_tracearg_from_tracepoint(trace_point);
|
@@ -59,7 +60,7 @@ Byebug_thread_context(VALUE self, VALUE thread)
|
|
59
60
|
|
60
61
|
context = rb_hash_aref(contexts, thread);
|
61
62
|
if (context == Qnil) {
|
62
|
-
context =
|
63
|
+
context = Context_create(thread, cDebugThread);
|
63
64
|
rb_hash_aset(contexts, thread, context);
|
64
65
|
}
|
65
66
|
return context;
|
@@ -71,11 +72,13 @@ Byebug_current_context(VALUE self)
|
|
71
72
|
return Byebug_thread_context(self, rb_thread_current());
|
72
73
|
}
|
73
74
|
|
75
|
+
/*
|
74
76
|
static int
|
75
77
|
remove_dead_threads(VALUE thread, VALUE context, VALUE ignored)
|
76
78
|
{
|
77
79
|
return (IS_THREAD_ALIVE(thread)) ? ST_CONTINUE : ST_DELETE;
|
78
80
|
}
|
81
|
+
*/
|
79
82
|
|
80
83
|
static void
|
81
84
|
cleanup(debug_context_t *context)
|
@@ -96,9 +99,7 @@ cleanup(debug_context_t *context)
|
|
96
99
|
static int
|
97
100
|
check_start_processing(debug_context_t *context, VALUE thread)
|
98
101
|
{
|
99
|
-
/* return if thread is marked as 'ignored'
|
100
|
-
byebug's threads are marked this way
|
101
|
-
*/
|
102
|
+
/* return if thread is marked as 'ignored' */
|
102
103
|
if(CTX_FL_TEST(context, CTX_FL_IGNORE)) return 0;
|
103
104
|
|
104
105
|
while(1)
|
@@ -161,26 +162,32 @@ call_at_line(debug_context_t *context, char *file, int line,
|
|
161
162
|
rb_funcall(context_object, rb_intern("at_line"), 2, path, lineno);
|
162
163
|
}
|
163
164
|
|
165
|
+
#define EVENT_SETUP \
|
166
|
+
VALUE path, lineno, method_id, defined_class, binding, self; \
|
167
|
+
VALUE context_object; \
|
168
|
+
debug_context_t *context; \
|
169
|
+
context_object = Byebug_current_context(mByebug); \
|
170
|
+
Data_Get_Struct(context_object, debug_context_t, context); \
|
171
|
+
if (!check_start_processing(context, rb_thread_current())) return; \
|
172
|
+
load_frame_info(trace_point, &path, &lineno, &method_id, &defined_class, \
|
173
|
+
&binding, &self); \
|
174
|
+
if (debug == Qtrue) \
|
175
|
+
printf("%s (stack_size: %d)\n", \
|
176
|
+
RSTRING_PTR(tp_inspect(trace_point)), context->stack_size); \
|
177
|
+
|
164
178
|
static void
|
165
179
|
process_line_event(VALUE trace_point, void *data)
|
166
180
|
{
|
167
|
-
|
168
|
-
VALUE context_object;
|
181
|
+
EVENT_SETUP;
|
169
182
|
VALUE breakpoint;
|
170
|
-
debug_context_t *context;
|
171
183
|
int moved = 0;
|
172
184
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
if (debug == Qtrue)
|
180
|
-
printf("%s (stack_size: %d)\n", RSTRING_PTR(tp_inspect(trace_point)),
|
181
|
-
context->stack_size);
|
182
|
-
update_frame(context_object, RSTRING_PTR(path), FIX2INT(lineno), method_id,
|
183
|
-
defined_class, binding, self);
|
185
|
+
if (context->stack_size == 0)
|
186
|
+
push_frame(context, RSTRING_PTR(path), FIX2INT(lineno), method_id,
|
187
|
+
defined_class, binding, self);
|
188
|
+
else
|
189
|
+
update_frame(context->stack, RSTRING_PTR(path), FIX2INT(lineno), method_id,
|
190
|
+
defined_class, binding, self);
|
184
191
|
|
185
192
|
if (context->last_line != FIX2INT(lineno) || context->last_file == NULL ||
|
186
193
|
strcmp(context->last_file, RSTRING_PTR(path)))
|
@@ -227,52 +234,48 @@ process_line_event(VALUE trace_point, void *data)
|
|
227
234
|
}
|
228
235
|
|
229
236
|
static void
|
230
|
-
|
237
|
+
process_c_return_event(VALUE trace_point, void *data)
|
231
238
|
{
|
232
|
-
|
233
|
-
VALUE context_object;
|
234
|
-
debug_context_t *context;
|
239
|
+
EVENT_SETUP;
|
235
240
|
|
236
|
-
|
237
|
-
Data_Get_Struct(context_object, debug_context_t, context);
|
238
|
-
if (!check_start_processing(context, rb_thread_current())) return;
|
241
|
+
pop_frame(context);
|
239
242
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
243
|
+
cleanup(context);
|
244
|
+
}
|
245
|
+
|
246
|
+
static void
|
247
|
+
process_return_event(VALUE trace_point, void *data)
|
248
|
+
{
|
249
|
+
EVENT_SETUP;
|
245
250
|
|
246
251
|
if (context->stack_size == context->stop_frame)
|
247
252
|
{
|
248
253
|
context->stop_next = 1;
|
249
254
|
context->stop_frame = 0;
|
250
255
|
}
|
256
|
+
pop_frame(context);
|
257
|
+
|
258
|
+
cleanup(context);
|
259
|
+
}
|
251
260
|
|
252
|
-
|
261
|
+
static void
|
262
|
+
process_c_call_event(VALUE trace_point, void *data)
|
263
|
+
{
|
264
|
+
EVENT_SETUP;
|
253
265
|
|
266
|
+
push_frame(context, RSTRING_PTR(path), FIX2INT(lineno), method_id,
|
267
|
+
defined_class, binding, self);
|
254
268
|
cleanup(context);
|
255
269
|
}
|
256
270
|
|
257
271
|
static void
|
258
272
|
process_call_event(VALUE trace_point, void *data)
|
259
273
|
{
|
260
|
-
|
261
|
-
VALUE context_object;
|
274
|
+
EVENT_SETUP;
|
262
275
|
VALUE breakpoint;
|
263
|
-
debug_context_t *context;
|
264
276
|
|
265
|
-
|
266
|
-
|
267
|
-
if (!check_start_processing(context, rb_thread_current())) return;
|
268
|
-
|
269
|
-
load_frame_info(
|
270
|
-
trace_point, &path, &lineno, &method_id, &defined_class, &binding, &self);
|
271
|
-
if (debug == Qtrue)
|
272
|
-
printf("%s (stack_size: %d)\n", RSTRING_PTR(tp_inspect(trace_point)),
|
273
|
-
context->stack_size);
|
274
|
-
push_frame(context_object, RSTRING_PTR(path), FIX2INT(lineno), method_id,
|
275
|
-
defined_class, binding, self);
|
277
|
+
push_frame(context, RSTRING_PTR(path), FIX2INT(lineno), method_id,
|
278
|
+
defined_class, binding, self);
|
276
279
|
|
277
280
|
breakpoint = find_breakpoint_by_method(breakpoints, defined_class,
|
278
281
|
SYM2ID(method_id),
|
@@ -290,30 +293,27 @@ process_call_event(VALUE trace_point, void *data)
|
|
290
293
|
static void
|
291
294
|
process_raise_event(VALUE trace_point, void *data)
|
292
295
|
{
|
293
|
-
|
294
|
-
VALUE context_object;
|
296
|
+
EVENT_SETUP;
|
295
297
|
VALUE expn_class, aclass;
|
296
298
|
VALUE err = rb_errinfo();
|
297
299
|
VALUE ancestors;
|
298
|
-
debug_context_t *context;
|
299
300
|
int i;
|
300
301
|
|
301
|
-
|
302
|
-
Data_Get_Struct(context_object, debug_context_t, context);
|
303
|
-
if (!check_start_processing(context, rb_thread_current())) return;
|
304
|
-
|
305
|
-
load_frame_info(
|
306
|
-
trace_point, &path, &lineno, &method_id, &defined_class, &binding, &self);
|
307
|
-
if (debug == Qtrue)
|
308
|
-
printf("%s (stack_size: %d)\n", RSTRING_PTR(tp_inspect(trace_point)),
|
309
|
-
context->stack_size);
|
310
|
-
update_frame(context_object, RSTRING_PTR(path), FIX2INT(lineno), method_id,
|
302
|
+
update_frame(context->stack, RSTRING_PTR(path), FIX2INT(lineno), method_id,
|
311
303
|
defined_class, binding, self);
|
312
304
|
|
305
|
+
if (post_mortem == Qtrue && self)
|
306
|
+
{
|
307
|
+
VALUE binding = rb_binding_new();
|
308
|
+
rb_ivar_set(rb_errinfo(), rb_intern("@__debug_file"), path);
|
309
|
+
rb_ivar_set(rb_errinfo(), rb_intern("@__debug_line"), lineno);
|
310
|
+
rb_ivar_set(rb_errinfo(), rb_intern("@__debug_binding"), binding);
|
311
|
+
rb_ivar_set(rb_errinfo(), rb_intern("@__debug_context"), Context_dup(context));
|
312
|
+
}
|
313
|
+
|
313
314
|
expn_class = rb_obj_class(err);
|
314
315
|
|
315
|
-
if (catchpoints == Qnil ||
|
316
|
-
context->stack_size == 0 ||
|
316
|
+
if (catchpoints == Qnil || context->stack_size == 0 ||
|
317
317
|
CTX_FL_TEST(context, CTX_FL_CATCHING) ||
|
318
318
|
RHASH_TBL(catchpoints)->num_entries == 0) {
|
319
319
|
cleanup(context);
|
@@ -353,22 +353,34 @@ Byebug_setup_tracepoints(VALUE self)
|
|
353
353
|
catchpoints = rb_hash_new();
|
354
354
|
|
355
355
|
tpLine = rb_tracepoint_new(Qnil,
|
356
|
-
|
357
|
-
|
358
|
-
|
356
|
+
RUBY_EVENT_LINE,
|
357
|
+
process_line_event, NULL);
|
358
|
+
|
359
|
+
tpCall = rb_tracepoint_new(Qnil,
|
360
|
+
RUBY_EVENT_CALL | RUBY_EVENT_B_CALL | RUBY_EVENT_CLASS,
|
361
|
+
process_call_event, NULL);
|
362
|
+
|
363
|
+
tpCCall = rb_tracepoint_new(Qnil,
|
364
|
+
RUBY_EVENT_C_CALL,
|
365
|
+
process_c_call_event, NULL);
|
359
366
|
|
360
367
|
tpReturn = rb_tracepoint_new(Qnil,
|
361
|
-
|
362
|
-
|
363
|
-
rb_tracepoint_enable(tpReturn);
|
368
|
+
RUBY_EVENT_RETURN | RUBY_EVENT_B_RETURN | RUBY_EVENT_END,
|
369
|
+
process_return_event, NULL);
|
364
370
|
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
rb_tracepoint_enable(tpCall);
|
371
|
+
tpCReturn = rb_tracepoint_new(Qnil,
|
372
|
+
RUBY_EVENT_C_RETURN,
|
373
|
+
process_c_return_event, NULL);
|
369
374
|
|
370
375
|
tpRaise = rb_tracepoint_new(Qnil,
|
371
|
-
|
376
|
+
RUBY_EVENT_RAISE,
|
377
|
+
process_raise_event, NULL);
|
378
|
+
|
379
|
+
rb_tracepoint_enable(tpLine);
|
380
|
+
rb_tracepoint_enable(tpCall);
|
381
|
+
rb_tracepoint_enable(tpCCall);
|
382
|
+
rb_tracepoint_enable(tpReturn);
|
383
|
+
rb_tracepoint_enable(tpCReturn);
|
372
384
|
rb_tracepoint_enable(tpRaise);
|
373
385
|
|
374
386
|
return Qnil;
|
@@ -381,14 +393,30 @@ Byebug_remove_tracepoints(VALUE self)
|
|
381
393
|
breakpoints = Qnil;
|
382
394
|
catchpoints = Qnil;
|
383
395
|
|
384
|
-
if (tpLine != Qnil)
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
if (tpCall != Qnil)
|
389
|
-
|
390
|
-
|
391
|
-
|
396
|
+
if (tpLine != Qnil) {
|
397
|
+
rb_tracepoint_disable(tpLine);
|
398
|
+
tpLine = Qnil;
|
399
|
+
}
|
400
|
+
if (tpCall != Qnil) {
|
401
|
+
rb_tracepoint_disable(tpCall);
|
402
|
+
tpCall = Qnil;
|
403
|
+
}
|
404
|
+
if (tpCCall != Qnil) {
|
405
|
+
rb_tracepoint_disable(tpCCall);
|
406
|
+
tpCCall = Qnil;
|
407
|
+
}
|
408
|
+
if (tpReturn != Qnil) {
|
409
|
+
rb_tracepoint_disable(tpReturn);
|
410
|
+
tpReturn = Qnil;
|
411
|
+
}
|
412
|
+
if (tpCReturn != Qnil) {
|
413
|
+
rb_tracepoint_disable(tpCReturn);
|
414
|
+
tpCReturn = Qnil;
|
415
|
+
}
|
416
|
+
if (tpRaise != Qnil) {
|
417
|
+
rb_tracepoint_disable(tpRaise);
|
418
|
+
tpRaise = Qnil;
|
419
|
+
}
|
392
420
|
return Qnil;
|
393
421
|
}
|
394
422
|
|
@@ -399,16 +427,17 @@ values_i(VALUE key, VALUE value, VALUE ary)
|
|
399
427
|
return ST_CONTINUE;
|
400
428
|
}
|
401
429
|
|
430
|
+
#define BYEBUG_STARTED (catchpoints != Qnil)
|
402
431
|
static VALUE
|
403
432
|
Byebug_started(VALUE self)
|
404
433
|
{
|
405
|
-
return
|
434
|
+
return BYEBUG_STARTED;
|
406
435
|
}
|
407
436
|
|
408
437
|
static VALUE
|
409
438
|
Byebug_stop(VALUE self)
|
410
439
|
{
|
411
|
-
if (
|
440
|
+
if (BYEBUG_STARTED)
|
412
441
|
{
|
413
442
|
Byebug_remove_tracepoints(self);
|
414
443
|
return Qfalse;
|
@@ -421,7 +450,7 @@ Byebug_start(VALUE self)
|
|
421
450
|
{
|
422
451
|
VALUE result;
|
423
452
|
|
424
|
-
if (
|
453
|
+
if (BYEBUG_STARTED)
|
425
454
|
result = Qfalse;
|
426
455
|
else
|
427
456
|
{
|
@@ -435,6 +464,21 @@ Byebug_start(VALUE self)
|
|
435
464
|
return result;
|
436
465
|
}
|
437
466
|
|
467
|
+
static VALUE
|
468
|
+
set_current_skipped_status(VALUE status)
|
469
|
+
{
|
470
|
+
VALUE context_object;
|
471
|
+
debug_context_t *context;
|
472
|
+
|
473
|
+
context_object = Byebug_current_context(mByebug);
|
474
|
+
Data_Get_Struct(context_object, debug_context_t, context);
|
475
|
+
if (status)
|
476
|
+
CTX_FL_SET(context, CTX_FL_SKIPPED);
|
477
|
+
else
|
478
|
+
CTX_FL_UNSET(context, CTX_FL_SKIPPED);
|
479
|
+
return Qnil;
|
480
|
+
}
|
481
|
+
|
438
482
|
static VALUE
|
439
483
|
Byebug_load(int argc, VALUE *argv, VALUE self)
|
440
484
|
{
|
@@ -466,24 +510,65 @@ Byebug_load(int argc, VALUE *argv, VALUE self)
|
|
466
510
|
return errinfo;
|
467
511
|
}
|
468
512
|
|
469
|
-
/* We should run all at_exit handler's in order to provide,
|
470
|
-
*
|
513
|
+
/* We should run all at_exit handler's in order to provide, for instance, a
|
514
|
+
* chance to run all defined test cases */
|
471
515
|
rb_exec_end_proc();
|
472
516
|
|
473
517
|
return Qnil;
|
474
518
|
}
|
475
519
|
|
520
|
+
static VALUE
|
521
|
+
debug_at_exit_c(VALUE proc)
|
522
|
+
{
|
523
|
+
return rb_funcall(proc, rb_intern("call"), 0);
|
524
|
+
}
|
525
|
+
|
526
|
+
static void
|
527
|
+
debug_at_exit_i(VALUE proc)
|
528
|
+
{
|
529
|
+
if (BYEBUG_STARTED)
|
530
|
+
{
|
531
|
+
set_current_skipped_status(Qtrue);
|
532
|
+
rb_ensure(debug_at_exit_c, proc, set_current_skipped_status, Qfalse);
|
533
|
+
}
|
534
|
+
else
|
535
|
+
debug_at_exit_c(proc);
|
536
|
+
}
|
537
|
+
|
538
|
+
static VALUE
|
539
|
+
Byebug_at_exit(VALUE self)
|
540
|
+
{
|
541
|
+
VALUE proc;
|
542
|
+
if (!rb_block_given_p()) rb_raise(rb_eArgError, "called without a block");
|
543
|
+
proc = rb_block_proc();
|
544
|
+
rb_set_end_proc(debug_at_exit_i, proc);
|
545
|
+
return proc;
|
546
|
+
}
|
547
|
+
|
476
548
|
static VALUE
|
477
549
|
Byebug_tracing(VALUE self)
|
478
550
|
{
|
479
|
-
|
551
|
+
return tracing;
|
480
552
|
}
|
481
553
|
|
482
554
|
static VALUE
|
483
555
|
Byebug_set_tracing(VALUE self, VALUE value)
|
484
556
|
{
|
485
|
-
|
486
|
-
|
557
|
+
tracing = RTEST(value) ? Qtrue : Qfalse;
|
558
|
+
return value;
|
559
|
+
}
|
560
|
+
|
561
|
+
static VALUE
|
562
|
+
Byebug_post_mortem(VALUE self)
|
563
|
+
{
|
564
|
+
return post_mortem;
|
565
|
+
}
|
566
|
+
|
567
|
+
static VALUE
|
568
|
+
Byebug_set_post_mortem(VALUE self, VALUE value)
|
569
|
+
{
|
570
|
+
post_mortem = RTEST(value) ? Qtrue : Qfalse;
|
571
|
+
return value;
|
487
572
|
}
|
488
573
|
|
489
574
|
static VALUE
|
@@ -494,7 +579,7 @@ Byebug_contexts(VALUE self)
|
|
494
579
|
ary = rb_ary_new();
|
495
580
|
|
496
581
|
/* check that all contexts point to alive threads */
|
497
|
-
rb_hash_foreach(contexts, remove_dead_threads,
|
582
|
+
/*rb_hash_foreach(contexts, remove_dead_threads, self);*/
|
498
583
|
|
499
584
|
rb_hash_foreach(contexts, values_i, ary);
|
500
585
|
|
@@ -551,11 +636,12 @@ Init_byebug()
|
|
551
636
|
rb_define_module_function(mByebug, "_start", Byebug_start, 0);
|
552
637
|
rb_define_module_function(mByebug, "stop", Byebug_stop, 0);
|
553
638
|
rb_define_module_function(mByebug, "started?", Byebug_started, 0);
|
554
|
-
rb_define_module_function(mByebug, "tracing", Byebug_tracing, 0);
|
639
|
+
rb_define_module_function(mByebug, "tracing?", Byebug_tracing, 0);
|
555
640
|
rb_define_module_function(mByebug, "tracing=", Byebug_set_tracing, 1);
|
556
641
|
rb_define_module_function(mByebug, "debug_load", Byebug_load, -1);
|
557
|
-
|
558
|
-
|
642
|
+
rb_define_module_function(mByebug, "debug_at_exit", Byebug_at_exit, 0);
|
643
|
+
rb_define_module_function(mByebug, "post_mortem?", Byebug_post_mortem, 0);
|
644
|
+
rb_define_module_function(mByebug, "post_mortem=", Byebug_set_post_mortem, 1);
|
559
645
|
|
560
646
|
cContext = Init_context(mByebug);
|
561
647
|
|