byebug 9.0.5 → 11.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +399 -264
  3. data/CONTRIBUTING.md +12 -19
  4. data/GUIDE.md +40 -26
  5. data/LICENSE +18 -18
  6. data/README.md +103 -74
  7. data/exe/byebug +6 -0
  8. data/ext/byebug/breakpoint.c +2 -2
  9. data/ext/byebug/byebug.c +26 -31
  10. data/ext/byebug/byebug.h +44 -28
  11. data/ext/byebug/context.c +45 -32
  12. data/ext/byebug/extconf.rb +7 -5
  13. data/ext/byebug/locker.c +4 -4
  14. data/ext/byebug/threads.c +12 -12
  15. data/lib/byebug/attacher.rb +18 -4
  16. data/lib/byebug/breakpoint.rb +26 -6
  17. data/lib/byebug/command.rb +20 -14
  18. data/lib/byebug/command_list.rb +3 -1
  19. data/lib/byebug/commands/break.rb +36 -22
  20. data/lib/byebug/commands/catch.rb +16 -18
  21. data/lib/byebug/commands/condition.rb +11 -11
  22. data/lib/byebug/commands/continue.rb +32 -12
  23. data/lib/byebug/commands/debug.rb +7 -5
  24. data/lib/byebug/commands/delete.rb +13 -11
  25. data/lib/byebug/commands/disable/breakpoints.rb +7 -5
  26. data/lib/byebug/commands/disable/display.rb +7 -5
  27. data/lib/byebug/commands/disable.rb +8 -6
  28. data/lib/byebug/commands/display.rb +11 -9
  29. data/lib/byebug/commands/down.rb +10 -8
  30. data/lib/byebug/commands/edit.rb +11 -8
  31. data/lib/byebug/commands/enable/breakpoints.rb +7 -5
  32. data/lib/byebug/commands/enable/display.rb +7 -5
  33. data/lib/byebug/commands/enable.rb +8 -6
  34. data/lib/byebug/commands/finish.rb +9 -7
  35. data/lib/byebug/commands/frame.rb +11 -9
  36. data/lib/byebug/commands/help.rb +7 -5
  37. data/lib/byebug/commands/history.rb +7 -5
  38. data/lib/byebug/commands/info/breakpoints.rb +18 -14
  39. data/lib/byebug/commands/info/display.rb +16 -9
  40. data/lib/byebug/commands/info/file.rb +13 -14
  41. data/lib/byebug/commands/info/line.rb +5 -3
  42. data/lib/byebug/commands/info/program.rb +8 -6
  43. data/lib/byebug/commands/info.rb +11 -9
  44. data/lib/byebug/commands/interrupt.rb +8 -4
  45. data/lib/byebug/commands/irb.rb +13 -12
  46. data/lib/byebug/commands/kill.rb +11 -11
  47. data/lib/byebug/commands/list.rb +41 -46
  48. data/lib/byebug/commands/method.rb +10 -8
  49. data/lib/byebug/commands/next.rb +8 -6
  50. data/lib/byebug/commands/pry.rb +10 -10
  51. data/lib/byebug/commands/quit.rb +10 -8
  52. data/lib/byebug/commands/restart.rb +30 -11
  53. data/lib/byebug/commands/save.rb +10 -8
  54. data/lib/byebug/commands/set.rb +13 -11
  55. data/lib/byebug/commands/show.rb +7 -5
  56. data/lib/byebug/commands/skip.rb +85 -0
  57. data/lib/byebug/commands/source.rb +7 -7
  58. data/lib/byebug/commands/step.rb +8 -6
  59. data/lib/byebug/commands/thread/current.rb +6 -4
  60. data/lib/byebug/commands/thread/list.rb +7 -5
  61. data/lib/byebug/commands/thread/resume.rb +7 -7
  62. data/lib/byebug/commands/thread/stop.rb +6 -4
  63. data/lib/byebug/commands/thread/switch.rb +6 -4
  64. data/lib/byebug/commands/thread.rb +11 -9
  65. data/lib/byebug/commands/tracevar.rb +10 -11
  66. data/lib/byebug/commands/undisplay.rb +12 -11
  67. data/lib/byebug/commands/untracevar.rb +8 -6
  68. data/lib/byebug/commands/up.rb +10 -8
  69. data/lib/byebug/commands/var/all.rb +7 -5
  70. data/lib/byebug/commands/var/args.rb +6 -4
  71. data/lib/byebug/commands/var/const.rb +9 -9
  72. data/lib/byebug/commands/var/global.rb +5 -3
  73. data/lib/byebug/commands/var/instance.rb +6 -4
  74. data/lib/byebug/commands/var/local.rb +6 -4
  75. data/lib/byebug/commands/var.rb +12 -10
  76. data/lib/byebug/commands/where.rb +9 -7
  77. data/lib/byebug/commands.rb +40 -37
  78. data/lib/byebug/context.rb +7 -5
  79. data/lib/byebug/core.rb +26 -25
  80. data/lib/byebug/errors.rb +4 -2
  81. data/lib/byebug/frame.rb +19 -22
  82. data/lib/byebug/helpers/bin.rb +47 -0
  83. data/lib/byebug/helpers/eval.rb +15 -13
  84. data/lib/byebug/helpers/file.rb +6 -4
  85. data/lib/byebug/helpers/frame.rb +7 -5
  86. data/lib/byebug/helpers/parse.rb +5 -5
  87. data/lib/byebug/helpers/path.rb +9 -11
  88. data/lib/byebug/helpers/reflection.rb +2 -0
  89. data/lib/byebug/helpers/string.rb +11 -2
  90. data/lib/byebug/helpers/thread.rb +10 -8
  91. data/lib/byebug/helpers/toggle.rb +28 -27
  92. data/lib/byebug/helpers/var.rb +9 -7
  93. data/lib/byebug/history.rb +20 -11
  94. data/lib/byebug/interface.rb +13 -11
  95. data/lib/byebug/interfaces/local_interface.rb +25 -7
  96. data/lib/byebug/interfaces/remote_interface.rb +21 -9
  97. data/lib/byebug/interfaces/script_interface.rb +4 -1
  98. data/lib/byebug/interfaces/test_interface.rb +5 -3
  99. data/lib/byebug/option_setter.rb +14 -12
  100. data/lib/byebug/printers/base.rb +10 -10
  101. data/lib/byebug/printers/plain.rb +9 -8
  102. data/lib/byebug/printers/texts/base.yml +7 -3
  103. data/lib/byebug/printers/texts/plain.yml +1 -1
  104. data/lib/byebug/processors/command_processor.rb +11 -12
  105. data/lib/byebug/processors/control_processor.rb +4 -6
  106. data/lib/byebug/processors/post_mortem_processor.rb +4 -2
  107. data/lib/byebug/processors/script_processor.rb +7 -3
  108. data/lib/byebug/remote/client.rb +57 -0
  109. data/lib/byebug/remote/server.rb +47 -0
  110. data/lib/byebug/remote.rb +46 -66
  111. data/lib/byebug/runner.rb +43 -49
  112. data/lib/byebug/setting.rb +11 -5
  113. data/lib/byebug/settings/autoirb.rb +7 -5
  114. data/lib/byebug/settings/autolist.rb +7 -5
  115. data/lib/byebug/settings/autopry.rb +7 -5
  116. data/lib/byebug/settings/autosave.rb +4 -2
  117. data/lib/byebug/settings/basename.rb +4 -2
  118. data/lib/byebug/settings/callstyle.rb +4 -3
  119. data/lib/byebug/settings/fullpath.rb +4 -2
  120. data/lib/byebug/settings/histfile.rb +5 -3
  121. data/lib/byebug/settings/histsize.rb +4 -2
  122. data/lib/byebug/settings/linetrace.rb +6 -4
  123. data/lib/byebug/settings/listsize.rb +4 -2
  124. data/lib/byebug/settings/post_mortem.rb +6 -4
  125. data/lib/byebug/settings/savefile.rb +4 -2
  126. data/lib/byebug/settings/stack_on_error.rb +4 -2
  127. data/lib/byebug/settings/width.rb +3 -1
  128. data/lib/byebug/source_file_formatter.rb +71 -0
  129. data/lib/byebug/subcommands.rb +6 -4
  130. data/lib/byebug/version.rb +2 -1
  131. data/lib/byebug.rb +3 -1
  132. metadata +22 -20
  133. data/bin/byebug +0 -7
