byebug 3.4.2 → 3.5.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/GUIDE.md +88 -15
- data/lib/byebug/attacher.rb +1 -0
- data/lib/byebug/commands/enable_disable.rb +1 -1
- data/lib/byebug/commands/frame.rb +1 -1
- data/lib/byebug/commands/history.rb +3 -6
- data/lib/byebug/commands/list.rb +60 -50
- data/lib/byebug/commands/pry.rb +1 -8
- data/lib/byebug/commands/restart.rb +1 -6
- data/lib/byebug/commands/save.rb +5 -19
- data/lib/byebug/commands/undisplay.rb +2 -2
- data/lib/byebug/core.rb +11 -19
- data/lib/byebug/helper.rb +2 -2
- data/lib/byebug/history.rb +86 -26
- data/lib/byebug/interface.rb +13 -2
- data/lib/byebug/interfaces/local_interface.rb +4 -12
- data/lib/byebug/interfaces/remote_interface.rb +0 -3
- data/lib/byebug/processors/command_processor.rb +45 -22
- data/lib/byebug/runner.rb +7 -4
- data/lib/byebug/version.rb +1 -1
- data/test/commands/history_test.rb +35 -19
- data/test/commands/list_test.rb +8 -24
- data/test/commands/pry_test.rb +1 -8
- data/test/commands/restart_test.rb +4 -22
- data/test/commands/save_test.rb +4 -4
- data/test/commands/set_test.rb +1 -0
- data/test/runner_test.rb +26 -19
- data/test/support/test_interface.rb +19 -15
- data/test/test_helper.rb +2 -5
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e311c958672db924c18ba6c50b079b8d0b02071
|
4
|
+
data.tar.gz: 9b5b874f7334cf8f2de778c6587d87717b79b780
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6804f3c19226009adecad6208753584bf3b9364e290c70b7be4e3ae92a8d7e300f4f6bb5a2aec029b7c3ac9df4ded55efa144ff7fff530364fec7d7058f42b10
|
7
|
+
data.tar.gz: 25f86abebed81ad2667b6fea393c8f4404d46d2556688fa900da8e5c5c45a223485eadab5ec0f599d9a62f978b597f379b625d182649ce7b95fa8cf0687980a9
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
# 3.5.0
|
2
|
+
- Bugfixes
|
3
|
+
* Fix #81, byebug's history does not mess with other programs that use
|
4
|
+
Readline too.
|
5
|
+
* Fix more issues with readline's history. Now it should always be properly
|
6
|
+
saved and inmediately available.
|
7
|
+
* Fix issue where user would not be notified when trying to debug a non
|
8
|
+
existent script.
|
9
|
+
|
10
|
+
- Improvements
|
11
|
+
* Complete rewrite of byebug's history.
|
12
|
+
* Complete rewrite of list command.
|
13
|
+
* Docs about stacktrace related commands (up, down, frame, backtrace).
|
14
|
+
|
15
|
+
|
1
16
|
# 3.4.2
|
2
17
|
* Fix #67, you can debug commands starting with `ruby` now, as in `byebug --
|
3
18
|
ruby -Itest test/controllers/posts_controller_test.rb -n test_should_get_index`
|
data/GUIDE.md
CHANGED
@@ -941,18 +941,18 @@ want to debug, add a call to `byebug` as was done without remote execution:
|
|
941
941
|
## Byebug Command Reference
|
942
942
|
|
943
943
|
### Command Syntax
|
944
|
-
Usually a command is put on a single line. There is no limit on how long it can
|
945
|
-
It starts with a command name, which is followed by arguments whose meaning
|
946
|
-
on the command name. For example, the command `step` accepts an
|
947
|
-
number of times to step, as in `step 5`. You can also use
|
948
|
-
arguments. Some commands do not allow any arguments.
|
944
|
+
Usually a command is put on a single line. There is no limit on how long it can
|
945
|
+
be. It starts with a command name, which is followed by arguments whose meaning
|
946
|
+
depends on the command name. For example, the command `step` accepts an
|
947
|
+
argument which is the number of times to step, as in `step 5`. You can also use
|
948
|
+
the `step` command with no arguments. Some commands do not allow any arguments.
|
949
949
|
|
950
|
-
Multiple commands can be put on a line by separating each with a semicolon `;`.
|
951
|
-
can disable the meaning of a semicolon to separate commands by escaping it
|
952
|
-
backslash.
|
950
|
+
Multiple commands can be put on a line by separating each with a semicolon `;`.
|
951
|
+
You can disable the meaning of a semicolon to separate commands by escaping it
|
952
|
+
with a backslash.
|
953
953
|
|
954
|
-
For example, if you have [autoeval]() set, which is the default, you might want
|
955
|
-
enter the following code to compute the 5th Fibonacci number.
|
954
|
+
For example, if you have [autoeval]() set, which is the default, you might want
|
955
|
+
to enter the following code to compute the 5th Fibonacci number.
|
956
956
|
|
957
957
|
```bash
|
958
958
|
(byebug) fib1=0; fib2=1; 5.times {|temp| temp=fib1; fib1=fib2; fib2 += temp }
|
@@ -975,10 +975,11 @@ nil
|
|
975
975
|
8
|
976
976
|
```
|
977
977
|
|
978
|
-
You might also consider using the [irb]() or [pry]() commands and then you
|
979
|
-
to escape semicolons.
|
978
|
+
You might also consider using the [irb]() or [pry]() commands and then you
|
979
|
+
won't have to escape semicolons.
|
980
980
|
|
981
|
-
A blank line as input (typing just `<RET>`) means to repeat the previous
|
981
|
+
A blank line as input (typing just `<RET>`) means to repeat the previous
|
982
|
+
command.
|
982
983
|
|
983
984
|
Byebug uses readline, which handles line editing and retrieval of previous commands.
|
984
985
|
Up arrow, for example, moves to the previous byebug command; down arrow moves to the
|
@@ -1309,7 +1310,7 @@ same as running `ps <object>.instance_methods(false)`.
|
|
1309
1310
|
`<class-or-module>`. Basically this is the same as running
|
1310
1311
|
`ps <class-or-module>.methods`.
|
1311
1312
|
|
1312
|
-
### Examining Program Source Files
|
1313
|
+
### Examining Program Source Files: list
|
1313
1314
|
|
1314
1315
|
`byebug` can print parts of your script's source. When your script stops,
|
1315
1316
|
`byebug` spontaneously lists the source code around the line where it stopped
|
@@ -1342,7 +1343,7 @@ equivalent to typing just `list`. This is more useful than listing the same
|
|
1342
1343
|
lines again. An exception is made for an argument of `-`: that argument is
|
1343
1344
|
preserved in repetition so that each repetition moves up in the source file.
|
1344
1345
|
|
1345
|
-
### Editing Source files
|
1346
|
+
### Editing Source files: edit
|
1346
1347
|
|
1347
1348
|
To edit a source file, use the `edit` command. The editor of your choice is invoked
|
1348
1349
|
with the current line set to the active line in the program. Alternatively, you can
|
@@ -1370,3 +1371,75 @@ or in the `csh` shell,
|
|
1370
1371
|
setenv EDITOR /usr/bin/vi
|
1371
1372
|
byebug ...
|
1372
1373
|
```
|
1374
|
+
|
1375
|
+
### The stack trace
|
1376
|
+
|
1377
|
+
When your script has stopped, one thing you'll probably want to know is where
|
1378
|
+
it stopped and some idea of how it got there.
|
1379
|
+
|
1380
|
+
Each time your script calls a method or enters a block, information about this
|
1381
|
+
action is saved. This information is what we call a _stack frame_ or just a
|
1382
|
+
_frame_. The set of all frames at a certain point in the program's execution is
|
1383
|
+
called the _stack trace_ or just the _stack_. Each frame contains a line number
|
1384
|
+
and the source-file name that the line refers to. If the frame is the beginning
|
1385
|
+
of a method it also contains the method name.
|
1386
|
+
|
1387
|
+
When your script is started, the stack has only one frame, that of the `main`
|
1388
|
+
method. This is called the _initial frame_ or the _outermost frame_. Each time
|
1389
|
+
a method is called, a new frame is added to the stack trace. Each time a method
|
1390
|
+
returns, the frame for that method invocation is removed. If a method is
|
1391
|
+
recursive, there can be many frames for the same method. The frame for the
|
1392
|
+
method in which execution is actually occurring is called the _innermost
|
1393
|
+
frame_. This is the most recently created of all the stack frames that still
|
1394
|
+
exist.
|
1395
|
+
|
1396
|
+
Every time the debugger stops, one entry in the stack is selected as the
|
1397
|
+
current frame. Many byebug commands refer implicitly to the selected block. In
|
1398
|
+
particular, whenever you ask Byebug to list lines without giving a line number
|
1399
|
+
or location the value is found in the selected frame. There are special
|
1400
|
+
commands to select whichever frame you're interested in, such as `up`, `down`
|
1401
|
+
and `frame`.
|
1402
|
+
|
1403
|
+
After switching frames, when you issue a `list` command without any position
|
1404
|
+
information, the position used is the location in the frame that you just
|
1405
|
+
switched between, rather than a location that got updated via a prior `list`
|
1406
|
+
command.
|
1407
|
+
|
1408
|
+
Byebug assigns numbers to all existing stack frames, starting with zero for the
|
1409
|
+
_innermost frame_, one for the frame that called it, and so on upward. These
|
1410
|
+
numbers do not really exist in your script, they are assigned by Byebug to give
|
1411
|
+
you a way of designating stack frames in commands.
|
1412
|
+
|
1413
|
+
### Printing the Stack: `where` command
|
1414
|
+
|
1415
|
+
The command `where`, aliased to `bt` or `backtrace` prints the call stack., It
|
1416
|
+
shows one line per frame, for many frames, starting with the place that you are
|
1417
|
+
stopped at (frame zero), followed by its caller (frame one), and on up the
|
1418
|
+
stack. Each frame is numbered and can be referred to in the `frame` command.
|
1419
|
+
The position of the current frame is marked with `-->`.
|
1420
|
+
|
1421
|
+
The are some special frames generated for methods that are implemented in C.
|
1422
|
+
One such method is `each`. They are marked differently in the call stack to
|
1423
|
+
indicate that we cannot switch to those frames. This is because they have no
|
1424
|
+
source code in Ruby, so we can not debug them using Byebug.
|
1425
|
+
|
1426
|
+
```bash
|
1427
|
+
(byebug) where
|
1428
|
+
--> #0 Object.gcd(a#Fixnum, b#Fixnum) at line gcd.rb:6
|
1429
|
+
#1 at line gcd.rb:19
|
1430
|
+
```
|
1431
|
+
|
1432
|
+
### Selecting a frame: `up`, `down` and `frame` commands
|
1433
|
+
|
1434
|
+
* `up <n>`: Move `n` frames up the stack, towards the outermost frame (higher
|
1435
|
+
frame numbers, frames that have existed longer). `n` defaults to one.
|
1436
|
+
|
1437
|
+
* `down <n>`: Move `n` frames down the stack, towards the _innermost frame_
|
1438
|
+
(lower frame numbers, frames that were created more recently). `n` defaults to
|
1439
|
+
one.
|
1440
|
+
|
1441
|
+
* `frame <n>`: Allows you to move to an arbitrary frame. `n` is the stack frame
|
1442
|
+
number or 0 if no frame number is given. `frame 0` will show the current and
|
1443
|
+
most recent stack frame. If a negative number is given, counting is from the
|
1444
|
+
other end of the stack frame, so `frame -1` shows the least-recent, outermost
|
1445
|
+
stack frame. Without an argument, `frame` prints the current stack frame.
|
data/lib/byebug/attacher.rb
CHANGED
@@ -45,7 +45,7 @@ module Byebug
|
|
45
45
|
@state.frame_pos = abs_frame_pos
|
46
46
|
@state.file = @state.context.frame_file @state.frame_pos
|
47
47
|
@state.line = @state.context.frame_line @state.frame_pos
|
48
|
-
@state.
|
48
|
+
@state.prev_line = nil
|
49
49
|
ListCommand.new(@state).execute
|
50
50
|
end
|
51
51
|
|
@@ -8,17 +8,14 @@ module Byebug
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def execute
|
11
|
-
|
12
|
-
return errmsg('Not currently saving history. ' \
|
13
|
-
"Enable it with \"set autosave\"")
|
14
|
-
end
|
11
|
+
history = @state.interface.history
|
15
12
|
|
16
13
|
if @match[:num_cmds]
|
17
|
-
size,
|
14
|
+
size, _ = get_int(@match[:num_cmds], 'history', 1, history.size)
|
18
15
|
return errmsg(err) unless size
|
19
16
|
end
|
20
17
|
|
21
|
-
puts
|
18
|
+
puts history.to_s(size)
|
22
19
|
end
|
23
20
|
|
24
21
|
class << self
|
data/lib/byebug/commands/list.rb
CHANGED
@@ -11,17 +11,14 @@ module Byebug
|
|
11
11
|
Byebug.source_reload if Setting[:autoreload]
|
12
12
|
|
13
13
|
lines = get_lines(@state.file)
|
14
|
-
unless lines
|
15
|
-
errmsg "No sourcefile available for #{@state.file}\n"
|
16
|
-
return @state.previous_line
|
17
|
-
end
|
18
|
-
|
19
|
-
b, e = set_line_range(Setting[:listsize], lines.size)
|
20
|
-
return @state.previous_line if b < 0
|
14
|
+
return errmsg "No sourcefile available for #{@state.file}\n" unless lines
|
21
15
|
|
16
|
+
@match ||= match('list')
|
17
|
+
b, e = range(@match[2], lines.size)
|
18
|
+
return errmsg('Invalid line range') unless valid_range?(b, e, lines.size)
|
22
19
|
display_lines(b, e, lines)
|
23
20
|
|
24
|
-
@state.
|
21
|
+
@state.prev_line = b
|
25
22
|
end
|
26
23
|
|
27
24
|
class << self
|
@@ -42,57 +39,70 @@ module Byebug
|
|
42
39
|
|
43
40
|
private
|
44
41
|
|
45
|
-
|
42
|
+
#
|
43
|
+
# Line range to be printed by `list`.
|
44
|
+
#
|
45
|
+
# If <input> is set, range is parsed from it.
|
46
|
+
#
|
47
|
+
# Otherwise it's automatically chosen.
|
48
|
+
#
|
49
|
+
def range(input, max_line)
|
50
|
+
size = [Setting[:listsize], max_line].min
|
51
|
+
|
52
|
+
return set_range(size, max_line) unless input
|
53
|
+
|
54
|
+
parse_range(input, size, max_line)
|
55
|
+
end
|
56
|
+
|
57
|
+
def valid_range?(first, last, max)
|
58
|
+
first <= last && (1..max).include?(first) && (1..max).include?(last)
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
46
62
|
# Set line range to be printed by list
|
47
63
|
#
|
48
|
-
# @param
|
49
|
-
# @param
|
64
|
+
# @param size - number of lines to be printed
|
65
|
+
# @param max_line - max line number that can be printed
|
50
66
|
#
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
@state.previous_line = nil
|
70
|
-
b = @state.line - (listsize / 2)
|
67
|
+
# @return first line number to list
|
68
|
+
# @return last line number to list
|
69
|
+
#
|
70
|
+
def set_range(size, max_line)
|
71
|
+
first = amend(lower(size, @match[1] || '+'), size, max_line - size + 1)
|
72
|
+
|
73
|
+
[first, move(first, size - 1)]
|
74
|
+
end
|
75
|
+
|
76
|
+
def parse_range(input, size, max_line)
|
77
|
+
first, err = get_int(input.split(/[-,]/)[0], 'List', 1, max_line)
|
78
|
+
return [-1, -1] if err
|
79
|
+
|
80
|
+
if input.split(/[-,]/)[1]
|
81
|
+
last, err = get_int(input.split(/[-,]/)[1], 'List', 1, max_line)
|
82
|
+
return [-1, -1] unless last
|
83
|
+
|
84
|
+
last = amend(last, size, max_line)
|
71
85
|
else
|
72
|
-
|
73
|
-
if e
|
74
|
-
b = b.to_i
|
75
|
-
e = e.to_i
|
76
|
-
else
|
77
|
-
b = b.to_i - (listsize / 2)
|
78
|
-
end
|
86
|
+
first -= (size / 2)
|
79
87
|
end
|
80
88
|
|
81
|
-
|
82
|
-
|
83
|
-
return [-1, -1]
|
84
|
-
end
|
89
|
+
[first, last || move(first, size - 1)]
|
90
|
+
end
|
85
91
|
|
86
|
-
|
87
|
-
|
92
|
+
def amend(line, size, max_line)
|
93
|
+
return 1 if line < 1
|
88
94
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
95
|
+
[max_line, line].min
|
96
|
+
end
|
97
|
+
|
98
|
+
def lower(size, direction = '+')
|
99
|
+
return @state.line - size / 2 if direction == '=' || !@state.prev_line
|
100
|
+
|
101
|
+
move(@state.prev_line, size, direction)
|
102
|
+
end
|
94
103
|
|
95
|
-
|
104
|
+
def move(line, size, direction = '+')
|
105
|
+
line.send(direction, size)
|
96
106
|
end
|
97
107
|
|
98
108
|
#
|
data/lib/byebug/commands/pry.rb
CHANGED
@@ -12,10 +12,6 @@ module Byebug
|
|
12
12
|
def execute
|
13
13
|
prog = Byebug.debugged_program
|
14
14
|
|
15
|
-
unless File.exist?(File.expand_path(prog))
|
16
|
-
return errmsg("Ruby program #{prog} doesn't exist")
|
17
|
-
end
|
18
|
-
|
19
15
|
if defined?(BYEBUG_SCRIPT)
|
20
16
|
cmd = "#{BYEBUG_SCRIPT} #{prog}"
|
21
17
|
else
|
@@ -23,8 +19,7 @@ module Byebug
|
|
23
19
|
if File.executable?(prog)
|
24
20
|
cmd = prog
|
25
21
|
else
|
26
|
-
puts "
|
27
|
-
"We'll wrap it in a ruby call"
|
22
|
+
puts "Program #{prog} not executable... Wrapping it in a ruby call"
|
28
23
|
cmd = "ruby -rbyebug -I#{$LOAD_PATH.join(' -I')} #{prog}"
|
29
24
|
end
|
30
25
|
end
|
data/lib/byebug/commands/save.rb
CHANGED
@@ -1,19 +1,8 @@
|
|
1
1
|
module Byebug
|
2
2
|
#
|
3
|
-
#
|
3
|
+
# Default file where commands are saved
|
4
4
|
#
|
5
|
-
|
6
|
-
# Create a temporary file to write in if file is nil
|
7
|
-
def open_save
|
8
|
-
require 'tempfile'
|
9
|
-
file = Tempfile.new('byebug-save')
|
10
|
-
# We want close to not unlink, so redefine.
|
11
|
-
def file.close
|
12
|
-
@tmpfile.close if @tmpfile
|
13
|
-
end
|
14
|
-
file
|
15
|
-
end
|
16
|
-
end
|
5
|
+
RESTART_FILE = '.byebug-save' unless defined?(RESTART_FILE)
|
17
6
|
|
18
7
|
#
|
19
8
|
# Save current settings to use them in another debug session.
|
@@ -48,17 +37,14 @@ module Byebug
|
|
48
37
|
end
|
49
38
|
|
50
39
|
def execute
|
51
|
-
|
52
|
-
|
53
|
-
else
|
54
|
-
file = open(@match[1], 'w')
|
55
|
-
end
|
40
|
+
file = open(@match[1] || RESTART_FILE, 'w')
|
41
|
+
|
56
42
|
save_breakpoints(file)
|
57
43
|
save_catchpoints(file)
|
58
44
|
save_displays(file)
|
59
45
|
save_settings(file)
|
46
|
+
|
60
47
|
puts "Saved to '#{file.path}'"
|
61
|
-
@state.interface.restart_file = file.path if @state && @state.interface
|
62
48
|
file.close
|
63
49
|
end
|
64
50
|
|
@@ -11,8 +11,8 @@ module Byebug
|
|
11
11
|
|
12
12
|
def execute
|
13
13
|
if @match[1]
|
14
|
-
pos, err = get_int(@match[1], 'Undisplay')
|
15
|
-
return errmsg(err) unless
|
14
|
+
pos, err = get_int(@match[1], 'Undisplay', 1, @state.display.size)
|
15
|
+
return errmsg(err) unless err.nil?
|
16
16
|
|
17
17
|
unless @state.display[pos - 1]
|
18
18
|
return errmsg("Display expression #{pos} is not defined.")
|
data/lib/byebug/core.rb
CHANGED
@@ -12,26 +12,25 @@ require 'tracer'
|
|
12
12
|
require 'linecache19'
|
13
13
|
|
14
14
|
module Byebug
|
15
|
+
#
|
15
16
|
# List of files byebug will ignore while debugging
|
17
|
+
#
|
16
18
|
IGNORED_FILES = Dir.glob(File.expand_path('../**/*.rb', __FILE__))
|
17
19
|
|
20
|
+
#
|
18
21
|
# Configuration file used for startup commands. Default value is .byebugrc
|
19
|
-
|
22
|
+
#
|
23
|
+
INIT_FILE = '.byebugrc' unless defined?(INIT_FILE)
|
20
24
|
|
21
25
|
class << self
|
22
|
-
attr_accessor :handler
|
23
|
-
|
26
|
+
attr_accessor :handler, :debugged_program
|
27
|
+
|
28
|
+
extend Forwardable
|
29
|
+
def_delegators :handler, :errmsg, :puts
|
24
30
|
end
|
25
31
|
|
26
32
|
Byebug.handler = CommandProcessor.new
|
27
33
|
|
28
|
-
#
|
29
|
-
# Program being debugged (or a default one if not set yet)
|
30
|
-
#
|
31
|
-
def self.debugged_program
|
32
|
-
@debugged_program ||= $PROGRAM_NAME
|
33
|
-
end
|
34
|
-
|
35
34
|
def self.source_reload
|
36
35
|
hsh = 'SCRIPT_LINES__'
|
37
36
|
Object.send(:remove_const, hsh) if Object.const_defined?(hsh)
|
@@ -45,13 +44,6 @@ module Byebug
|
|
45
44
|
handler.interface = value
|
46
45
|
end
|
47
46
|
|
48
|
-
#
|
49
|
-
# Byebug's prints according to its handler's interface
|
50
|
-
#
|
51
|
-
def self.puts(message)
|
52
|
-
handler.interface.puts(message)
|
53
|
-
end
|
54
|
-
|
55
47
|
#
|
56
48
|
# Runs normal byebug initialization scripts.
|
57
49
|
#
|
@@ -62,10 +54,10 @@ module Byebug
|
|
62
54
|
# program you are debugging, in the directory where you invoke byebug.
|
63
55
|
#
|
64
56
|
def self.run_init_script(out = handler.interface)
|
65
|
-
cwd_script = File.expand_path(File.join('.',
|
57
|
+
cwd_script = File.expand_path(File.join('.', INIT_FILE))
|
66
58
|
run_script(cwd_script, out, true) if File.exist?(cwd_script)
|
67
59
|
|
68
|
-
home_script = File.expand_path(File.join(ENV['HOME'].to_s,
|
60
|
+
home_script = File.expand_path(File.join(ENV['HOME'].to_s, INIT_FILE))
|
69
61
|
if File.exist?(home_script) && cwd_script != home_script
|
70
62
|
run_script(home_script, out, true)
|
71
63
|
end
|