byebug 9.1.0 → 10.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.
Files changed (129) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +24 -3
  3. data/CONTRIBUTING.md +39 -18
  4. data/GUIDE.md +16 -17
  5. data/README.md +64 -52
  6. data/exe/byebug +6 -0
  7. data/ext/byebug/breakpoint.c +1 -1
  8. data/ext/byebug/byebug.c +16 -16
  9. data/ext/byebug/byebug.h +40 -26
  10. data/ext/byebug/context.c +26 -26
  11. data/ext/byebug/extconf.rb +7 -5
  12. data/ext/byebug/threads.c +8 -8
  13. data/lib/byebug.rb +3 -1
  14. data/lib/byebug/attacher.rb +17 -3
  15. data/lib/byebug/breakpoint.rb +25 -3
  16. data/lib/byebug/command.rb +20 -14
  17. data/lib/byebug/command_list.rb +3 -1
  18. data/lib/byebug/commands.rb +39 -37
  19. data/lib/byebug/commands/break.rb +33 -15
  20. data/lib/byebug/commands/catch.rb +16 -14
  21. data/lib/byebug/commands/condition.rb +11 -9
  22. data/lib/byebug/commands/continue.rb +9 -7
  23. data/lib/byebug/commands/debug.rb +7 -5
  24. data/lib/byebug/commands/delete.rb +11 -9
  25. data/lib/byebug/commands/disable.rb +8 -6
  26. data/lib/byebug/commands/disable/breakpoints.rb +7 -5
  27. data/lib/byebug/commands/disable/display.rb +7 -5
  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 +10 -8
  31. data/lib/byebug/commands/enable.rb +8 -6
  32. data/lib/byebug/commands/enable/breakpoints.rb +7 -5
  33. data/lib/byebug/commands/enable/display.rb +7 -5
  34. data/lib/byebug/commands/finish.rb +8 -6
  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.rb +11 -9
  39. data/lib/byebug/commands/info/breakpoints.rb +17 -11
  40. data/lib/byebug/commands/info/display.rb +16 -7
  41. data/lib/byebug/commands/info/file.rb +12 -10
  42. data/lib/byebug/commands/info/line.rb +5 -3
  43. data/lib/byebug/commands/info/program.rb +8 -6
  44. data/lib/byebug/commands/interrupt.rb +8 -4
  45. data/lib/byebug/commands/irb.rb +9 -7
  46. data/lib/byebug/commands/kill.rb +9 -7
  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 -8
  51. data/lib/byebug/commands/quit.rb +7 -5
  52. data/lib/byebug/commands/restart.rb +13 -11
  53. data/lib/byebug/commands/save.rb +9 -7
  54. data/lib/byebug/commands/set.rb +12 -10
  55. data/lib/byebug/commands/show.rb +7 -5
  56. data/lib/byebug/commands/source.rb +7 -5
  57. data/lib/byebug/commands/step.rb +8 -6
  58. data/lib/byebug/commands/thread.rb +11 -9
  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 -5
  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/tracevar.rb +10 -8
  65. data/lib/byebug/commands/undisplay.rb +10 -8
  66. data/lib/byebug/commands/untracevar.rb +8 -6
  67. data/lib/byebug/commands/up.rb +10 -8
  68. data/lib/byebug/commands/var.rb +12 -10
  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 -7
  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/where.rb +9 -7
  76. data/lib/byebug/context.rb +7 -5
  77. data/lib/byebug/core.rb +25 -25
  78. data/lib/byebug/errors.rb +4 -2
  79. data/lib/byebug/frame.rb +16 -16
  80. data/lib/byebug/helpers/bin.rb +28 -7
  81. data/lib/byebug/helpers/eval.rb +8 -6
  82. data/lib/byebug/helpers/file.rb +4 -2
  83. data/lib/byebug/helpers/frame.rb +5 -3
  84. data/lib/byebug/helpers/parse.rb +5 -3
  85. data/lib/byebug/helpers/path.rb +7 -5
  86. data/lib/byebug/helpers/reflection.rb +2 -0
  87. data/lib/byebug/helpers/string.rb +4 -2
  88. data/lib/byebug/helpers/thread.rb +10 -8
  89. data/lib/byebug/helpers/toggle.rb +10 -8
  90. data/lib/byebug/helpers/var.rb +8 -6
  91. data/lib/byebug/history.rb +7 -5
  92. data/lib/byebug/interface.rb +13 -11
  93. data/lib/byebug/interfaces/local_interface.rb +4 -4
  94. data/lib/byebug/interfaces/remote_interface.rb +21 -9
  95. data/lib/byebug/interfaces/script_interface.rb +2 -0
  96. data/lib/byebug/interfaces/test_interface.rb +5 -3
  97. data/lib/byebug/option_setter.rb +14 -12
  98. data/lib/byebug/printers/base.rb +6 -6
  99. data/lib/byebug/printers/plain.rb +8 -6
  100. data/lib/byebug/printers/texts/base.yml +3 -3
  101. data/lib/byebug/processors/command_processor.rb +11 -12
  102. data/lib/byebug/processors/control_processor.rb +4 -6
  103. data/lib/byebug/processors/post_mortem_processor.rb +4 -2
  104. data/lib/byebug/processors/script_processor.rb +7 -3
  105. data/lib/byebug/remote.rb +45 -65
  106. data/lib/byebug/remote/client.rb +55 -0
  107. data/lib/byebug/remote/server.rb +47 -0
  108. data/lib/byebug/runner.rb +26 -19
  109. data/lib/byebug/setting.rb +10 -4
  110. data/lib/byebug/settings/autoirb.rb +5 -3
  111. data/lib/byebug/settings/autolist.rb +5 -3
  112. data/lib/byebug/settings/autopry.rb +5 -3
  113. data/lib/byebug/settings/autosave.rb +4 -2
  114. data/lib/byebug/settings/basename.rb +4 -2
  115. data/lib/byebug/settings/callstyle.rb +3 -3
  116. data/lib/byebug/settings/fullpath.rb +4 -2
  117. data/lib/byebug/settings/histfile.rb +5 -3
  118. data/lib/byebug/settings/histsize.rb +4 -2
  119. data/lib/byebug/settings/linetrace.rb +4 -2
  120. data/lib/byebug/settings/listsize.rb +4 -2
  121. data/lib/byebug/settings/post_mortem.rb +4 -2
  122. data/lib/byebug/settings/savefile.rb +4 -2
  123. data/lib/byebug/settings/stack_on_error.rb +4 -2
  124. data/lib/byebug/settings/width.rb +3 -1
  125. data/lib/byebug/source_file_formatter.rb +71 -0
  126. data/lib/byebug/subcommands.rb +6 -4
  127. data/lib/byebug/version.rb +1 -1
  128. metadata +8 -5
  129. data/bin/byebug +0 -9