@@ -1,6 +1,8 @@
1
- require 'byebug/setting'
2
- require 'byebug/history'
3
- require 'byebug/helpers/file'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "setting"
4
+ require_relative "history"
5
+ require_relative "helpers/file"
4
6
 
5
7
  #
6
8
  # Namespace for all of byebug's code
@@ -20,7 +22,7 @@ module Byebug
20
22
  def initialize
21
23
  @command_queue = []
22
24
  @history = History.new
23
- @last_line = ''
25
+ @last_line = ""
24
26
  end
25
27
 
26
28
  def last_if_empty(input)
@@ -97,7 +99,7 @@ module Byebug
97
99
  # Confirms user introduced an affirmative response to the input stream.
98
100
  #
99
101
  def confirm(prompt)
100
- readline(prompt) == 'y'
102
+ readline(prompt) == "y"
101
103
  end
102
104
 
103
105
  def close
@@ -124,7 +126,7 @@ module Byebug
124
126
  # array of commands: [cmd1, cmd2, ..., cmdN]
125
127
  #
126
128
  def split_commands(cmd_line)
127
- return [''] if cmd_line.empty?
129
+ return [""] if cmd_line.empty?
128
130
 
129
131
  cmd_line.split(/;/).each_with_object([]) do |v, m|
130
132
  if m.empty? || m.last[-1] != '\\'
