byebug 3.2.0 → 3.3.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/.rubocop.yml +3 -0
- data/CHANGELOG.md +125 -99
- data/CONTRIBUTING.md +4 -6
- data/GUIDE.md +42 -20
- data/Gemfile +5 -3
- data/README.md +2 -3
- data/Rakefile +11 -7
- data/bin/byebug +2 -252
- data/byebug.gemspec +7 -4
- data/ext/byebug/byebug.c +17 -18
- data/ext/byebug/byebug.h +4 -5
- data/ext/byebug/context.c +37 -39
- data/ext/byebug/threads.c +39 -18
- data/lib/byebug.rb +2 -110
- data/lib/byebug/attacher.rb +23 -0
- data/lib/byebug/breakpoint.rb +60 -0
- data/lib/byebug/command.rb +62 -70
- data/lib/byebug/commands/break.rb +24 -24
- data/lib/byebug/commands/catchpoint.rb +18 -10
- data/lib/byebug/commands/condition.rb +18 -17
- data/lib/byebug/commands/continue.rb +17 -9
- data/lib/byebug/commands/delete.rb +19 -13
- data/lib/byebug/commands/display.rb +19 -53
- data/lib/byebug/commands/edit.rb +7 -4
- data/lib/byebug/commands/enable_disable.rb +130 -0
- data/lib/byebug/commands/eval.rb +40 -22
- data/lib/byebug/commands/finish.rb +13 -4
- data/lib/byebug/commands/frame.rb +65 -45
- data/lib/byebug/commands/help.rb +17 -18
- data/lib/byebug/commands/history.rb +14 -8
- data/lib/byebug/commands/info.rb +160 -182
- data/lib/byebug/commands/interrupt.rb +4 -1
- data/lib/byebug/commands/irb.rb +30 -0
- data/lib/byebug/commands/kill.rb +7 -8
- data/lib/byebug/commands/list.rb +71 -66
- data/lib/byebug/commands/method.rb +14 -6
- data/lib/byebug/commands/pry.rb +35 -0
- data/lib/byebug/commands/quit.rb +9 -6
- data/lib/byebug/commands/reload.rb +5 -2
- data/lib/byebug/commands/restart.rb +13 -9
- data/lib/byebug/commands/save.rb +17 -17
- data/lib/byebug/commands/set.rb +16 -15
- data/lib/byebug/commands/show.rb +10 -11
- data/lib/byebug/commands/source.rb +11 -5
- data/lib/byebug/commands/stepping.rb +38 -24
- data/lib/byebug/commands/threads.rb +45 -31
- data/lib/byebug/commands/trace.rb +22 -9
- data/lib/byebug/commands/undisplay.rb +45 -0
- data/lib/byebug/commands/variables.rb +83 -27
- data/lib/byebug/context.rb +25 -22
- data/lib/byebug/core.rb +82 -0
- data/lib/byebug/helper.rb +37 -28
- data/lib/byebug/history.rb +8 -4
- data/lib/byebug/interface.rb +12 -17
- data/lib/byebug/interfaces/local_interface.rb +11 -8
- data/lib/byebug/interfaces/remote_interface.rb +11 -8
- data/lib/byebug/interfaces/script_interface.rb +9 -6
- data/lib/byebug/options.rb +46 -0
- data/lib/byebug/processor.rb +7 -1
- data/lib/byebug/processors/command_processor.rb +135 -125
- data/lib/byebug/processors/control_command_processor.rb +23 -23
- data/lib/byebug/remote.rb +17 -26
- data/lib/byebug/runner.rb +100 -0
- data/lib/byebug/setting.rb +33 -8
- data/lib/byebug/settings/autoeval.rb +5 -15
- data/lib/byebug/settings/autoirb.rb +4 -1
- data/lib/byebug/settings/autolist.rb +5 -2
- data/lib/byebug/settings/autoreload.rb +5 -2
- data/lib/byebug/settings/autosave.rb +6 -2
- data/lib/byebug/settings/basename.rb +7 -2
- data/lib/byebug/settings/callstyle.rb +4 -1
- data/lib/byebug/settings/forcestep.rb +6 -3
- data/lib/byebug/settings/fullpath.rb +5 -2
- data/lib/byebug/settings/histfile.rb +5 -3
- data/lib/byebug/settings/histsize.rb +5 -3
- data/lib/byebug/settings/linetrace.rb +4 -1
- data/lib/byebug/settings/listsize.rb +5 -1
- data/lib/byebug/settings/post_mortem.rb +21 -13
- data/lib/byebug/settings/stack_on_error.rb +6 -2
- data/lib/byebug/settings/testing.rb +6 -1
- data/lib/byebug/settings/tracing_plus.rb +5 -1
- data/lib/byebug/settings/verbose.rb +13 -2
- data/lib/byebug/settings/width.rb +4 -1
- data/lib/byebug/version.rb +1 -1
- data/test/{break_test.rb → commands/break_test.rb} +41 -53
- data/test/{condition_test.rb → commands/condition_test.rb} +14 -14
- data/test/{continue_test.rb → commands/continue_test.rb} +0 -0
- data/test/{delete_test.rb → commands/delete_test.rb} +2 -2
- data/test/commands/display_test.rb +37 -0
- data/test/{edit_test.rb → commands/edit_test.rb} +0 -0
- data/test/{eval_test.rb → commands/eval_test.rb} +1 -0
- data/test/{finish_test.rb → commands/finish_test.rb} +11 -1
- data/test/{frame_test.rb → commands/frame_test.rb} +12 -16
- data/test/{help_test.rb → commands/help_test.rb} +21 -4
- data/test/{history_test.rb → commands/history_test.rb} +0 -0
- data/test/{info_test.rb → commands/info_test.rb} +5 -55
- data/test/{interrupt_test.rb → commands/interrupt_test.rb} +0 -0
- data/test/commands/irb_test.rb +28 -0
- data/test/{kill_test.rb → commands/kill_test.rb} +1 -1
- data/test/{list_test.rb → commands/list_test.rb} +1 -1
- data/test/{method_test.rb → commands/method_test.rb} +0 -0
- data/test/{post_mortem_test.rb → commands/post_mortem_test.rb} +6 -10
- data/test/{pry_test.rb → commands/pry_test.rb} +4 -13
- data/test/{quit_test.rb → commands/quit_test.rb} +4 -4
- data/test/{reload_test.rb → commands/reload_test.rb} +0 -0
- data/test/{restart_test.rb → commands/restart_test.rb} +6 -0
- data/test/{save_test.rb → commands/save_test.rb} +2 -2
- data/test/{set_test.rb → commands/set_test.rb} +9 -2
- data/test/{show_test.rb → commands/show_test.rb} +1 -1
- data/test/{source_test.rb → commands/source_test.rb} +3 -3
- data/test/{stepping_test.rb → commands/stepping_test.rb} +44 -35
- data/test/{thread_test.rb → commands/thread_test.rb} +0 -0
- data/test/{trace_test.rb → commands/trace_test.rb} +0 -0
- data/test/{display_test.rb → commands/undisplay_test.rb} +7 -45
- data/test/{variables_test.rb → commands/variables_test.rb} +10 -1
- data/test/debugger_alias_test.rb +2 -2
- data/test/runner_test.rb +127 -0
- data/test/support/matchers.rb +27 -25
- data/test/support/test_interface.rb +9 -5
- data/test/support/utils.rb +96 -101
- data/test/test_helper.rb +32 -20
- metadata +93 -68
- data/lib/byebug/commands/enable.rb +0 -154
- data/lib/byebug/commands/repl.rb +0 -126
- data/test/irb_test.rb +0 -47
- data/test/support/breakpoint.rb +0 -13
data/lib/byebug/commands/save.rb
CHANGED
@@ -1,17 +1,23 @@
|
|
1
1
|
module Byebug
|
2
|
+
#
|
3
|
+
# Utilities for the save command.
|
4
|
+
#
|
2
5
|
module SaveFunctions
|
3
6
|
# Create a temporary file to write in if file is nil
|
4
7
|
def open_save
|
5
|
-
require
|
6
|
-
file = Tempfile.new(
|
8
|
+
require 'tempfile'
|
9
|
+
file = Tempfile.new('byebug-save')
|
7
10
|
# We want close to not unlink, so redefine.
|
8
11
|
def file.close
|
9
12
|
@tmpfile.close if @tmpfile
|
10
13
|
end
|
11
|
-
|
14
|
+
file
|
12
15
|
end
|
13
16
|
end
|
14
17
|
|
18
|
+
#
|
19
|
+
# Save current settings to use them in another debug session.
|
20
|
+
#
|
15
21
|
class SaveCommand < Command
|
16
22
|
self.allow_in_control = true
|
17
23
|
|
@@ -28,15 +34,10 @@ module Byebug
|
|
28
34
|
end
|
29
35
|
|
30
36
|
def save_displays(file)
|
31
|
-
|
32
|
-
if d[0]
|
33
|
-
file.puts "display #{d[1]}"
|
34
|
-
end
|
35
|
-
end
|
37
|
+
@state.display.each { |d| file.puts "display #{d[1]}" if d[0] }
|
36
38
|
end
|
37
39
|
|
38
40
|
def save_settings(file)
|
39
|
-
# FIXME put routine in set
|
40
41
|
%w(autoeval autoirb autolist basename testing).each do |setting|
|
41
42
|
file.puts "set #{setting} #{Setting[setting.to_sym]}"
|
42
43
|
end
|
@@ -47,8 +48,8 @@ module Byebug
|
|
47
48
|
end
|
48
49
|
|
49
50
|
def execute
|
50
|
-
if
|
51
|
-
file = open_save
|
51
|
+
if !@match[1]
|
52
|
+
file = open_save
|
52
53
|
else
|
53
54
|
file = open(@match[1], 'w')
|
54
55
|
end
|
@@ -56,10 +57,8 @@ module Byebug
|
|
56
57
|
save_catchpoints(file)
|
57
58
|
save_displays(file)
|
58
59
|
save_settings(file)
|
59
|
-
|
60
|
-
if @state
|
61
|
-
@state.interface.restart_file = file.path
|
62
|
-
end
|
60
|
+
puts "Saved to '#{file.path}'"
|
61
|
+
@state.interface.restart_file = file.path if @state && @state.interface
|
63
62
|
file.close
|
64
63
|
end
|
65
64
|
|
@@ -69,12 +68,13 @@ module Byebug
|
|
69
68
|
end
|
70
69
|
|
71
70
|
def description
|
72
|
-
%
|
71
|
+
%(save[ FILE]
|
73
72
|
|
74
73
|
Saves current byebug state to FILE as a script file. This includes
|
75
74
|
breakpoints, catchpoints, display expressions and some settings. If
|
76
75
|
no filename is given, we will fabricate one.
|
77
|
-
|
76
|
+
|
77
|
+
Use the "source" command in another debug session to restore them.)
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
data/lib/byebug/commands/set.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
module Byebug
|
2
|
+
#
|
3
|
+
# Change byebug settings.
|
4
|
+
#
|
2
5
|
class SetCommand < Command
|
3
6
|
self.allow_in_control = true
|
4
7
|
|
@@ -8,34 +11,35 @@ module Byebug
|
|
8
11
|
|
9
12
|
def execute
|
10
13
|
key, value = @match[:setting], @match[:value]
|
11
|
-
return
|
14
|
+
return puts(SetCommand.help) if key.nil? && value.nil?
|
12
15
|
|
13
16
|
full_key = Setting.find(key)
|
14
|
-
return
|
17
|
+
return errmsg("Unknown setting :#{key}") unless full_key
|
15
18
|
|
16
19
|
if !Setting.boolean?(full_key) && value.nil?
|
17
|
-
|
20
|
+
value, err = nil, "You must specify a value for setting :#{key}"
|
18
21
|
elsif Setting.boolean?(full_key)
|
19
|
-
value = get_onoff(value, key =~ /^no/ ? false : true)
|
22
|
+
value, err = get_onoff(value, key =~ /^no/ ? false : true)
|
20
23
|
elsif Setting.integer?(full_key)
|
21
|
-
|
24
|
+
value, err = get_int(value, full_key, 1)
|
22
25
|
end
|
26
|
+
return errmsg(err) if value.nil?
|
23
27
|
|
24
28
|
Setting[full_key.to_sym] = value
|
25
29
|
|
26
|
-
|
30
|
+
puts Setting.settings[full_key.to_sym].to_s
|
27
31
|
end
|
28
32
|
|
29
33
|
def get_onoff(arg, default)
|
30
34
|
return default if arg.nil?
|
35
|
+
|
31
36
|
case arg
|
32
37
|
when '1', 'on', 'true'
|
33
|
-
|
38
|
+
true
|
34
39
|
when '0', 'off', 'false'
|
35
|
-
|
40
|
+
false
|
36
41
|
else
|
37
|
-
|
38
|
-
raise RuntimeError
|
42
|
+
[nil, "Expecting 'on', 1, true, 'off', 0, false. Got: #{arg}.\n"]
|
39
43
|
end
|
40
44
|
end
|
41
45
|
|
@@ -56,14 +60,11 @@ module Byebug
|
|
56
60
|
Conversely, you can use "set no<setting> to disable them.
|
57
61
|
|
58
62
|
You can see these environment settings with the "show" command.
|
59
|
-
|
60
63
|
EOD
|
61
64
|
end
|
62
65
|
|
63
|
-
def help(
|
64
|
-
|
65
|
-
|
66
|
-
description + Setting.format()
|
66
|
+
def help(subcmds = [])
|
67
|
+
Setting.help('set', subcmds.first)
|
67
68
|
end
|
68
69
|
end
|
69
70
|
end
|
data/lib/byebug/commands/show.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
module Byebug
|
2
|
+
#
|
3
|
+
# Show byebug settings.
|
4
|
+
#
|
2
5
|
class ShowCommand < Command
|
3
6
|
self.allow_in_control = true
|
4
7
|
|
@@ -8,14 +11,12 @@ module Byebug
|
|
8
11
|
|
9
12
|
def execute
|
10
13
|
key = @match[:setting]
|
11
|
-
return
|
14
|
+
return puts(self.class.help) if key.nil?
|
12
15
|
|
13
16
|
full_key = Setting.find(key)
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
print "Unknown setting :#{key}\n"
|
18
|
-
end
|
17
|
+
return errmsg("Unknown setting :#{key}") unless full_key
|
18
|
+
|
19
|
+
puts Setting.settings[full_key.to_sym].to_s
|
19
20
|
end
|
20
21
|
|
21
22
|
class << self
|
@@ -24,7 +25,7 @@ module Byebug
|
|
24
25
|
end
|
25
26
|
|
26
27
|
def description
|
27
|
-
<<-EOD.gsub(/^
|
28
|
+
<<-EOD.gsub(/^ {8}/, '')
|
28
29
|
|
29
30
|
show <setting> <value>
|
30
31
|
|
@@ -34,10 +35,8 @@ module Byebug
|
|
34
35
|
EOD
|
35
36
|
end
|
36
37
|
|
37
|
-
def help(
|
38
|
-
|
39
|
-
|
40
|
-
description + Setting.format()
|
38
|
+
def help(subcmds = [])
|
39
|
+
Setting.help('show', subcmds.first)
|
41
40
|
end
|
42
41
|
end
|
43
42
|
end
|
@@ -1,4 +1,9 @@
|
|
1
1
|
module Byebug
|
2
|
+
#
|
3
|
+
# Execute a file containing byebug commands.
|
4
|
+
#
|
5
|
+
# It can be used to restore a previously saved debugging session.
|
6
|
+
#
|
2
7
|
class SourceCommand < Command
|
3
8
|
self.allow_in_control = true
|
4
9
|
|
@@ -7,13 +12,12 @@ module Byebug
|
|
7
12
|
end
|
8
13
|
|
9
14
|
def execute
|
10
|
-
return
|
11
|
-
SourceCommand.names.include?(@match[0])
|
15
|
+
return puts(self.class.help) if self.class.names.include?(@match[0])
|
12
16
|
|
13
17
|
file = File.expand_path(@match[1]).strip
|
14
|
-
return errmsg
|
18
|
+
return errmsg("File \"#{file}\" not found") unless File.exist?(file)
|
15
19
|
|
16
|
-
if @state
|
20
|
+
if @state && @state.interface
|
17
21
|
@state.interface.command_queue += File.open(file).readlines
|
18
22
|
else
|
19
23
|
Byebug.run_script(file, @state)
|
@@ -26,7 +30,9 @@ module Byebug
|
|
26
30
|
end
|
27
31
|
|
28
32
|
def description
|
29
|
-
%
|
33
|
+
%(source <file>
|
34
|
+
|
35
|
+
Executes file <file> containing byebug commands.)
|
30
36
|
end
|
31
37
|
end
|
32
38
|
end
|
@@ -3,19 +3,24 @@ module Byebug
|
|
3
3
|
# Mixin to assist command parsing
|
4
4
|
#
|
5
5
|
module SteppingFunctions
|
6
|
-
def
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
6
|
+
def parse_force(str)
|
7
|
+
return Setting[:forcestep] unless str
|
8
|
+
|
9
|
+
case str
|
10
|
+
when '+' then
|
11
|
+
true
|
12
|
+
when '-' then
|
13
|
+
false
|
13
14
|
end
|
14
|
-
steps = get_int(match[2], command_name, 1)
|
15
|
-
return [steps, force]
|
16
15
|
end
|
17
16
|
end
|
18
17
|
|
18
|
+
#
|
19
|
+
# Implements the next functionality.
|
20
|
+
#
|
21
|
+
# Allows the user the continue execution until the next instruction in the
|
22
|
+
# current frame.
|
23
|
+
#
|
19
24
|
class NextCommand < Command
|
20
25
|
self.allow_in_post_mortem = false
|
21
26
|
|
@@ -24,9 +29,10 @@ module Byebug
|
|
24
29
|
end
|
25
30
|
|
26
31
|
def execute
|
27
|
-
steps,
|
28
|
-
return unless steps
|
29
|
-
|
32
|
+
steps, err = parse_steps(@match[2], 'Next')
|
33
|
+
return errmsg(err) unless steps
|
34
|
+
|
35
|
+
@state.context.step_over(steps, @state.frame_pos, parse_force(@match[1]))
|
30
36
|
@state.proceed
|
31
37
|
end
|
32
38
|
|
@@ -36,14 +42,21 @@ module Byebug
|
|
36
42
|
end
|
37
43
|
|
38
44
|
def description
|
39
|
-
%
|
40
|
-
|
41
|
-
|
42
|
-
|
45
|
+
%(n[ext][+-]?[ nnn]
|
46
|
+
|
47
|
+
Steps over once or nnn times.
|
48
|
+
'+' forces to move to another line.
|
49
|
+
'-' is the opposite of '+' and disables the :forcestep setting.)
|
43
50
|
end
|
44
51
|
end
|
45
52
|
end
|
46
53
|
|
54
|
+
#
|
55
|
+
# Implements the step functionality.
|
56
|
+
#
|
57
|
+
# Allows the user the continue execution until the next instruction, possibily
|
58
|
+
# in a different frame. Use step to step into method calls or blocks.
|
59
|
+
#
|
47
60
|
class StepCommand < Command
|
48
61
|
self.allow_in_post_mortem = false
|
49
62
|
|
@@ -52,9 +65,10 @@ module Byebug
|
|
52
65
|
end
|
53
66
|
|
54
67
|
def execute
|
55
|
-
steps,
|
56
|
-
return unless steps
|
57
|
-
|
68
|
+
steps, err = parse_steps(@match[2], 'Steps')
|
69
|
+
return errmsg(err) unless steps
|
70
|
+
|
71
|
+
@state.context.step_into(steps, parse_force(@match[1]))
|
58
72
|
@state.proceed
|
59
73
|
end
|
60
74
|
|
@@ -64,11 +78,11 @@ module Byebug
|
|
64
78
|
end
|
65
79
|
|
66
80
|
def description
|
67
|
-
%{
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
81
|
+
%{s[tep][+-]?[ nnn]
|
82
|
+
|
83
|
+
Steps (into methods) once or nnn times.
|
84
|
+
'+' forces to move to another line.
|
85
|
+
'-' is the opposite of '+' and disables the :forcestep setting.}
|
72
86
|
end
|
73
87
|
end
|
74
88
|
end
|
@@ -1,17 +1,22 @@
|
|
1
1
|
module Byebug
|
2
|
+
#
|
3
|
+
# Utilities to assist commands related to threads.
|
4
|
+
#
|
2
5
|
module ThreadFunctions
|
3
6
|
def display_context(context, should_show_top_frame = true)
|
4
7
|
args = thread_arguments(context, should_show_top_frame)
|
5
|
-
|
6
|
-
|
8
|
+
interp = format("%s%s%d %s\t%s",
|
9
|
+
args[:status_flag], args[:debug_flag], args[:id],
|
10
|
+
args[:thread], args[:file_line])
|
11
|
+
puts interp
|
7
12
|
end
|
8
13
|
|
9
14
|
def thread_arguments(context, should_show_top_frame = true)
|
10
15
|
status_flag = if context.suspended?
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
16
|
+
'$'
|
17
|
+
else
|
18
|
+
context.thread == Thread.current ? '+' : ' '
|
19
|
+
end
|
15
20
|
debug_flag = context.ignored? ? '!' : ' '
|
16
21
|
if should_show_top_frame
|
17
22
|
if context.thread == Thread.current && !context.dead?
|
@@ -36,19 +41,18 @@ module Byebug
|
|
36
41
|
end
|
37
42
|
|
38
43
|
def parse_thread_num(subcmd, arg)
|
39
|
-
if '' == arg
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
get_context(thread_num)
|
46
|
-
end
|
44
|
+
return errmsg("\"#{subcmd}\" needs a thread number") if '' == arg
|
45
|
+
|
46
|
+
thread_num, err = get_int(arg, subcmd, 1)
|
47
|
+
return errmsg(err) unless thread_num
|
48
|
+
|
49
|
+
Byebug.contexts.find { |c| c.thnum == thnum }
|
47
50
|
end
|
48
51
|
|
49
52
|
def parse_thread_num_for_cmd(subcmd, arg)
|
50
53
|
c = parse_thread_num(subcmd, arg)
|
51
|
-
return
|
54
|
+
return unless c
|
55
|
+
|
52
56
|
case
|
53
57
|
when nil == c
|
54
58
|
errmsg 'No such thread'
|
@@ -57,13 +61,14 @@ module Byebug
|
|
57
61
|
when c.ignored?
|
58
62
|
errmsg "Can't #{subcmd} thread #{arg}"
|
59
63
|
else
|
60
|
-
|
64
|
+
c
|
61
65
|
end
|
62
|
-
return nil
|
63
66
|
end
|
64
|
-
|
65
67
|
end
|
66
68
|
|
69
|
+
#
|
70
|
+
# List current threads.
|
71
|
+
#
|
67
72
|
class ThreadListCommand < Command
|
68
73
|
self.allow_in_control = true
|
69
74
|
|
@@ -82,13 +87,14 @@ module Byebug
|
|
82
87
|
end
|
83
88
|
|
84
89
|
def description
|
85
|
-
%
|
86
|
-
th[read] l[ist]\t\t\tlist all threads
|
87
|
-
}
|
90
|
+
%(th[read] l[ist] Lists all threads.)
|
88
91
|
end
|
89
92
|
end
|
90
93
|
end
|
91
94
|
|
95
|
+
#
|
96
|
+
# Show current thread.
|
97
|
+
#
|
92
98
|
class ThreadCurrentCommand < Command
|
93
99
|
def regexp
|
94
100
|
/^\s* th(?:read)? \s+ (?:cur(?:rent)?)? \s*$/x
|
@@ -104,11 +110,14 @@ module Byebug
|
|
104
110
|
end
|
105
111
|
|
106
112
|
def description
|
107
|
-
%
|
113
|
+
%(th[read] [cur[rent]] Shows current thread.)
|
108
114
|
end
|
109
115
|
end
|
110
116
|
end
|
111
117
|
|
118
|
+
#
|
119
|
+
# Stop execution of a thread.
|
120
|
+
#
|
112
121
|
class ThreadStopCommand < Command
|
113
122
|
self.allow_in_control = true
|
114
123
|
self.allow_in_post_mortem = false
|
@@ -120,6 +129,7 @@ module Byebug
|
|
120
129
|
def execute
|
121
130
|
c = parse_thread_num_for_cmd('thread stop', @match[1])
|
122
131
|
return unless c
|
132
|
+
|
123
133
|
c.suspend
|
124
134
|
display_context(c)
|
125
135
|
end
|
@@ -130,11 +140,14 @@ module Byebug
|
|
130
140
|
end
|
131
141
|
|
132
142
|
def description
|
133
|
-
%
|
143
|
+
%(th[read] stop <n> Stops thread <n>.)
|
134
144
|
end
|
135
145
|
end
|
136
146
|
end
|
137
147
|
|
148
|
+
#
|
149
|
+
# Resume execution of a thread.
|
150
|
+
#
|
138
151
|
class ThreadResumeCommand < Command
|
139
152
|
self.allow_in_control = true
|
140
153
|
self.allow_in_post_mortem = false
|
@@ -146,10 +159,7 @@ module Byebug
|
|
146
159
|
def execute
|
147
160
|
c = parse_thread_num_for_cmd('thread resume', @match[1])
|
148
161
|
return unless c
|
149
|
-
|
150
|
-
errmsg 'Already running'
|
151
|
-
return
|
152
|
-
end
|
162
|
+
return errmsg('Already running') unless c.suspended?
|
153
163
|
c.resume
|
154
164
|
display_context(c)
|
155
165
|
end
|
@@ -160,11 +170,14 @@ module Byebug
|
|
160
170
|
end
|
161
171
|
|
162
172
|
def description
|
163
|
-
%
|
173
|
+
%(th[read] resume <n> Resumes thread <n>.)
|
164
174
|
end
|
165
175
|
end
|
166
176
|
end
|
167
177
|
|
178
|
+
#
|
179
|
+
# Switch execution to a different thread.
|
180
|
+
#
|
168
181
|
class ThreadSwitchCommand < Command
|
169
182
|
self.allow_in_control = true
|
170
183
|
self.allow_in_post_mortem = false
|
@@ -175,11 +188,12 @@ module Byebug
|
|
175
188
|
|
176
189
|
def execute
|
177
190
|
if @match[1] =~ /switch/
|
178
|
-
errmsg
|
179
|
-
return
|
191
|
+
return errmsg('"thread switch" needs a thread number')
|
180
192
|
end
|
193
|
+
|
181
194
|
c = parse_thread_num_for_cmd('thread switch', @match[1])
|
182
195
|
return unless c
|
196
|
+
|
183
197
|
display_context(c)
|
184
198
|
c.step_into 1
|
185
199
|
c.thread.run
|
@@ -192,7 +206,7 @@ module Byebug
|
|
192
206
|
end
|
193
207
|
|
194
208
|
def description
|
195
|
-
%
|
209
|
+
%(th[read] [sw[itch]] <nnn> Switches thread context to <n>.)
|
196
210
|
end
|
197
211
|
end
|
198
212
|
end
|