byebug 11.0.1

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.
Files changed (132) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +897 -0
  3. data/CONTRIBUTING.md +58 -0
  4. data/GUIDE.md +1806 -0
  5. data/LICENSE +23 -0
  6. data/README.md +199 -0
  7. data/exe/byebug +6 -0
  8. data/ext/byebug/breakpoint.c +517 -0
  9. data/ext/byebug/byebug.c +905 -0
  10. data/ext/byebug/byebug.h +143 -0
  11. data/ext/byebug/context.c +673 -0
  12. data/ext/byebug/extconf.rb +12 -0
  13. data/ext/byebug/locker.c +96 -0
  14. data/ext/byebug/threads.c +230 -0
  15. data/lib/byebug.rb +3 -0
  16. data/lib/byebug/attacher.rb +48 -0
  17. data/lib/byebug/breakpoint.rb +111 -0
  18. data/lib/byebug/command.rb +111 -0
  19. data/lib/byebug/command_list.rb +34 -0
  20. data/lib/byebug/commands.rb +40 -0
  21. data/lib/byebug/commands/break.rb +112 -0
  22. data/lib/byebug/commands/catch.rb +78 -0
  23. data/lib/byebug/commands/condition.rb +55 -0
  24. data/lib/byebug/commands/continue.rb +68 -0
  25. data/lib/byebug/commands/debug.rb +38 -0
  26. data/lib/byebug/commands/delete.rb +55 -0
  27. data/lib/byebug/commands/disable.rb +33 -0
  28. data/lib/byebug/commands/disable/breakpoints.rb +42 -0
  29. data/lib/byebug/commands/disable/display.rb +43 -0
  30. data/lib/byebug/commands/display.rb +66 -0
  31. data/lib/byebug/commands/down.rb +45 -0
  32. data/lib/byebug/commands/edit.rb +69 -0
  33. data/lib/byebug/commands/enable.rb +33 -0
  34. data/lib/byebug/commands/enable/breakpoints.rb +42 -0
  35. data/lib/byebug/commands/enable/display.rb +43 -0
  36. data/lib/byebug/commands/finish.rb +57 -0
  37. data/lib/byebug/commands/frame.rb +57 -0
  38. data/lib/byebug/commands/help.rb +64 -0
  39. data/lib/byebug/commands/history.rb +39 -0
  40. data/lib/byebug/commands/info.rb +37 -0
  41. data/lib/byebug/commands/info/breakpoints.rb +65 -0
  42. data/lib/byebug/commands/info/display.rb +49 -0
  43. data/lib/byebug/commands/info/file.rb +80 -0
  44. data/lib/byebug/commands/info/line.rb +35 -0
  45. data/lib/byebug/commands/info/program.rb +49 -0
  46. data/lib/byebug/commands/interrupt.rb +34 -0
  47. data/lib/byebug/commands/irb.rb +50 -0
  48. data/lib/byebug/commands/kill.rb +45 -0
  49. data/lib/byebug/commands/list.rb +159 -0
  50. data/lib/byebug/commands/method.rb +53 -0
  51. data/lib/byebug/commands/next.rb +40 -0
  52. data/lib/byebug/commands/pry.rb +41 -0
  53. data/lib/byebug/commands/quit.rb +42 -0
  54. data/lib/byebug/commands/restart.rb +64 -0
  55. data/lib/byebug/commands/save.rb +72 -0
  56. data/lib/byebug/commands/set.rb +79 -0
  57. data/lib/byebug/commands/show.rb +45 -0
  58. data/lib/byebug/commands/skip.rb +85 -0
  59. data/lib/byebug/commands/source.rb +40 -0
  60. data/lib/byebug/commands/step.rb +40 -0
  61. data/lib/byebug/commands/thread.rb +34 -0
  62. data/lib/byebug/commands/thread/current.rb +37 -0
  63. data/lib/byebug/commands/thread/list.rb +43 -0
  64. data/lib/byebug/commands/thread/resume.rb +45 -0
  65. data/lib/byebug/commands/thread/stop.rb +43 -0
  66. data/lib/byebug/commands/thread/switch.rb +46 -0
  67. data/lib/byebug/commands/tracevar.rb +54 -0
  68. data/lib/byebug/commands/undisplay.rb +51 -0
  69. data/lib/byebug/commands/untracevar.rb +36 -0
  70. data/lib/byebug/commands/up.rb +45 -0
  71. data/lib/byebug/commands/var.rb +37 -0
  72. data/lib/byebug/commands/var/all.rb +41 -0
  73. data/lib/byebug/commands/var/args.rb +39 -0
  74. data/lib/byebug/commands/var/const.rb +49 -0
  75. data/lib/byebug/commands/var/global.rb +37 -0
  76. data/lib/byebug/commands/var/instance.rb +39 -0
  77. data/lib/byebug/commands/var/local.rb +39 -0
  78. data/lib/byebug/commands/where.rb +53 -0
  79. data/lib/byebug/context.rb +157 -0
  80. data/lib/byebug/core.rb +115 -0
  81. data/lib/byebug/errors.rb +29 -0
  82. data/lib/byebug/frame.rb +185 -0
  83. data/lib/byebug/helpers/bin.rb +47 -0
  84. data/lib/byebug/helpers/eval.rb +126 -0
  85. data/lib/byebug/helpers/file.rb +63 -0
  86. data/lib/byebug/helpers/frame.rb +75 -0
  87. data/lib/byebug/helpers/parse.rb +75 -0
  88. data/lib/byebug/helpers/path.rb +40 -0
  89. data/lib/byebug/helpers/reflection.rb +19 -0
  90. data/lib/byebug/helpers/string.rb +33 -0
  91. data/lib/byebug/helpers/thread.rb +67 -0
  92. data/lib/byebug/helpers/toggle.rb +62 -0
  93. data/lib/byebug/helpers/var.rb +54 -0
  94. data/lib/byebug/history.rb +130 -0
  95. data/lib/byebug/interface.rb +146 -0
  96. data/lib/byebug/interfaces/local_interface.rb +44 -0
  97. data/lib/byebug/interfaces/remote_interface.rb +50 -0
  98. data/lib/byebug/interfaces/script_interface.rb +33 -0
  99. data/lib/byebug/interfaces/test_interface.rb +67 -0
  100. data/lib/byebug/option_setter.rb +95 -0
  101. data/lib/byebug/printers/base.rb +68 -0
  102. data/lib/byebug/printers/plain.rb +44 -0
  103. data/lib/byebug/printers/texts/base.yml +115 -0
  104. data/lib/byebug/printers/texts/plain.yml +33 -0
  105. data/lib/byebug/processors/command_processor.rb +173 -0
  106. data/lib/byebug/processors/control_processor.rb +24 -0
  107. data/lib/byebug/processors/post_mortem_processor.rb +18 -0
  108. data/lib/byebug/processors/script_processor.rb +49 -0
  109. data/lib/byebug/remote.rb +85 -0
  110. data/lib/byebug/remote/client.rb +57 -0
  111. data/lib/byebug/remote/server.rb +47 -0
  112. data/lib/byebug/runner.rb +198 -0
  113. data/lib/byebug/setting.rb +79 -0
  114. data/lib/byebug/settings/autoirb.rb +29 -0
  115. data/lib/byebug/settings/autolist.rb +29 -0
  116. data/lib/byebug/settings/autopry.rb +29 -0
  117. data/lib/byebug/settings/autosave.rb +17 -0
  118. data/lib/byebug/settings/basename.rb +16 -0
  119. data/lib/byebug/settings/callstyle.rb +20 -0
  120. data/lib/byebug/settings/fullpath.rb +16 -0
  121. data/lib/byebug/settings/histfile.rb +20 -0
  122. data/lib/byebug/settings/histsize.rb +20 -0
  123. data/lib/byebug/settings/linetrace.rb +22 -0
  124. data/lib/byebug/settings/listsize.rb +21 -0
  125. data/lib/byebug/settings/post_mortem.rb +27 -0
  126. data/lib/byebug/settings/savefile.rb +20 -0
  127. data/lib/byebug/settings/stack_on_error.rb +15 -0
  128. data/lib/byebug/settings/width.rb +20 -0
  129. data/lib/byebug/source_file_formatter.rb +71 -0
  130. data/lib/byebug/subcommands.rb +54 -0
  131. data/lib/byebug/version.rb +8 -0
  132. metadata +199 -0
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "byebug/command"
4
+ require "byebug/helpers/eval"
5
+
6
+ module Byebug
7
+ #
8
+ # Enter Pry from byebug's prompt
9
+ #
10
+ class PryCommand < Command
11
+ self.allow_in_post_mortem = true
12
+
13
+ def self.regexp
14
+ /^\s* pry \s*$/x
15
+ end
16
+
17
+ def self.description
18
+ <<-DESCRIPTION
19
+ pry
20
+
21
+ #{short_description}
22
+ DESCRIPTION
23
+ end
24
+
25
+ def self.short_description
26
+ "Starts a Pry session"
27
+ end
28
+
29
+ def execute
30
+ return errmsg(pr("base.errors.only_local")) unless processor.interface.instance_of?(LocalInterface)
31
+
32
+ begin
33
+ require "pry"
34
+ rescue LoadError
35
+ return errmsg(pr("pry.errors.not_installed"))
36
+ end
37
+
38
+ Pry.start(context.frame._binding)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "byebug/command"
4
+
5
+ module Byebug
6
+ #
7
+ # Exit from byebug.
8
+ #
9
+ class QuitCommand < Command
10
+ self.allow_in_control = true
11
+ self.allow_in_post_mortem = true
12
+
13
+ def self.regexp
14
+ /^\s* q(?:uit)? \s* (?:(!|\s+unconditionally))? \s*$/x
15
+ end
16
+
17
+ def self.description
18
+ <<-DESCRIPTION
19
+ q[uit][!| unconditionally]
20
+
21
+ #{short_description}
22
+
23
+ Normally we prompt before exiting. However, if the parameter
24
+ "unconditionally" is given or command is suffixed with "!", we exit
25
+ without asking further questions.
26
+ DESCRIPTION
27
+ end
28
+
29
+ def self.short_description
30
+ "Exits byebug"
31
+ end
32
+
33
+ def execute
34
+ return unless @match[1] || confirm(pr("quit.confirmations.really"))
35
+
36
+ processor.interface.autosave
37
+ processor.interface.close
38
+
39
+ Process.exit!
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "byebug/command"
4
+ require "byebug/helpers/bin"
5
+ require "byebug/helpers/path"
6
+ require "shellwords"
7
+ require "English"
8
+ require "rbconfig"
9
+
10
+ module Byebug
11
+ #
12
+ # Restart debugged program from within byebug.
13
+ #
14
+ class RestartCommand < Command
15
+ include Helpers::BinHelper
16
+ include Helpers::PathHelper
17
+
18
+ self.allow_in_control = true
19
+ self.allow_in_post_mortem = true
20
+
21
+ def self.regexp
22
+ /^\s* restart (?:\s+(?<args>.+))? \s*$/x
23
+ end
24
+
25
+ def self.description
26
+ <<-DESCRIPTION
27
+ restart [args]
28
+
29
+ #{short_description}
30
+
31
+ This is a re-exec - all byebug state is lost. If command arguments are
32
+ passed those are used.
33
+ DESCRIPTION
34
+ end
35
+
36
+ def self.short_description
37
+ "Restarts the debugged program"
38
+ end
39
+
40
+ def execute
41
+ cmd = [$PROGRAM_NAME]
42
+
43
+ cmd = prepend_byebug_bin(cmd)
44
+ cmd = prepend_ruby_bin(cmd)
45
+
46
+ cmd += (@match[:args] ? @match[:args].shellsplit : $ARGV)
47
+
48
+ puts pr("restart.success", cmd: cmd.shelljoin)
49
+ Kernel.exec(*cmd)
50
+ end
51
+
52
+ private
53
+
54
+ def prepend_byebug_bin(cmd)
55
+ cmd.unshift(bin_file) if Byebug.mode == :standalone
56
+ cmd
57
+ end
58
+
59
+ def prepend_ruby_bin(cmd)
60
+ cmd.unshift(RbConfig.ruby) if which("ruby") != which(cmd.first)
61
+ cmd
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "byebug/command"
4
+
5
+ module Byebug
6
+ #
7
+ # Save current settings to use them in another debug session.
8
+ #
9
+ class SaveCommand < Command
10
+ self.allow_in_control = true
11
+ self.allow_in_post_mortem = true
12
+
13
+ def self.regexp
14
+ /^\s* sa(?:ve)? (?:\s+(\S+))? \s*$/x
15
+ end
16
+
17
+ def self.description
18
+ <<-DESCRIPTION
19
+ save[ FILE]
20
+
21
+ #{short_description}
22
+
23
+ Byebug state is saved as a script file. This includes breakpoints,
24
+ catchpoints, display expressions and some settings. If no filename is
25
+ given, byebug will fabricate one.
26
+
27
+ Use the "source" command in another debug session to restore the saved
28
+ file.
29
+ DESCRIPTION
30
+ end
31
+
32
+ def self.short_description
33
+ "Saves current byebug session to a file"
34
+ end
35
+
36
+ def execute
37
+ file = File.open(@match[1] || Setting[:savefile], "w")
38
+
39
+ save_breakpoints(file)
40
+ save_catchpoints(file)
41
+ save_displays(file)
42
+ save_settings(file)
43
+
44
+ print pr("save.messages.done", path: file.path)
45
+ file.close
46
+ end
47
+
48
+ private
49
+
50
+ def save_breakpoints(file)
51
+ Byebug.breakpoints.each do |b|
52
+ file.puts "break #{b.source}:#{b.pos}#{" if #{b.expr}" if b.expr}"
53
+ end
54
+ end
55
+
56
+ def save_catchpoints(file)
57
+ Byebug.catchpoints.each_key do |c|
58
+ file.puts "catch #{c}"
59
+ end
60
+ end
61
+
62
+ def save_displays(file)
63
+ Byebug.displays.each { |d| file.puts "display #{d[1]}" if d[0] }
64
+ end
65
+
66
+ def save_settings(file)
67
+ %w[autoirb autolist basename].each do |setting|
68
+ file.puts "set #{setting} #{Setting[setting.to_sym]}"
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "byebug/command"
4
+ require "byebug/helpers/parse"
5
+
6
+ module Byebug
7
+ #
8
+ # Change byebug settings.
9
+ #
10
+ class SetCommand < Command
11
+ include Helpers::ParseHelper
12
+
13
+ self.allow_in_control = true
14
+ self.allow_in_post_mortem = true
15
+
16
+ def self.regexp
17
+ /^\s* set (?:\s+(?<setting>\w+))? (?:\s+(?<value>\S+))? \s*$/x
18
+ end
19
+
20
+ def self.description
21
+ <<-DESCRIPTION
22
+ set <setting> <value>
23
+
24
+ #{short_description}
25
+
26
+ Boolean values take "on", "off", "true", "false", "1" or "0". If you
27
+ don't specify a value, the boolean setting will be enabled. Conversely,
28
+ you can use "set no<setting>" to disable them.
29
+
30
+ You can see these environment settings with the "show" command.
31
+ DESCRIPTION
32
+ end
33
+
34
+ def self.short_description
35
+ "Modifies byebug settings"
36
+ end
37
+
38
+ def self.help
39
+ super + Setting.help_all
40
+ end
41
+
42
+ def execute
43
+ key = @match[:setting]
44
+ value = @match[:value]
45
+ return puts(help) if key.nil? && value.nil?
46
+
47
+ setting = Setting.find(key)
48
+ return errmsg(pr("set.errors.unknown_setting", key: key)) unless setting
49
+
50
+ if !setting.boolean? && value.nil?
51
+ err = pr("set.errors.must_specify_value", key: key)
52
+ elsif setting.boolean?
53
+ value, err = get_onoff(value, key =~ /^no/ ? false : true)
54
+ elsif setting.integer?
55
+ value, err = get_int(value, setting.to_sym, 1)
56
+ end
57
+ return errmsg(err) if value.nil?
58
+
59
+ setting.value = value
60
+
61
+ puts setting.to_s
62
+ end
63
+
64
+ private
65
+
66
+ def get_onoff(arg, default)
67
+ return default if arg.nil?
68
+
69
+ case arg
70
+ when "1", "on", "true"
71
+ true
72
+ when "0", "off", "false"
73
+ false
74
+ else
75
+ [nil, pr("set.errors.on_off", arg: arg)]
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "byebug/command"
4
+
5
+ module Byebug
6
+ #
7
+ # Show byebug settings.
8
+ #
9
+ class ShowCommand < Command
10
+ self.allow_in_control = true
11
+ self.allow_in_post_mortem = true
12
+
13
+ def self.regexp
14
+ /^\s* show (?:\s+(?<setting>\w+))? \s*$/x
15
+ end
16
+
17
+ def self.description
18
+ <<-DESCRIPTION
19
+ show <setting> <value>
20
+
21
+ #{short_description}
22
+
23
+ You can change them with the "set" command.
24
+ DESCRIPTION
25
+ end
26
+
27
+ def self.short_description
28
+ "Shows byebug settings"
29
+ end
30
+
31
+ def self.help
32
+ super + Setting.help_all
33
+ end
34
+
35
+ def execute
36
+ key = @match[:setting]
37
+ return puts(help) unless key
38
+
39
+ setting = Setting.find(key)
40
+ return errmsg(pr("show.errors.unknown_setting", key: key)) unless setting
41
+
42
+ puts Setting.settings[setting.to_sym]
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "byebug/command"
4
+ require "byebug/helpers/parse"
5
+
6
+ module Byebug
7
+ #
8
+ # Allows the user to continue execution until the next breakpoint, as
9
+ # long as it is different from the current one
10
+ #
11
+ class SkipCommand < Command
12
+ include Helpers::ParseHelper
13
+
14
+ class << self
15
+ attr_writer :file_line, :file_path
16
+ attr_reader :previous_autolist
17
+
18
+ def file_line
19
+ @file_line ||= 0
20
+ end
21
+
22
+ def file_path
23
+ @file_path ||= ""
24
+ end
25
+
26
+ def setup_autolist(value)
27
+ @previous_autolist = ListCommand.always_run
28
+ ListCommand.always_run = value
29
+ end
30
+
31
+ def restore_autolist
32
+ ListCommand.always_run = @previous_autolist
33
+ @previous_autolist = nil
34
+ end
35
+ end
36
+
37
+ def self.regexp
38
+ /^\s* sk(?:ip)? \s*$/x
39
+ end
40
+
41
+ def self.description
42
+ <<-DESCRIPTION
43
+ sk[ip]
44
+
45
+ #{short_description}
46
+ DESCRIPTION
47
+ end
48
+
49
+ def self.short_description
50
+ "Runs until the next breakpoint as long as it is different from the current one"
51
+ end
52
+
53
+ def initialize_attributes
54
+ self.class.always_run = 2
55
+ self.class.setup_autolist(0)
56
+ self.class.file_path = frame.file
57
+ self.class.file_line = frame.line
58
+ end
59
+
60
+ def keep_execution
61
+ [self.class.file_path, self.class.file_line] == [frame.file, frame.line]
62
+ end
63
+
64
+ def reset_attributes
65
+ self.class.always_run = 0
66
+ ListCommand.new(processor).execute if self.class.previous_autolist == 1
67
+ self.class.restore_autolist
68
+ end
69
+
70
+ def auto_run
71
+ return false unless self.class.always_run == 2
72
+
73
+ keep_execution ? processor.proceed! : reset_attributes
74
+ true
75
+ end
76
+
77
+ def execute
78
+ return if auto_run
79
+
80
+ initialize_attributes
81
+ processor.proceed!
82
+ Byebug.stop if Byebug.stoppable?
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "byebug/command"
4
+
5
+ module Byebug
6
+ #
7
+ # Execute a file containing byebug commands.
8
+ #
9
+ # It can be used to restore a previously saved debugging session.
10
+ #
11
+ class SourceCommand < Command
12
+ self.allow_in_control = true
13
+ self.allow_in_post_mortem = true
14
+
15
+ def self.regexp
16
+ /^\s* so(?:urce)? (?:\s+(\S+))? \s*$/x
17
+ end
18
+
19
+ def self.description
20
+ <<-DESCRIPTION
21
+ source <file>
22
+
23
+ #{short_description}
24
+ DESCRIPTION
25
+ end
26
+
27
+ def self.short_description
28
+ "Restores a previously saved byebug session"
29
+ end
30
+
31
+ def execute
32
+ return puts(help) unless @match[1]
33
+
34
+ file = File.expand_path(@match[1]).strip
35
+ return errmsg(pr("source.errors.not_found", file: file)) unless File.exist?(file)
36
+
37
+ processor.interface.read_file(file)
38
+ end
39
+ end
40
+ end