@@ -132,13 +134,13 @@ module Byebug
132
134
  next
133
135
  end
134
136
 
135
- m.last[-1, 1] = ''
136
- m.last << ';' << v
137
+ m.last[-1, 1] = ""
138
+ m.last << ";" << v
137
139
  end
138
140
  end
139
141
  end
140
142
  end
141
143
 
142
- require 'byebug/interfaces/local_interface'
143
- require 'byebug/interfaces/script_interface'
144
- require 'byebug/interfaces/remote_interface'
144
+ require_relative "interfaces/local_interface"
145
+ require_relative "interfaces/script_interface"
146
+ require_relative "interfaces/remote_interface"
@@ -1,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Byebug
3
4
  #
4
5
  # Interface class for standard byebug use.
5
6
  #
6
7
  class LocalInterface < Interface
7
- EOF_ALIAS = 'continue'.freeze
8
+ EOF_ALIAS = "continue"
8
9
 
9
10
  def initialize
10
11
  super()
@@ -20,9 +21,7 @@ module Byebug
20
21
  # @param prompt Prompt to be displayed.
21
22
  #
22
23
  def readline(prompt)
23
- with_repl_like_sigint do
24
- Readline.readline(prompt, false) || EOF_ALIAS
25
- end
24
+ with_repl_like_sigint { without_readline_completion { Readline.readline(prompt) || EOF_ALIAS } }
26
25
  end
27
26
 
28
27
  #
@@ -33,13 +32,32 @@ module Byebug
33
32
  # @note Any external 'INT' traps are overriden during this method.
34
33
  #
35
34
  def with_repl_like_sigint
36
- orig_handler = trap('INT') { raise Interrupt }
35
+ orig_handler = trap("INT") { raise Interrupt }
37
36
  yield
38
37
  rescue Interrupt
39
- puts('^C')
38
+ puts("^C")
40
39
  retry
41
40
  ensure
42
- trap('INT', orig_handler)
41
+ trap("INT", orig_handler)
42
+ end
43
+
44
+ #
45
+ # Disable any Readline completion procs.
46
+ #
47
+ # Other gems, for example, IRB could've installed completion procs that are
48
+ # dependent on them being loaded. Disable those while byebug is the REPL
49
+ # making use of Readline.
50
+ #
51
+ def without_readline_completion
52
+ orig_completion = Readline.completion_proc
53
+ return yield unless orig_completion
54
+
55
+ begin
56
+ Readline.completion_proc = ->(_) { nil }
57
+ yield
58
+ ensure
59
+ Readline.completion_proc = orig_completion
60
+ end
43
61
  end
44
62
  end
45
63
  end
@@ -1,4 +1,6 @@
1
- require 'byebug/history'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../history"
2
4
 
3
5
  module Byebug
4
6
  #
@@ -14,25 +16,35 @@ module Byebug
14
16
 
15
17
  def read_command(prompt)
16
18
  super("PROMPT #{prompt}")
19
+ rescue Errno::EPIPE, Errno::ECONNABORTED
20
+ "continue"
17
21
  end
18
22
 
19
23
  def confirm(prompt)
20
24
  super("CONFIRM #{prompt}")