@@ -1,14 +1,12 @@
1
- require 'byebug/processors/command_processor'
1
+ # frozen_string_literal: true
2
+
3
+ require "byebug/processors/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 "byebug/processors/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 "byebug/processors/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
@@ -1,11 +1,13 @@
1
- require 'socket'
2
- require 'byebug/processors/control_processor'
1
+ # frozen_string_literal: true
2
+
3
+ require "socket"
4
+ require "byebug/processors/control_processor"
5
+ require "byebug/remote/server"
6
+ require "byebug/remote/client"
3
7
 
4
8
  #
5
9
  # Remote debugging functionality.
6
10
  #
7
- # @todo Refactor & add tests
8
- #
9
11
  module Byebug
10
12
  # Port number used for remote debugging
11
13
  PORT = 8989 unless defined?(PORT)
@@ -15,8 +17,14 @@ module Byebug
15
17
  attr_accessor :wait_connection
16
18
 
17
19
  # The actual port that the server is started at
18
- attr_accessor :actual_port
19
- attr_reader :actual_control_port
20
+ def actual_port
21
+ server.actual_port
22
+ end
23
+
24
+ # The actual port that the control server is started at
25
+ def actual_control_port
26
+ control.actual_port
27
+ end
20
28
 
21
29
  #
22
30
  # Interrupts the current thread
@@ -26,80 +34,52 @@ module Byebug
26
34
  end
27
35
 
28
36
  #
29
- # Starts a remote byebug
37
+ # Starts the remote server main thread
30
38
  #
31
39
  def start_server(host = nil, port = PORT)
32
- return if @thread
33
-
34
- Context.interface = nil
35
- start
36
-
37
40
  start_control(host, port.zero? ? 0 : port + 1)
