byebug 3.2.0 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|