25
+ rescue Errno::EPIPE, Errno::ECONNABORTED
26
+ false
27
+ end
28
+
29
+ def print(message)
30
+ super(message)
31
+ rescue Errno::EPIPE, Errno::ECONNABORTED
32
+ nil
33
+ end
34
+
35
+ def puts(message)
36
+ super(message)
37
+ rescue Errno::EPIPE, Errno::ECONNABORTED
38
+ nil
21
39
  end
22
40
 
23
41
  def close
24
42
  output.close
25
- rescue IOError
26
- errmsg('Error closing the interface...')
27
43
  end
28
44
 
29
45
  def readline(prompt)
30
- output.puts(prompt)
31
-
32
- result = input.gets
33
- raise IOError unless result
34
-
35
- result.chomp
46
+ puts(prompt)
47
+ (input.gets || "continue").chomp
36
48
  end
37
49
  end
38
50
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Interface class for command execution from script files.
@@ -22,7 +24,8 @@ module Byebug
22
24
  def readline(*)
23
25
  while (result = input.gets)
24
26
  output.puts "+ #{result}" if @verbose
25
- next if result =~ /^\s*#/
27
+ next if /^\s*#/.match?(result)
28
+
26
29
  return result.chomp
27
30
  end
28
31
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Custom interface for easier assertions
@@ -41,9 +43,9 @@ module Byebug
41
43
 
42
44
  def inspect
43
45
  [
44
- 'Input:', input.join("\n"),
45
- 'Output:', output.join("\n"),
46
- 'Error:', error.join("\n")
46
+ "Input:", input.join("\n"),
47
+ "Output:", output.join("\n"),
48
+ "Error:", error.join("\n")
47
49
  ].join("\n")
48
50
  end
49
51
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Byebug
2
4
  #
3
5
  # Handles byebug's command line options
@@ -25,67 +27,67 @@ module Byebug
25
27
  private
26
28
 
27
29
  def debug
28
- @opts.on '-d', '--debug', 'Set $DEBUG=true' do
30
+ @opts.on "-d", "--debug", "Set $DEBUG=true" do
29
31
  $DEBUG = true
30
32
  end
31
33
  end
32
34
 
33
35
  def include_flag
34
- @opts.on '-I', '--include list', 'Add to paths to $LOAD_PATH' do |list|
35
- $LOAD_PATH.push(list.split(':')).flatten!
36
+ @opts.on "-I", "--include list", "Add to paths to $LOAD_PATH" do |list|
37
+ $LOAD_PATH.push(list.split(":")).flatten!
36
38
  end
37
39
  end
38
40
 
39
41
  def post_mortem
40
- @opts.on '-m', '--[no-]post-mortem', 'Use post-mortem mode' do |v|
42
+ @opts.on "-m", "--[no-]post-mortem", "Use post-mortem mode" do |v|
41
43
  Setting[:post_mortem] = v
42
44
  end
43
45
  end
44
46
 
45
47
  def quit
46
- @opts.on '-q', '--[no-]quit', 'Quit when script finishes' do |v|
48
+ @opts.on "-q", "--[no-]quit", "Quit when script finishes" do |v|
47
49
  @runner.quit = v
48
50
  end
49
51
  end
50
52
 
51
53
  def rc
52
- @opts.on '-x', '--[no-]rc', 'Run byebug initialization file' do |v|
54
+ @opts.on "-x", "--[no-]rc", "Run byebug initialization file" do |v|
53
55
  @runner.init_script = v
54
56
  end
55
57
  end
56
58
 
57
59
  def stop
58
- @opts.on '-s', '--[no-]stop', 'Stop when script is loaded' do |v|
60
+ @opts.on "-s", "--[no-]stop", "Stop when script is loaded" do |v|
59
61
  @runner.stop = v
60
62
  end
61
63
  end
62
64
 
63
65
  def require_flag
64
- @opts.on '-r', '--require file', 'Require library before script' do |lib|
66
+ @opts.on "-r", "--require file", "Require library before script" do |lib|
65
67
  require lib
66
68
  end
67
69
  end
68
70
 
69
71
  def remote
70
- @opts.on '-R', '--remote [host:]port', 'Remote debug [host:]port' do |p|
72
+ @opts.on "-R", "--remote [host:]port", "Remote debug [host:]port" do |p|
71
73
  @runner.remote = p
72
74
  end