38
41
 
39
- mutex = Mutex.new
40
- proceed = ConditionVariable.new
41
-
42
- server = TCPServer.new(host, port)
43
- self.actual_port = server.addr[1]
44
-
45
- yield if block_given?
46
-
47
- @thread = DebugThread.new do
48
- while (session = server.accept)
49
- Context.interface = RemoteInterface.new(session)
50
- mutex.synchronize { proceed.signal } if wait_connection
51
- end
52
- end
42
+ server.start(host, port)
43
+ end
53
44
 
54
- mutex.synchronize { proceed.wait(mutex) } if wait_connection
45
+ #
46
+ # Starts the remote server control thread
47
+ #
48
+ def start_control(host = nil, port = PORT + 1)
49
+ control.start(host, port)
55
50
  end
56
51
 
57
- def start_control(host = nil, ctrl_port = PORT + 1)
58
- return @actual_control_port if @control_thread
59
- server = TCPServer.new(host, ctrl_port)
60
- @actual_control_port = server.addr[1]
52
+ #
53
+ # Connects to the remote byebug
54
+ #
55
+ def start_client(host = "localhost", port = PORT)
56
+ client.start(host, port)
57
+ end
61
58
 
62
- @control_thread = DebugThread.new do
63
- while (session = server.accept)
64
- Context.interface = RemoteInterface.new(session)
59
+ def parse_host_and_port(host_port_spec)
60
+ location = host_port_spec.split(":")
61
+ location[1] ? [location[0], location[1].to_i] : ["localhost", location[0]]
62
+ end
65
63
 
66
- ControlProcessor.new(Byebug.current_context).process_commands
67
- end
68
- end
64
+ private
69
65
 
70
- @actual_control_port
66
+ def client
67
+ @client ||= Remote::Client.new(Context.interface)
71
68
  end
72
69
 
73
- #
74
- # Connects to the remote byebug
75
- #
76
- def start_client(host = 'localhost', port = PORT)
77
- interface = LocalInterface.new
78
- puts 'Connecting to byebug server...'
79
- socket = TCPSocket.new(host, port)
80
- puts 'Connected.'
81
-
82
- while (line = socket.gets)
83
- case line
84
- when /^PROMPT (.*)$/
85
- input = interface.read_command(Regexp.last_match[1])
86
- break unless input
87
- socket.puts input
88
- when /^CONFIRM (.*)$/
89
- input = interface.readline(Regexp.last_match[1])
90
- break unless input
91
- socket.puts input
92
- else
93
- puts line
94
- end
70
+ def server
71
+ @server ||= Remote::Server.new(wait_connection: wait_connection) do |s|
72
+ Context.interface = RemoteInterface.new(s)
95
73
  end
96
-
97
- socket.close
98
74
  end
99
75
 
100
- def parse_host_and_port(host_port_spec)
101
- location = host_port_spec.split(':')
102
- location[1] ? [location[0], location[1].to_i] : ['localhost', location[0]]
76
+ def control
77
+ @control ||= Remote::Server.new(wait_connection: false) do |s|
78
+ context = Byebug.current_context
79
+ interface = RemoteInterface.new(s)
80
+
81
+ ControlProcessor.new(context, interface).process_commands
82
+ end
103
83
  end
104
84
  end
105
85
  end
@@ -0,0 +1,55 @@
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
+ socket.puts input
30
+ when /^CONFIRM (.*)$/
31
+ input = interface.readline(Regexp.last_match[1])
32
+ break unless input
33
+ socket.puts input
34
+ else
35
+ interface.puts line
36
+ end
37
+ end
38
+
39
+ socket.close
40
+ end
41
+
42
+ def started?
43
+ !socket.nil?
44
+ end
45
+
46
+ private
47
+
48
+ def connect_at(host, port)
49
+ interface.puts "Connecting to byebug server at #{host}:#{port}..."
50
+ @socket = TCPSocket.new(host, port)
51
+ interface.puts "Connected."
52
+ end
53
+ end
54
+ end
55
+ 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
@@ -1,12 +1,14 @@
1
- require 'optparse'
2
- require 'English'
3
- require 'byebug/core'
4
- require 'byebug/version'
5
- require 'byebug/helpers/bin'
6
- require 'byebug/helpers/parse'
7
- require 'byebug/helpers/string'
8
- require 'byebug/option_setter'
9
- require 'byebug/processors/control_processor'
1
+ # frozen_string_literal: true
2
+
3
+ require "optparse"
4
+ require "English"
5
+ require "byebug/core"
6
+ require "byebug/version"
7
+ require "byebug/helpers/bin"
8
+ require "byebug/helpers/parse"
9
+ require "byebug/helpers/string"
10
+ require "byebug/option_setter"
11
+ require "byebug/processors/control_processor"
10
12
 
