byebug 1.8.2 → 2.0.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 +8 -1
- data/GUIDE.md +14 -22
- data/README.md +69 -6
- data/bin/byebug +3 -20
- data/ext/byebug/breakpoint.c +185 -101
- data/ext/byebug/byebug.c +393 -214
- data/ext/byebug/byebug.h +34 -15
- data/ext/byebug/context.c +327 -102
- data/ext/byebug/extconf.rb +1 -1
- data/ext/byebug/locker.c +54 -0
- data/ext/byebug/threads.c +113 -0
- data/lib/byebug.rb +19 -58
- data/lib/byebug/command.rb +18 -19
- data/lib/byebug/commands/breakpoints.rb +1 -4
- data/lib/byebug/commands/catchpoint.rb +1 -1
- data/lib/byebug/commands/condition.rb +1 -1
- data/lib/byebug/commands/control.rb +2 -3
- data/lib/byebug/commands/display.rb +2 -7
- data/lib/byebug/commands/edit.rb +1 -1
- data/lib/byebug/commands/enable.rb +12 -12
- data/lib/byebug/commands/eval.rb +4 -4
- data/lib/byebug/commands/finish.rb +1 -1
- data/lib/byebug/commands/frame.rb +12 -8
- data/lib/byebug/commands/info.rb +20 -52
- data/lib/byebug/commands/kill.rb +1 -5
- data/lib/byebug/commands/list.rb +2 -1
- data/lib/byebug/commands/quit.rb +1 -1
- data/lib/byebug/commands/repl.rb +2 -2
- data/lib/byebug/commands/save.rb +1 -1
- data/lib/byebug/commands/set.rb +84 -90
- data/lib/byebug/commands/show.rb +44 -53
- data/lib/byebug/commands/skip.rb +1 -1
- data/lib/byebug/commands/stepping.rb +5 -4
- data/lib/byebug/commands/threads.rb +202 -0
- data/lib/byebug/commands/trace.rb +1 -1
- data/lib/byebug/helper.rb +3 -3
- data/lib/byebug/interface.rb +2 -20
- data/lib/byebug/processor.rb +21 -100
- data/lib/byebug/remote.rb +3 -3
- data/lib/byebug/version.rb +1 -1
- data/old_doc/byebug.1 +0 -6
- data/old_doc/byebug.texi +29 -46
- data/test/breakpoints_test.rb +44 -65
- data/test/conditions_test.rb +0 -9
- data/test/continue_test.rb +2 -2
- data/test/display_test.rb +4 -23
- data/test/edit_test.rb +2 -16
- data/test/eval_test.rb +4 -13
- data/test/examples/thread.rb +32 -0
- data/test/finish_test.rb +1 -13
- data/test/frame_test.rb +5 -12
- data/test/help_test.rb +2 -12
- data/test/info_test.rb +8 -18
- data/test/kill_test.rb +1 -10
- data/test/list_test.rb +5 -14
- data/test/method_test.rb +1 -10
- data/test/post_mortem_test.rb +247 -14
- data/test/quit_test.rb +0 -9
- data/test/reload_test.rb +1 -15
- data/test/repl_test.rb +1 -9
- data/test/restart_test.rb +3 -18
- data/test/save_test.rb +1 -13
- data/test/set_test.rb +35 -32
- data/test/show_test.rb +8 -27
- data/test/source_test.rb +1 -8
- data/test/stepping_test.rb +65 -96
- data/test/support/test_dsl.rb +12 -17
- data/test/test_helper.rb +1 -1
- data/test/thread_test.rb +106 -0
- data/test/trace_test.rb +5 -17
- data/test/variables_test.rb +1 -10
- metadata +9 -7
- data/lib/byebug/commands/jump.rb +0 -52
- data/test/jump_test.rb +0 -77
- data/test/support/context.rb +0 -15
data/lib/byebug/commands/show.rb
CHANGED
@@ -5,9 +5,6 @@ module Byebug
|
|
5
5
|
|
6
6
|
def show_setting(setting_name)
|
7
7
|
case setting_name
|
8
|
-
when /^annotate$/
|
9
|
-
Byebug.annotate ||= 0
|
10
|
-
return ("Annotation level is #{Byebug.annotate}")
|
11
8
|
when /^args$/
|
12
9
|
if Command.settings[:argv] and Command.settings[:argv].size > 0
|
13
10
|
if defined?(Byebug::BYEBUG_SCRIPT)
|
@@ -77,10 +74,10 @@ module Byebug
|
|
77
74
|
on_off = Command.settings[:testing]
|
78
75
|
return "Currently testing byebug is #{show_onoff(on_off)}."
|
79
76
|
when /^forcestep$/
|
80
|
-
on_off = Command.settings[:
|
77
|
+
on_off = Command.settings[:forcestep]
|
81
78
|
return "force-stepping is #{show_onoff(on_off)}."
|
82
79
|
when /^fullpath$/
|
83
|
-
on_off = Command.settings[:
|
80
|
+
on_off = Command.settings[:fullpath]
|
84
81
|
return "Displaying frame's full file names is #{show_onoff(on_off)}."
|
85
82
|
when /^history(:?\s+(filename|save|size))?$/
|
86
83
|
args = @match[1].split
|
@@ -119,21 +116,23 @@ module Byebug
|
|
119
116
|
when /^linetrace$/
|
120
117
|
on_off = Byebug.tracing?
|
121
118
|
return "line tracing is #{show_onoff(on_off)}."
|
122
|
-
when /^
|
123
|
-
|
124
|
-
if on_off
|
125
|
-
return "line tracing style is different consecutive lines."
|
126
|
-
else
|
119
|
+
when /^linetrace_plus$/
|
120
|
+
if Command.settings[:linetrace_plus]
|
127
121
|
return "line tracing style is every line."
|
122
|
+
else
|
123
|
+
return "line tracing style is different consecutive lines."
|
128
124
|
end
|
129
125
|
when /^listsize$/
|
130
126
|
listlines = Command.settings[:listsize]
|
131
127
|
return "Number of source lines to list is #{listlines}."
|
132
|
-
when /^
|
128
|
+
when /^post_mortem$/
|
129
|
+
on_off = Byebug.post_mortem?
|
130
|
+
return "post-mortem mode is #{show_onoff(on_off)}"
|
131
|
+
when /^stack_trace_on_error$/
|
133
132
|
on_off = Command.settings[:stack_trace_on_error]
|
134
133
|
return "Displaying stack trace is #{show_onoff(on_off)}."
|
135
134
|
when /^version$/
|
136
|
-
return "
|
135
|
+
return "Byebug #{Byebug::VERSION}"
|
137
136
|
when /^width$/
|
138
137
|
return "width is #{Command.settings[:width]}."
|
139
138
|
else
|
@@ -147,53 +146,45 @@ module Byebug
|
|
147
146
|
|
148
147
|
Subcommands =
|
149
148
|
[
|
150
|
-
['
|
151
|
-
'
|
152
|
-
'
|
153
|
-
'
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
['post-mortem', 3,
|
182
|
-
'Show whether we go into post-mortem debugging on an uncaught ' \
|
183
|
-
'exception'],
|
184
|
-
['trace', 1,
|
185
|
-
'Show whether a stack trace is displayed when "eval" raises an ' \
|
186
|
-
'exception'],
|
187
|
-
['version', 1, 'Show byebug\'s version'],
|
188
|
-
['width', 1, 'Show the number of characters per line for byebug']
|
149
|
+
['args', 2,
|
150
|
+
'Show argument list to the program being debugged when it is started',
|
151
|
+
'Follow this command with any number of args to be passed to the ' \
|
152
|
+
'program'],
|
153
|
+
['autoeval', 4, 'Show whether unrecognized commands are evaluated'],
|
154
|
+
['autolist', 4, 'Show whether "list" command is run on stopping'],
|
155
|
+
['autoirb', 4, 'Show whether IRB is invoked on stopping'],
|
156
|
+
['autoreload', 4, 'Show whether source code is reloaded when changed'],
|
157
|
+
['basename', 1, 'Show whether basename is used when reporting files'],
|
158
|
+
['callstyle', 2, 'Show paramater style used when showing call frames'],
|
159
|
+
['commands', 2, 'Show the history of commands you typed',
|
160
|
+
'You can supply a command number to start with'],
|
161
|
+
['forcestep', 1,
|
162
|
+
'Show whether "next/step" commands are set to always move to a line'],
|
163
|
+
['fullpath', 2, 'Show whether full paths are displayed in frames'],
|
164
|
+
['history', 2, 'Generic command to show command history parameters',
|
165
|
+
'show history filename -- Show the filename in which to record the ' \
|
166
|
+
'command history' \
|
167
|
+
'show history save -- Show whether history record should be saved ' \
|
168
|
+
'on exit' \
|
169
|
+
'show history size -- Show the size of the command history'],
|
170
|
+
['linetrace', 3, 'Show line execution tracing status'],
|
171
|
+
['linetrace_plus', 10,
|
172
|
+
'Show whether different consecutive lines are shown in tracing'],
|
173
|
+
['listsize', 3, 'Show number of source lines to list by default'],
|
174
|
+
['post-mortem', 3, 'Show whether we should go into post-mortem ' \
|
175
|
+
'debugging on an uncaught exception'],
|
176
|
+
['stack_trace_on_error', 1, 'Show whether a stack trace is displayed ' \
|
177
|
+
'when "eval" raises an exception'],
|
178
|
+
['version', 1, 'Show byebug\'s version'],
|
179
|
+
['width', 1, 'Show the number of characters per line for byebug']
|
189
180
|
].map do |name, min, short_help, long_help|
|
190
|
-
|
181
|
+
Subcmd.new(name, min, short_help, long_help)
|
191
182
|
end unless defined?(Subcommands)
|
192
183
|
|
193
184
|
self.allow_in_control = true
|
194
185
|
|
195
186
|
def regexp
|
196
|
-
/^\s* show (?:\s+(.+))? \s*$/
|
187
|
+
/^\s* show (?:\s+(.+))? \s*$/x
|
197
188
|
end
|
198
189
|
|
199
190
|
def execute
|
data/lib/byebug/commands/skip.rb
CHANGED
@@ -4,7 +4,7 @@ module Byebug
|
|
4
4
|
module SteppingFunctions
|
5
5
|
def parse_stepping_args(command_name, match)
|
6
6
|
if match[1].nil?
|
7
|
-
force = Command.settings[:
|
7
|
+
force = Command.settings[:forcestep]
|
8
8
|
elsif match[1] == '+'
|
9
9
|
force = true
|
10
10
|
elsif match[1] == '-'
|
@@ -39,7 +39,8 @@ module Byebug
|
|
39
39
|
def description
|
40
40
|
%{n[ext][+-]?[ nnn]\tstep over once or nnn times,
|
41
41
|
\t\t'+' forces to move to another line.
|
42
|
-
\t\t'-' is the opposite of '+' and disables the
|
42
|
+
\t\t'-' is the opposite of '+' and disables the :forcestep setting.
|
43
|
+
}
|
43
44
|
end
|
44
45
|
end
|
45
46
|
end
|
@@ -69,8 +70,8 @@ module Byebug
|
|
69
70
|
%{
|
70
71
|
s[tep][+-]?[ nnn]\tstep (into methods) once or nnn times
|
71
72
|
\t\t'+' forces to move to another line.
|
72
|
-
\t\t'-' is the opposite of '+' and disables the
|
73
|
-
|
73
|
+
\t\t'-' is the opposite of '+' and disables the :forcestep setting.
|
74
|
+
}
|
74
75
|
end
|
75
76
|
end
|
76
77
|
end
|
@@ -0,0 +1,202 @@
|
|
1
|
+
module Byebug
|
2
|
+
module ThreadFunctions
|
3
|
+
def display_context(context, should_show_top_frame = true)
|
4
|
+
args = thread_arguments(context, should_show_top_frame)
|
5
|
+
print "%s%s%d %s\t%s\n", args[:status_flag], args[:debug_flag], args[:id],
|
6
|
+
args[:thread], args[:file_line]
|
7
|
+
end
|
8
|
+
|
9
|
+
def thread_arguments(context, should_show_top_frame = true)
|
10
|
+
status_flag = if context.suspended?
|
11
|
+
"$"
|
12
|
+
else
|
13
|
+
context.thread == Thread.current ? '+' : ' '
|
14
|
+
end
|
15
|
+
debug_flag = context.ignored? ? '!' : ' '
|
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)
|
20
|
+
else
|
21
|
+
if context.thread.backtrace_locations && context.thread.backtrace_locations[0]
|
22
|
+
file = context.thread.backtrace_locations[0].path
|
23
|
+
line = context.thread.backtrace_locations[0].lineno
|
24
|
+
end
|
25
|
+
end
|
26
|
+
file_line = "#{file}:#{line}"
|
27
|
+
end
|
28
|
+
{
|
29
|
+
status_flag: status_flag,
|
30
|
+
debug_flag: debug_flag,
|
31
|
+
id: context.thnum,
|
32
|
+
thread: context.thread.inspect,
|
33
|
+
file_line: file_line ? file_line : ''
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
def parse_thread_num(subcmd, arg)
|
38
|
+
if '' == arg
|
39
|
+
errmsg "\"#{subcmd}\" needs a thread number"
|
40
|
+
nil
|
41
|
+
else
|
42
|
+
thread_num = get_int(arg, subcmd, 1)
|
43
|
+
return nil unless thread_num
|
44
|
+
get_context(thread_num)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def parse_thread_num_for_cmd(subcmd, arg)
|
49
|
+
c = parse_thread_num(subcmd, arg)
|
50
|
+
return nil unless c
|
51
|
+
case
|
52
|
+
when nil == c
|
53
|
+
errmsg 'No such thread'
|
54
|
+
when @state.context == c
|
55
|
+
errmsg "It's the current thread"
|
56
|
+
when c.ignored?
|
57
|
+
errmsg "Can't #{subcmd} thread #{arg}"
|
58
|
+
else
|
59
|
+
return c
|
60
|
+
end
|
61
|
+
return nil
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
class ThreadListCommand < Command
|
67
|
+
self.allow_in_control = true
|
68
|
+
|
69
|
+
def regexp
|
70
|
+
/^\s* th(?:read)? \s+ l(?:ist)? \s*$/x
|
71
|
+
end
|
72
|
+
|
73
|
+
def execute
|
74
|
+
Byebug.contexts.sort_by(&:thnum).each { |c| display_context(c) }
|
75
|
+
end
|
76
|
+
|
77
|
+
class << self
|
78
|
+
def names
|
79
|
+
%w(thread)
|
80
|
+
end
|
81
|
+
|
82
|
+
def description
|
83
|
+
%{
|
84
|
+
th[read] l[ist]\t\t\tlist all threads
|
85
|
+
}
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
class ThreadCurrentCommand < Command
|
91
|
+
self.need_context = true
|
92
|
+
|
93
|
+
def regexp
|
94
|
+
/^\s* th(?:read)? \s+ (?:cur(?:rent)?)? \s*$/x
|
95
|
+
end
|
96
|
+
|
97
|
+
def execute
|
98
|
+
display_context(@state.context)
|
99
|
+
end
|
100
|
+
|
101
|
+
class << self
|
102
|
+
def names
|
103
|
+
%w(thread)
|
104
|
+
end
|
105
|
+
|
106
|
+
def description
|
107
|
+
%{th[read] [cur[rent]]\t\tshow current thread}
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
class ThreadStopCommand < Command
|
113
|
+
self.allow_in_control = true
|
114
|
+
self.allow_in_post_mortem = false
|
115
|
+
self.need_context = true
|
116
|
+
|
117
|
+
def regexp
|
118
|
+
/^\s* th(?:read)? \s+ stop \s* (\S*) \s*$/x
|
119
|
+
end
|
120
|
+
|
121
|
+
def execute
|
122
|
+
c = parse_thread_num_for_cmd('thread stop', @match[1])
|
123
|
+
return unless c
|
124
|
+
c.suspend
|
125
|
+
display_context(c)
|
126
|
+
end
|
127
|
+
|
128
|
+
class << self
|
129
|
+
def names
|
130
|
+
%w(thread)
|
131
|
+
end
|
132
|
+
|
133
|
+
def description
|
134
|
+
%{th[read] stop <nnn>\t\tstop thread nnn}
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
class ThreadResumeCommand < Command
|
140
|
+
self.allow_in_control = true
|
141
|
+
self.allow_in_post_mortem = false
|
142
|
+
self.need_context = true
|
143
|
+
|
144
|
+
def regexp
|
145
|
+
/^\s* th(?:read)? \s+ resume \s* (\S*) \s*$/x
|
146
|
+
end
|
147
|
+
|
148
|
+
def execute
|
149
|
+
c = parse_thread_num_for_cmd('thread resume', @match[1])
|
150
|
+
return unless c
|
151
|
+
if !c.suspended?
|
152
|
+
errmsg 'Already running'
|
153
|
+
return
|
154
|
+
end
|
155
|
+
c.resume
|
156
|
+
display_context(c)
|
157
|
+
end
|
158
|
+
|
159
|
+
class << self
|
160
|
+
def names
|
161
|
+
%w(thread)
|
162
|
+
end
|
163
|
+
|
164
|
+
def description
|
165
|
+
%{th[read] resume <nnn>\t\tresume thread nnn}
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
class ThreadSwitchCommand < Command
|
171
|
+
self.allow_in_control = true
|
172
|
+
self.allow_in_post_mortem = false
|
173
|
+
self.need_context = true
|
174
|
+
|
175
|
+
def regexp
|
176
|
+
/^\s* th(?:read)? \s+ (?:sw(?:itch)?\s+)? (\S+) \s*$/x
|
177
|
+
end
|
178
|
+
|
179
|
+
def execute
|
180
|
+
if @match[1] =~ /switch/
|
181
|
+
errmsg '"thread switch" needs a thread number'
|
182
|
+
return
|
183
|
+
end
|
184
|
+
c = parse_thread_num_for_cmd('thread switch', @match[1])
|
185
|
+
return unless c
|
186
|
+
display_context(c)
|
187
|
+
c.step_into 1
|
188
|
+
c.thread.run
|
189
|
+
@state.proceed
|
190
|
+
end
|
191
|
+
|
192
|
+
class << self
|
193
|
+
def names
|
194
|
+
%w(thread)
|
195
|
+
end
|
196
|
+
|
197
|
+
def description
|
198
|
+
%{th[read] [sw[itch]] <nnn>\tswitch thread context to nnn}
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
data/lib/byebug/helper.rb
CHANGED
@@ -11,15 +11,15 @@ module Byebug
|
|
11
11
|
begin
|
12
12
|
int = Integer(str)
|
13
13
|
if min and int < min
|
14
|
-
print "#{cmd} argument \"#{str}\" needs to be at least #{min}.\n"
|
14
|
+
print "\"#{cmd}\" argument \"#{str}\" needs to be at least #{min}.\n"
|
15
15
|
return nil
|
16
16
|
elsif max and int > max
|
17
|
-
print "#{cmd} argument \"#{str}\" needs to be at most #{max}.\n"
|
17
|
+
print "\"#{cmd}\" argument \"#{str}\" needs to be at most #{max}.\n"
|
18
18
|
return nil
|
19
19
|
end
|
20
20
|
return int
|
21
21
|
rescue
|
22
|
-
print "#{cmd} argument \"#{str}\" needs to be a number.\n"
|
22
|
+
print "\"#{cmd}\" argument \"#{str}\" needs to be a number.\n"
|
23
23
|
return nil
|
24
24
|
end
|
25
25
|
end
|
data/lib/byebug/interface.rb
CHANGED
@@ -10,23 +10,8 @@ module Byebug
|
|
10
10
|
# Common routine for reporting byebug error messages.
|
11
11
|
# Derived classes may want to override this to capture output.
|
12
12
|
def errmsg(*args)
|
13
|
-
|
14
|
-
|
15
|
-
print(*args)
|
16
|
-
aprint ''
|
17
|
-
else
|
18
|
-
print '*** '
|
19
|
-
print(*args)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
# Format msg with gdb-style annotation header
|
24
|
-
def afmt(msg, newline="\n")
|
25
|
-
"\032\032#{msg}#{newline}"
|
26
|
-
end
|
27
|
-
|
28
|
-
def aprint(msg)
|
29
|
-
print afmt(msg) if Byebug.annotate.to_i > 2
|
13
|
+
print '*** '
|
14
|
+
print(*args)
|
30
15
|
end
|
31
16
|
|
32
17
|
def format(*args)
|
@@ -83,9 +68,6 @@ module Byebug
|
|
83
68
|
|
84
69
|
# Things to do before quitting
|
85
70
|
def finalize
|
86
|
-
if Byebug.method_defined?("annotate") and Byebug.annotate.to_i > 2
|
87
|
-
print "\032\032exited\n\n"
|
88
|
-
end
|
89
71
|
if Byebug.respond_to?(:save_history)
|
90
72
|
Byebug.save_history
|
91
73
|
end
|
data/lib/byebug/processor.rb
CHANGED
@@ -9,7 +9,7 @@ module Byebug
|
|
9
9
|
attr_accessor :interface
|
10
10
|
|
11
11
|
extend Forwardable
|
12
|
-
def_delegators :@interface, :errmsg, :print
|
12
|
+
def_delegators :@interface, :errmsg, :print
|
13
13
|
|
14
14
|
def initialize(interface)
|
15
15
|
@interface = interface
|
@@ -19,22 +19,6 @@ module Byebug
|
|
19
19
|
class CommandProcessor < Processor
|
20
20
|
attr_reader :display
|
21
21
|
|
22
|
-
@@Show_breakpoints_postcmd = [ Byebug::BreakCommand.new(nil).regexp,
|
23
|
-
Byebug::ConditionCommand.new(nil).regexp,
|
24
|
-
Byebug::DeleteCommand.new(nil).regexp,
|
25
|
-
Byebug::DisableCommand.new(nil).regexp,
|
26
|
-
Byebug::EnableCommand.new(nil).regexp
|
27
|
-
]
|
28
|
-
@@Show_annotations_run = [ Byebug::ContinueCommand.new(nil).regexp,
|
29
|
-
Byebug::FinishCommand.new(nil).regexp,
|
30
|
-
Byebug::NextCommand.new(nil).regexp,
|
31
|
-
Byebug::StepCommand.new(nil).regexp
|
32
|
-
]
|
33
|
-
@@Show_annotations_postcmd = [ Byebug::DownCommand.new(nil).regexp,
|
34
|
-
Byebug::FrameCommand.new(nil).regexp,
|
35
|
-
Byebug::UpCommand.new(nil).regexp
|
36
|
-
]
|
37
|
-
|
38
22
|
def initialize(interface = LocalInterface.new)
|
39
23
|
super(interface)
|
40
24
|
|
@@ -43,8 +27,6 @@ module Byebug
|
|
43
27
|
@last_cmd = nil # To allow empty (just <RET>) commands
|
44
28
|
@last_file = nil # Filename the last time we stopped
|
45
29
|
@last_line = nil # Line number the last time we stopped
|
46
|
-
@breakpoints_were_empty = false # Show breakpoints 1st time
|
47
|
-
@displays_were_empty = true # No display 1st time
|
48
30
|
@context_was_dead = false # Assume we haven't started.
|
49
31
|
end
|
50
32
|
|
@@ -57,7 +39,7 @@ module Byebug
|
|
57
39
|
|
58
40
|
require 'pathname' # For cleanpath
|
59
41
|
|
60
|
-
|
42
|
+
#
|
61
43
|
# Regularize file name.
|
62
44
|
#
|
63
45
|
# This is also used as a common funnel place if basename is desired or if we
|
@@ -95,17 +77,14 @@ module Byebug
|
|
95
77
|
end
|
96
78
|
|
97
79
|
def at_breakpoint(context, breakpoint)
|
98
|
-
aprint 'stopped'
|
99
80
|
n = Byebug.breakpoints.index(breakpoint) + 1
|
100
81
|
file = CommandProcessor.canonic_file(breakpoint.source)
|
101
82
|
line = breakpoint.pos
|
102
|
-
aprint "source #{file}:#{line}"
|
103
83
|
print "Stopped by breakpoint #{n} at #{file}:#{line}\n"
|
104
84
|
end
|
105
85
|
protect :at_breakpoint
|
106
86
|
|
107
87
|
def at_catchpoint(context, excpt)
|
108
|
-
aprint 'stopped'
|
109
88
|
file = CommandProcessor.canonic_file(context.frame_file(0))
|
110
89
|
line = context.frame_line(0)
|
111
90
|
print "Catchpoint at %s:%d: `%s' (%s)\n", file, line, excpt, excpt.class
|
@@ -120,10 +99,8 @@ module Byebug
|
|
120
99
|
protect :at_catchpoint
|
121
100
|
|
122
101
|
def at_tracing(context, file, line)
|
123
|
-
if file != @last_file || line != @last_line ||
|
124
|
-
|
125
|
-
@last_file = file
|
126
|
-
@last_line = line
|
102
|
+
if file != @last_file || line != @last_line || Command.settings[:linetrace_plus]
|
103
|
+
@last_file, @last_line = file, line
|
127
104
|
print "Tracing: #{CommandProcessor.canonic_file(file)}:#{line} " \
|
128
105
|
"#{Byebug.line_at(file,line)}\n"
|
129
106
|
end
|
@@ -142,16 +119,14 @@ module Byebug
|
|
142
119
|
protect :at_return
|
143
120
|
|
144
121
|
private
|
145
|
-
|
122
|
+
#
|
146
123
|
# Prompt shown before reading a command.
|
147
124
|
#
|
148
125
|
def prompt(context)
|
149
|
-
|
150
|
-
p = afmt("pre-prompt")+p+"\n"+afmt("prompt") if Byebug.annotate.to_i > 2
|
151
|
-
return p
|
126
|
+
return "(byebug#{context.dead? ? ':post-mortem' : ''}) "
|
152
127
|
end
|
153
128
|
|
154
|
-
|
129
|
+
#
|
155
130
|
# Run commands everytime.
|
156
131
|
#
|
157
132
|
# For example display commands or possibly the list or irb in an
|
@@ -181,7 +156,7 @@ module Byebug
|
|
181
156
|
return state, commands
|
182
157
|
end
|
183
158
|
|
184
|
-
|
159
|
+
#
|
185
160
|
# Splits a command line of the form "cmd1 ; cmd2 ; ... ; cmdN" into an
|
186
161
|
# array of commands: [cmd1, cmd2, ..., cmdN]
|
187
162
|
#
|
@@ -201,7 +176,7 @@ module Byebug
|
|
201
176
|
end
|
202
177
|
end
|
203
178
|
|
204
|
-
|
179
|
+
#
|
205
180
|
# Handle byebug commands.
|
206
181
|
#
|
207
182
|
def process_commands(context, file, line)
|
@@ -209,7 +184,7 @@ module Byebug
|
|
209
184
|
$state = Command.settings[:testing] ? state : nil
|
210
185
|
|
211
186
|
preloop(commands, context)
|
212
|
-
|
187
|
+
print state.location if Command.settings[:autolist] == 0
|
213
188
|
|
214
189
|
while !state.proceed?
|
215
190
|
input = @interface.command_queue.empty? ?
|
@@ -225,25 +200,23 @@ module Byebug
|
|
225
200
|
end
|
226
201
|
split_commands(input).each do |cmd|
|
227
202
|
one_cmd(commands, context, cmd)
|
228
|
-
postcmd(commands, context, cmd)
|
229
203
|
end
|
230
204
|
end
|
231
205
|
end
|
232
|
-
postloop(commands, context)
|
233
206
|
end
|
234
207
|
|
235
|
-
|
208
|
+
#
|
236
209
|
# Executes a single byebug command
|
237
210
|
#
|
238
211
|
def one_cmd(commands, context, input)
|
239
|
-
if cmd = commands.find{ |c| c.match(input) }
|
212
|
+
if cmd = commands.find { |c| c.match(input) }
|
240
213
|
if context.dead? && cmd.class.need_context
|
241
214
|
print "Command is unavailable\n"
|
242
215
|
else
|
243
216
|
cmd.execute
|
244
217
|
end
|
245
218
|
else
|
246
|
-
unknown_cmd = commands.find{ |c| c.class.unknown }
|
219
|
+
unknown_cmd = commands.find { |c| c.class.unknown }
|
247
220
|
if unknown_cmd
|
248
221
|
unknown_cmd.execute
|
249
222
|
else
|
@@ -252,65 +225,16 @@ module Byebug
|
|
252
225
|
end
|
253
226
|
end
|
254
227
|
|
228
|
+
#
|
229
|
+
# Tasks to do before processor loop
|
230
|
+
#
|
255
231
|
def preloop(commands, context)
|
256
232
|
@context_was_dead = true if context.dead? and not @context_was_dead
|
257
233
|
|
258
|
-
aprint 'stopped'
|
259
234
|
if @context_was_dead
|
260
|
-
aprint 'exited'
|
261
235
|
print "The program finished.\n"
|
262
236
|
@context_was_dead = false
|
263
237
|
end
|
264
|
-
|
265
|
-
if Byebug.annotate.to_i > 2
|
266
|
-
breakpoint_annotations(commands, context)
|
267
|
-
display_annotations(commands, context)
|
268
|
-
annotation('stack', commands, context, "where")
|
269
|
-
annotation('variables', commands, context, "info variables") unless
|
270
|
-
context.dead?
|
271
|
-
end
|
272
|
-
end
|
273
|
-
|
274
|
-
def postcmd(commands, context, cmd)
|
275
|
-
if Byebug.annotate.to_i > 2
|
276
|
-
cmd = @last_cmd unless cmd
|
277
|
-
breakpoint_annotations(commands, context) if
|
278
|
-
@@Show_breakpoints_postcmd.find{|pat| cmd =~ pat}
|
279
|
-
display_annotations(commands, context)
|
280
|
-
if @@Show_annotations_postcmd.find{|pat| cmd =~ pat}
|
281
|
-
annotation('stack', commands, context, "where") if
|
282
|
-
context.stack_size > 0
|
283
|
-
annotation('variables', commands, context, "info variables") unless
|
284
|
-
context.dead?
|
285
|
-
end
|
286
|
-
if not context.dead? and @@Show_annotations_run.find{|pat| cmd =~ pat}
|
287
|
-
afmt 'starting'
|
288
|
-
@context_was_dead = false
|
289
|
-
end
|
290
|
-
end
|
291
|
-
end
|
292
|
-
|
293
|
-
def postloop(commands, context)
|
294
|
-
end
|
295
|
-
|
296
|
-
def annotation(label, commands, context, cmd)
|
297
|
-
print afmt(label)
|
298
|
-
one_cmd(commands, context, cmd)
|
299
|
-
end
|
300
|
-
|
301
|
-
def breakpoint_annotations(commands, context)
|
302
|
-
unless Byebug.breakpoints.empty? and @breakpoints_were_empty
|
303
|
-
annotation('breakpoints', commands, context, "info breakpoints")
|
304
|
-
@breakpoints_were_empty = Byebug.breakpoints.empty?
|
305
|
-
end
|
306
|
-
end
|
307
|
-
|
308
|
-
def display_annotations(commands, context)
|
309
|
-
return if display.empty?
|
310
|
-
have_display = display.find{|d| d[0]}
|
311
|
-
return unless have_display and @displays_were_empty
|
312
|
-
@displays_were_empty = have_display
|
313
|
-
annotation('display', commands, context, "display")
|
314
238
|
end
|
315
239
|
|
316
240
|
class State
|
@@ -324,7 +248,7 @@ module Byebug
|
|
324
248
|
end
|
325
249
|
|
326
250
|
extend Forwardable
|
327
|
-
def_delegators :@interface, :
|
251
|
+
def_delegators :@interface, :errmsg, :print, :confirm
|
328
252
|
|
329
253
|
def proceed?
|
330
254
|
@proceed
|
@@ -345,7 +269,6 @@ module Byebug
|
|
345
269
|
|
346
270
|
|
347
271
|
class ControlCommandProcessor < Processor
|
348
|
-
|
349
272
|
def initialize(interface)
|
350
273
|
super(interface)
|
351
274
|
@context_was_dead = false # Assume we haven't started.
|
@@ -359,7 +282,6 @@ module Byebug
|
|
359
282
|
commands = control_cmds.map{|cmd| cmd.new(state) }
|
360
283
|
|
361
284
|
if @context_was_dead
|
362
|
-
aprint 'exited'
|
363
285
|
print "The program finished.\n"
|
364
286
|
@context_was_dead = false
|
365
287
|
end
|
@@ -382,12 +304,11 @@ module Byebug
|
|
382
304
|
@interface.close
|
383
305
|
end
|
384
306
|
|
385
|
-
#
|
386
|
-
#
|
307
|
+
#
|
308
|
+
# Prompt shown before reading a command.
|
309
|
+
#
|
387
310
|
def prompt(context)
|
388
|
-
|
389
|
-
p = afmt("pre-prompt") +p+"\n"+ afmt("prompt") if Byebug.annotate.to_i > 2
|
390
|
-
return p
|
311
|
+
return '(byebug:ctrl) '
|
391
312
|
end
|
392
313
|
|
393
314
|
class State
|