73
75
  end
74
76
 
75
77
  def trace
76
- @opts.on '-t', '--[no-]trace', 'Turn on line tracing' do |v|
78
+ @opts.on "-t", "--[no-]trace", "Turn on line tracing" do |v|
77
79
  Setting[:linetrace] = v
78
80
  end
79
81
  end
80
82
 
81
83
  def version
82
- @opts.on '-v', '--version', 'Print program version' do
84
+ @opts.on "-v", "--version", "Print program version" do
83
85
  @runner.version = Byebug::VERSION
84
86
  end
85
87
  end
86
88
 
87
89
  def help
88
- @opts.on '-h', '--help', 'Display this message' do
90
+ @opts.on "-h", "--help", "Display this message" do
89
91
  @runner.help = @opts.help
90
92
  end
91
93
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
- require 'yaml'
2
+
3
+ require "yaml"
3
4
 
4
5
  module Byebug
5
6
  module Printers
@@ -10,33 +11,32 @@ module Byebug
10
11
  class MissedPath < StandardError; end
11
12
  class MissedArgument < StandardError; end
12
13
 
13
- SEPARATOR = '.'.freeze
14
+ SEPARATOR = "."
14
15
 
15
16
  def type
16
- self.class.name.split('::').last.downcase
17
+ self.class.name.split("::").last.downcase
17
18
  end
18
19
 
19
20
  private
20
21
 
21
22
  def locate(path)
22
23
  result = nil
23
- contents.each do |_, contents|
24
+ contents.each_value do |contents|
24
25
  result = parts(path).reduce(contents) do |r, part|
25
- r && r.key?(part) ? r[part] : nil
26
+ r&.key?(part) ? r[part] : nil
26
27
  end
27
28
  break if result
28
29
  end
29
30
  raise MissedPath, "Can't find part path '#{path}'" unless result
31
+
30
32
  result
31
33
  end
32
34
 
33
35
  def translate(string, args = {})
34
36
  # they may contain #{} string interpolation