11
13
  module Byebug
12
14
  #
@@ -58,7 +60,9 @@ module Byebug
58
60
  def version=(number)
59
61
  @version ||= number
60
62
 
61
- interface.puts("\n Running byebug #{number}\n")
63
+ interface.puts prettify <<-VERSION
64
+ Running byebug #{number}
65
+ VERSION
62
66
  end
63
67
 
64
68
  def remote=(host_and_port)
@@ -75,11 +79,11 @@ module Byebug
75
79
  # Usage banner.
76
80
  #
77
81
  def banner
78
- prettify <<-EOB
82
+ prettify <<-BANNER
79
83
  byebug #{Byebug::VERSION}
80
84
 
81
85
  Usage: byebug [options] <script.rb> -- <script.rb parameters>
82
- EOB
86
+ BANNER
83
87
  end
84
88
 
85
89
  #
@@ -100,14 +104,12 @@ module Byebug
100
104
 
101
105
  break if quit
102
106
 
103
- ControlProcessor.new.process_commands
107
+ ControlProcessor.new(nil, interface).process_commands
104
108
  end
105
109
  end
106
110
 
107
- attr_writer :interface
108
-
109
111
  def interface
110
- @interface ||= LocalInterface.new
112
+ @interface ||= Context.interface
111
113
  end
112
114
 
113
115
  #
@@ -124,7 +126,12 @@ module Byebug
124
126
  def program
125
127
  @program ||= begin
126
128
  candidate = which($ARGV.shift)
127
- candidate == which('ruby') ? which($ARGV.shift) : candidate
129
+
130
+ if [which("ruby"), RbConfig.ruby].include?(candidate)
131
+ which($ARGV.shift)
132
+ else
133
+ candidate
134
+ end
128
135
  end
129
136
  end
130
137
 
@@ -148,7 +155,7 @@ module Byebug
148
155
  def no_script?
149
156
  return false unless $ARGV.empty?
150
157
 
151
- print_error('You must specify a program to debug')
158
+ print_error("You must specify a program to debug")
152
159
  true
153
160
  end
154
161
 
@@ -168,7 +175,7 @@ module Byebug
168
175
  def invalid_script?
169
176
  return false if syntax_valid?(File.read(program))
170
177
 
171
- print_error('The script has incorrect syntax')
178
+ print_error("The script has incorrect syntax")
172
179
  true
173
180
  end
174
181
 
@@ -1,4 +1,6 @@
1
- require 'byebug/helpers/string'
1
+ # frozen_string_literal: true
2
+
3
+ require "byebug/helpers/string"
2
4
 
3
5
  module Byebug
4
6
  #
@@ -28,7 +30,7 @@ module Byebug
28
30
  end
29
31
 
30
32
  def to_sym
31
- name = self.class.name.gsub(/^Byebug::/, '').gsub(/Setting$/, '')
33
+ name = self.class.name.gsub(/^Byebug::/, "").gsub(/Setting$/, "")
32
34
  name.gsub(/(.)([A-Z])/, '\1_\2').downcase.to_sym
33
35
  end
34
36
 
@@ -63,8 +65,12 @@ module Byebug
63
65
  def help_all
64
66
  output = " List of supported settings:\n\n"
65
67
  width = settings.keys.max_by(&:size).size
66
- settings.values.each do |sett|
67
- output << format(" %-#{width}s -- %s\n", sett.to_sym, sett.banner)
68
+ settings.each_value do |sett|
69
+ output += format(
70
+ " %<name>-#{width}s -- %<description>s\n",
71
+ name: sett.to_sym,
72
+ description: sett.banner
73
+ )
68
74
  end
69
75
  output + "\n"
70
76
  end