35
- string.gsub(/\|\w+$/, '').gsub(/([^#]?){([^}]*)}/) do
37
+ string.gsub(/\|\w+$/, "").gsub(/([^#]?){([^}]*)}/) do
36
38
  key = Regexp.last_match[2].to_s
37
- unless args.key?(key.to_sym)
38
- raise MissedArgument, "Missed argument #{key} for '#{string}'"
39
- end
39
+ raise MissedArgument, "Missed argument #{key} for '#{string}'" unless args.key?(key.to_sym)
40
40
 
41
41
  "#{Regexp.last_match[1]}#{args[key.to_sym]}"
42
42
  end
@@ -61,7 +61,7 @@ module Byebug
61
61
  end
62
62
 
63
63
  def contents_files
64
- [File.expand_path(File.join('..', 'texts', 'base.yml'), __FILE__)]
64
+ [File.join(__dir__, "texts", "base.yml")]
65
65
  end
66
66
  end
67
67
  end
@@ -1,4 +1,6 @@
1
- require 'byebug/printers/base'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
2
4
 
3
5
  module Byebug
4
6
  module Printers
@@ -8,7 +10,7 @@ module Byebug
8
10
  class Plain < Base
9
11
  def print(path, args = {})
10
12
  message = translate(locate(path), args)
11
- tail = parts(path).include?('confirmations') ? ' (y/n) ' : "\n"
13
+ tail = parts(path).include?("confirmations") ? " (y/n) " : "\n"
12
14
  message << tail
13
15
  end
14
16
 
@@ -20,12 +22,12 @@ module Byebug
20
22
  lines.join
21
23
  end
22
24
 
23
- def print_variables(variables, *_)
24
- print_collection('variable.variable', variables) do |(key, value), _|
25
- value = value.nil? ? 'nil' : value.to_s
25
+ def print_variables(variables, *_unused)
26
+ print_collection("variable.variable", variables) do |(key, value), _|
27
+ value = value.nil? ? "nil" : value.to_s
26
28
  if "#{key} = #{value}".size > Setting[:width]
27
29
  key_size = "#{key} = ".size
28
- value = value[0..Setting[:width] - key_size - 4] + '...'
30
+ value = value[0..Setting[:width] - key_size - 4] + "..."
29
31
  end
30
32
 
31
33
  { key: key, value: value }
@@ -35,8 +37,7 @@ module Byebug
35
37
  private
36
38
 
37
39
  def contents_files
38
- [File.expand_path(File.join('..', 'texts', 'plain.yml'), __FILE__)] +
39
- super
40
+ [File.join(__dir__, "texts", "plain.yml")] + super
40
41
  end
41
42
  end
42
43
  end
@@ -1,10 +1,10 @@
1
1
  base:
2
2
  errors:
3
- only_local: 'Command is available only in local mode.'
3
+ only_local: "Command is available only in local mode."
4
4
 
5
5
  break:
6
6
  errors:
7
- line: "Line {line} is not a valid breakpoint in file {file}"
7
+ line: "Line {line} is not a valid breakpoint in file {file}.\n\nValid break points are:\n{valid_breakpoints}"
8
8
  location: "Invalid breakpoint location"
9
9
  state: "We are not in a state that has an associated file"
10
10
  class: "Unknown class {klass}"
@@ -16,6 +16,8 @@ break:
16
16
  not_changed: "Incorrect expression \"{expr}\", breakpoint not changed"
17
17
  confirmations:
18
18
  delete_all: "Delete all breakpoints?"
19
+ messages:
20
+ breakpoint_deleted: "Deleted breakpoint {pos}"
19
21
 
20
22
  catch:
21
23
  added: "Catching exception {exception}."
@@ -60,7 +62,7 @@ info:
60
62
 
61
63
  pry:
62
64
  errors:
63
- not_installed: 'You need to install pry in order to run this command'
65
+ not_installed: "You need to install pry in order to run this command"
64
66
 
65
67
  quit:
66
68
  confirmations:
@@ -97,6 +99,8 @@ toggle:
97
99
  no_display: "No display expressions have been set"
98
100
  syntax: "\"{toggle}\" must be followed by \"display\", \"breakpoints\" or breakpoint ids"
99
101
  expression: "Expression \"{expr}\" syntactically incorrect; breakpoint remains disabled."
102
+ messages:
103
+ toggled: "Breakpoint {bpnum} {endis}abled"
100
104
 
101
105
  parse:
102
106
  errors:
@@ -1,5 +1,5 @@
1
1
  break:
2
- created: "Successfully created breakpoint with id {id}"
2
+ created: "Created breakpoint {id} at {file}:{line}"
3
3
 
4
4
  display:
5
5
  result: "{n}: {exp} = {result}"
@@ -1,7 +1,9 @@
1
- require 'forwardable'
1
+ # frozen_string_literal: true
2
2
 
3
- require 'byebug/helpers/eval'
4
- require 'byebug/errors'
3
+ require "forwardable"
4
+
5
+ require_relative "../helpers/eval"
6
+ require_relative "../errors"
5
7
 
6
8
  module Byebug
7
9
  #
@@ -16,19 +18,16 @@ module Byebug
16
18
  include Helpers::EvalHelper
17
19
 
18
20
  attr_accessor :prev_line
19
- attr_reader :context
21
+ attr_reader :context, :interface
20
22
 
21
- def initialize(context)
23
+ def initialize(context, interface = LocalInterface.new)
22
24
  @context = context
25
+ @interface = interface
23
26
 
24
27
  @proceed = false
25
28
  @prev_line = nil
26
29
  end
27
30
 
28
- def interface
29
- @interface ||= Context.interface
30
- end
31
-
32
31
  def printer
33
32
  @printer ||= Printers::Plain.new
34
33
  end
@@ -106,7 +105,7 @@ module Byebug
106
105
  # Prompt shown before reading a command.
107
106
  #
108
107
  def prompt
109
- '(byebug) '
108
+ "(byebug) "
110
109
  end
111
110
 
112
111
  def before_repl
@@ -129,7 +128,7 @@ module Byebug
129
128
  cmd = interface.read_command(prompt)
130
129
  return if cmd.nil?
131
130
 
132
- next if cmd == ''
131
+ next if cmd == ""
133
132
 
134
133
  run_cmd(cmd)
135
134
  end
@@ -167,7 +166,7 @@ module Byebug
167
166
 
168
167
  def safely
169
168
  yield
170
- rescue => e
169
+ rescue StandardError => e
171
170
  errmsg(e.message)
172
171
  end
173
172
  end
@@ -1,14 +1,12 @@
1
- require 'byebug/processors/command_processor'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "command_processor"
2
4
 
3
5
  module Byebug
4
6
  #
5
7
  # Processes commands when there's not program running
6
8
  #
7
9
  class ControlProcessor < CommandProcessor
8
- def initialize(context = nil)
9
- @context = context
10
- end
11
-
12
10
  #
13
11
  # Available commands
14
12
  #
@@ -20,7 +18,7 @@ module Byebug
20
18
  # Prompt shown before reading a command.
21
19
  #
22
20
  def prompt
23
- '(byebug:ctrl) '
21
+ "(byebug:ctrl) "
24
22
  end
25
23
  end
26
24
  end
@@ -1,4 +1,6 @@
1
- require 'byebug/processors/command_processor'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "command_processor"
2
4
 
3
5
  module Byebug
4
6
  #
@@ -10,7 +12,7 @@ module Byebug
10
12
  end
11
13
 
12
14
  def prompt
13
- '(byebug:post_mortem) '
15
+ "(byebug:post_mortem) "
14
16
  end
15
17
  end
16
18
  end
@@ -1,4 +1,6 @@
1
- require 'byebug/processors/command_processor'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "command_processor"
2
4
 
3
5
  module Byebug
4
6
  #
@@ -24,6 +26,8 @@ module Byebug
24
26
  end
25
27
 
26
28
  def after_repl
29
+ super
30
+
27
31
  interface.close
28
32
  end
29
33
 
@@ -31,14 +35,14 @@ module Byebug
31
35
  # Prompt shown before reading a command.
32
36
  #
33
37
  def prompt
34
- '(byebug:ctrl) '
38
+ "(byebug:ctrl) "
35
39
  end
36
40
 
37
41
  private
38
42
 
39
43
  def without_exceptions
40
44
  yield
41
- rescue
45
+ rescue StandardError
42
46
  nil
43
47
  end
44
48
  end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "socket"
4
+
5
+ module Byebug
6
+ module Remote
7
+ #
8
+ # Client for remote debugging
9
+ #
10
+ class Client
11
+ attr_reader :interface, :socket
12
+
13
+ def initialize(interface)
14
+ @interface = interface
15
+ @socket = nil
16
+ end
17
+
18
+ #
19
+ # Connects to the remote byebug
20
+ #
21
+ def start(host = "localhost", port = PORT)
22
+ connect_at(host, port)
23
+
24
+ while (line = socket.gets)
25
+ case line
26
+ when /^PROMPT (.*)$/
27
+ input = interface.read_command(Regexp.last_match[1])
28
+ break unless input
29
+
30
+ socket.puts input
31
+ when /^CONFIRM (.*)$/
32
+ input = interface.readline(Regexp.last_match[1])
33
+ break unless input
34
+
35
+ socket.puts input
36
+ else
37
+ interface.puts line
38
+ end
39
+ end
40
+
41
+ socket.close
42
+ end
43
+
44
+ def started?
45
+ !socket.nil?
46
+ end
47
+
48
+ private
49
+
50
+ def connect_at(host, port)
51
+ interface.puts "Connecting to byebug server at #{host}:#{port}..."
52
+ @socket = TCPSocket.new(host, port)
53
+ interface.puts "Connected."
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "socket"
4
+
5
+ module Byebug
6
+ module Remote
7
+ #
8
+ # Server for remote debugging
9
+ #
10
+ class Server
11
+ attr_reader :actual_port, :wait_connection
12
+
13
+ def initialize(wait_connection:, &block)
14
+ @thread = nil
15
+ @wait_connection = wait_connection
16
+ @main_loop = block
17
+ end
18
+
19
+ #
20
+ # Start the remote debugging server
21
+ #
22
+ def start(host, port)
23
+ return if @thread
24
+
25
+ if wait_connection
26
+ mutex = Mutex.new
27
+ proceed = ConditionVariable.new
28
+ end
29
+
30
+ server = TCPServer.new(host, port)
31
+ @actual_port = server.addr[1]
32
+
33
+ yield if block_given?
34
+
35
+ @thread = DebugThread.new do
36
+ while (session = server.accept)
37
+ @main_loop.call(session)
38
+
39
+ mutex.synchronize { proceed.signal } if wait_connection
40
+ end
41
+ end
42
+
43
+ mutex.synchronize { proceed.wait(mutex) } if wait_connection
44
+ end
45
+ end
46
+ end
47
+ end