diff --git a/README.md b/README.md index c8f17c877..2cd3ddf51 100644 --- a/README.md +++ b/README.md @@ -244,16 +244,16 @@ It will help if you want to know what the program is doing. If you want to run a command written in Ruby like `rake`, `rails`, `bundle`, `rspec`, and so on, you can use `rdbg -c` option. -* Without `-c` option, `rdbg ` means that `` is Ruby script and invoke it like `ruby ` with the debugger. -* With `-c` option, `rdbg -c ` means that `` is a command in `PATH` and simply invokes it with the debugger. +* Without the `-c` option, `rdbg ` means that `` is a Ruby script and invokes it like `ruby ` with the debugger. +* With the `-c` option, `rdbg -c ` means that `` is a command in `PATH` and simply invokes it with the debugger. Examples: * `rdbg -c -- rails server` * `rdbg -c -- bundle exec ruby foo.rb` * `rdbg -c -- bundle exec rake test` -* `rdbg -c -- ruby target.rb` is same as `rdbg target.rb` +* `rdbg -c -- ruby target.rb` is the same as `rdbg target.rb` -NOTE: `--` is needed to separate the command line options for `rdbg` and invoking command. For example, `rdbg -c rake -T` is recognized like `rdbg -c -T -- rake`. It should be `rdbg -c -- rake -T`. +NOTE: `--` is needed to separate the command line options for `rdbg` and the invoking command. For example, `rdbg -c rake -T` is recognized like `rdbg -c -T -- rake`. It should be `rdbg -c -- rake -T`. NOTE: If you want to use bundler (`bundle` command), you need to write `gem debug` line in your `Gemfile`. @@ -330,7 +330,9 @@ When `rdbg --attach` connects to the debuggee, you can use any debug commands (s NOTE: If you use the `quit` command, only the remote console exits and the debuggee program continues to run (and you can connect it again). If you want to exit the debuggee program, use `kill` command. -If you want to use TCP/IP for the remote debugging, you need to specify the port and host with `--port` like `rdbg --open --port 12345` and it binds to `localhost:12345`. +If you want to use TCP/IP for the remote debugging, you need to specify the port and host with `--port` like `rdbg --open --port 12345` and it binds to `localhost:12345`. You can add an optional `--port_range` option to try multiple ports in a reliable way. For example, `rdbg --open --port 12345 --port_range 10` will try to bind to 12345, 12346, 12347, ... until it finds an available port. + +```shell To connect to the debuggee, you need to specify the port. @@ -499,6 +501,7 @@ config set no_color true * REMOTE * `RUBY_DEBUG_OPEN` (`open`): Open remote port (same as `rdbg --open` option) * `RUBY_DEBUG_PORT` (`port`): TCP/IP remote debugging: port + * `RUBY_DEBUG_PORT_RANGE` (`port_range`): TCP/IP remote debugging: length of port range * `RUBY_DEBUG_HOST` (`host`): TCP/IP remote debugging: host (default: 127.0.0.1) * `RUBY_DEBUG_SOCK_PATH` (`sock_path`): UNIX Domain Socket remote debugging: socket path * `RUBY_DEBUG_SOCK_DIR` (`sock_dir`): UNIX Domain Socket remote debugging: socket directory @@ -907,6 +910,7 @@ Debug console mode: Now rdbg, vscode and chrome is supported. --sock-path=SOCK_PATH UNIX Domain socket path --port=PORT Listening TCP/IP port + --port-range=PORT_RANGE Number of ports to try to connect to --host=HOST Listening TCP/IP host --cookie=COOKIE Set a cookie for connection --session-name=NAME Session name diff --git a/debug.gemspec b/debug.gemspec index 2a5891f32..f77ae68ae 100644 --- a/debug.gemspec +++ b/debug.gemspec @@ -14,6 +14,7 @@ Gem::Specification.new do |spec| spec.metadata["homepage_uri"] = spec.homepage spec.metadata["source_code_uri"] = spec.homepage + spec.metadata["changelog_uri"] = "#{spec.homepage}/releases/tag/v#{spec.version}" # Specify which files should be added to the gem when it is released. # The `git ls-files -z` loads the files in the RubyGem that have been added into git. diff --git a/lib/debug/config.rb b/lib/debug/config.rb index 86b9bfdc9..0fcbea7ec 100644 --- a/lib/debug/config.rb +++ b/lib/debug/config.rb @@ -44,6 +44,7 @@ module DEBUGGER__ # remote setting open: ['RUBY_DEBUG_OPEN', "REMOTE: Open remote port (same as `rdbg --open` option)"], port: ['RUBY_DEBUG_PORT', "REMOTE: TCP/IP remote debugging: port"], + port_range: ['RUBY_DEBUG_PORT_RANGE', "REMOTE: TCP/IP remote debugging: length of port range"], host: ['RUBY_DEBUG_HOST', "REMOTE: TCP/IP remote debugging: host", :string, "127.0.0.1"], sock_path: ['RUBY_DEBUG_SOCK_PATH', "REMOTE: UNIX Domain Socket remote debugging: socket path"], sock_dir: ['RUBY_DEBUG_SOCK_DIR', "REMOTE: UNIX Domain Socket remote debugging: socket directory"], @@ -352,6 +353,9 @@ def self.parse_argv argv o.on('--port=PORT', 'Listening TCP/IP port') do |port| config[:port] = port end + o.on('--port-range=PORT_RANGE', 'Number of ports to try to connect to') do |port_range| + config[:port_range] = port_range + end o.on('--host=HOST', 'Listening TCP/IP host') do |host| config[:host] = host end diff --git a/lib/debug/server.rb b/lib/debug/server.rb index 0915b5bd5..41f3bca13 100644 --- a/lib/debug/server.rb +++ b/lib/debug/server.rb @@ -399,6 +399,13 @@ def initialize host: nil, port: nil raise "Specify digits for port number" end end + @port_range = if @port.zero? + 0 + else + port_range_str = (CONFIG[:port_range] || "0").to_s + raise "Specify a positive integer <=16 for port range" unless port_range_str.match?(/\A\d+\z/) && port_range_str.to_i <= 16 + port_range_str.to_i + end @uuid = nil # for CDP super() @@ -452,7 +459,9 @@ def accept end end rescue Errno::EADDRINUSE - if retry_cnt < 10 + number_of_retries = @port_range.zero? ? 10 : @port_range + if retry_cnt < number_of_retries + @port += 1 unless @port_range.zero? retry_cnt += 1 sleep 0.1 retry diff --git a/lib/debug/server_cdp.rb b/lib/debug/server_cdp.rb index 3826f1242..9adb09795 100644 --- a/lib/debug/server_cdp.rb +++ b/lib/debug/server_cdp.rb @@ -688,7 +688,7 @@ def sock skip: false yield $stderr end - def puts result='' + def puts result = "" # STDERR.puts "puts: #{result}" # send_event 'output', category: 'stderr', output: "PUTS!!: " + result.to_s end diff --git a/lib/debug/server_dap.rb b/lib/debug/server_dap.rb index 87c22ca45..7502182a4 100644 --- a/lib/debug/server_dap.rb +++ b/lib/debug/server_dap.rb @@ -501,7 +501,7 @@ def respond req, res send_response(req, **res) end - def puts result + def puts result = "" # STDERR.puts "puts: #{result}" send_event 'output', category: 'console', output: "#{result&.chomp}\n" end diff --git a/lib/debug/thread_client.rb b/lib/debug/thread_client.rb index 80a434b0c..1d35d754a 100644 --- a/lib/debug/thread_client.rb +++ b/lib/debug/thread_client.rb @@ -44,7 +44,7 @@ def skip_location?(loc) end module GlobalVariablesHelper - SKIP_GLOBAL_LIST = %i[$= $KCODE $-K $SAFE].freeze + SKIP_GLOBAL_LIST = %i[$= $KCODE $-K $SAFE $FILENAME].freeze def safe_global_variables global_variables.reject{|name| SKIP_GLOBAL_LIST.include? name } end diff --git a/lib/debug/version.rb b/lib/debug/version.rb index cf7b7b23e..f1d1e9467 100644 --- a/lib/debug/version.rb +++ b/lib/debug/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module DEBUGGER__ - VERSION = "1.9.2" + VERSION = "1.10.0" end diff --git a/misc/README.md.erb b/misc/README.md.erb index e6751997b..90bb57e17 100644 --- a/misc/README.md.erb +++ b/misc/README.md.erb @@ -244,16 +244,16 @@ It will help if you want to know what the program is doing. If you want to run a command written in Ruby like `rake`, `rails`, `bundle`, `rspec`, and so on, you can use `rdbg -c` option. -* Without `-c` option, `rdbg ` means that `` is Ruby script and invoke it like `ruby ` with the debugger. -* With `-c` option, `rdbg -c ` means that `` is a command in `PATH` and simply invokes it with the debugger. +* Without the `-c` option, `rdbg ` means that `` is a Ruby script and invokes it like `ruby ` with the debugger. +* With the `-c` option, `rdbg -c ` means that `` is a command in `PATH` and simply invokes it with the debugger. Examples: * `rdbg -c -- rails server` * `rdbg -c -- bundle exec ruby foo.rb` * `rdbg -c -- bundle exec rake test` -* `rdbg -c -- ruby target.rb` is same as `rdbg target.rb` +* `rdbg -c -- ruby target.rb` is the same as `rdbg target.rb` -NOTE: `--` is needed to separate the command line options for `rdbg` and invoking command. For example, `rdbg -c rake -T` is recognized like `rdbg -c -T -- rake`. It should be `rdbg -c -- rake -T`. +NOTE: `--` is needed to separate the command line options for `rdbg` and the invoking command. For example, `rdbg -c rake -T` is recognized like `rdbg -c -T -- rake`. It should be `rdbg -c -- rake -T`. NOTE: If you want to use bundler (`bundle` command), you need to write `gem debug` line in your `Gemfile`. @@ -330,7 +330,9 @@ When `rdbg --attach` connects to the debuggee, you can use any debug commands (s NOTE: If you use the `quit` command, only the remote console exits and the debuggee program continues to run (and you can connect it again). If you want to exit the debuggee program, use `kill` command. -If you want to use TCP/IP for the remote debugging, you need to specify the port and host with `--port` like `rdbg --open --port 12345` and it binds to `localhost:12345`. +If you want to use TCP/IP for the remote debugging, you need to specify the port and host with `--port` like `rdbg --open --port 12345` and it binds to `localhost:12345`. You can add an optional `--port_range` option to try multiple ports in a reliable way. For example, `rdbg --open --port 12345 --port_range 10` will try to bind to 12345, 12346, 12347, ... until it finds an available port. + +```shell To connect to the debuggee, you need to specify the port. diff --git a/test/console/catch_test.rb b/test/console/catch_test.rb index 164ac4288..d4addf997 100644 --- a/test/console/catch_test.rb +++ b/test/console/catch_test.rb @@ -44,29 +44,29 @@ def test_catch_command_isnt_repeatable def test_catch_works_with_command debug_code(program) do - type 'catch ZeroDivisionError pre: p "1234"' + type 'catch ZeroDivisionError pre: p "catching zero division"' assert_line_text(/#0 BP - Catch "ZeroDivisionError"/) type 'continue' - assert_line_text(/1234/) + assert_line_text(/catching zero division/) type 'continue' type 'continue' end debug_code(program) do - type 'catch ZeroDivisionError do: p "1234"' + type 'catch ZeroDivisionError do: p "catching zero division"' assert_line_text(/#0 BP - Catch "ZeroDivisionError"/) type 'continue' - assert_line_text(/1234/) + assert_line_text(/catching zero division/) type 'continue' end end def test_catch_works_with_condition debug_code(program) do - type 'catch ZeroDivisionError if: a == 2 do: p "1234"' + type 'catch ZeroDivisionError if: a == 2 do: p "catching zero division"' assert_line_text(/#0 BP - Catch "ZeroDivisionError"/) type 'continue' - assert_no_line_text(/1234/) + assert_no_line_text(/catching zero division/) type 'continue' end end diff --git a/test/console/irb_test.rb b/test/console/irb_test.rb index 857d02dfd..746f9acdb 100644 --- a/test/console/irb_test.rb +++ b/test/console/irb_test.rb @@ -47,7 +47,7 @@ def test_irb_command_switches_console_to_irb debug_code(program, remote: false) do type 'irb' type '123' - assert_line_text 'irb:rdbg(main):002> 123' + assert_raw_line_text 'irb:rdbg(main):002> 123' type 'irb_info' assert_line_text('IRB version:') type 'next' @@ -67,7 +67,7 @@ def test_irb_console_config_activates_irb debug_code(program, remote: false) do type '123' - assert_line_text 'irb:rdbg(main):002> 123' + assert_raw_line_text 'irb:rdbg(main):002> 123' type 'irb_info' assert_line_text('IRB version:') type 'next' diff --git a/test/console/print_test.rb b/test/console/print_test.rb index 3f9702b76..16f5c4436 100644 --- a/test/console/print_test.rb +++ b/test/console/print_test.rb @@ -15,7 +15,7 @@ def test_p_prints_the_expression debug_code(program) do type "c" type "p h" - assert_line_text('{:foo=>"bar"}') + assert_line_text({ foo: "bar" }.inspect) type "c" end end @@ -24,7 +24,7 @@ def test_pp_pretty_prints_the_expression debug_code(program) do type "c" type "pp h" - assert_line_text([/\{:foo=>/, /"bar"\}/]) + assert_line_text({ foo: "bar" }.pretty_print_inspect) type "c" end end diff --git a/test/support/console_test_case.rb b/test/support/console_test_case.rb index f7e62fb4b..187506e99 100644 --- a/test/support/console_test_case.rb +++ b/test/support/console_test_case.rb @@ -225,7 +225,12 @@ def prepare_test_environment(program, test_steps, &block) @scenario = [] test_steps.call @scenario.freeze - inject_lib_to_load_path + + ENV['RUBYOPT'] = "-I #{__dir__}/../../lib" + + if ENV.key?('BUNDLE_GEMFILE') + ENV["RUBYOPT"] += " -rbundler/setup" + end block.call @@ -283,7 +288,7 @@ def run_rdbg program, options: nil, rubyopt: nil, &test_steps prepare_test_environment(program, test_steps) do test_info = TestInfo.new(dup_scenario, 'LOCAL', /\(rdbg\)/) cmd = "#{RDBG_EXECUTABLE} #{options} -- #{temp_file_path}" - cmd = "RUBYOPT=#{rubyopt} #{cmd}" if rubyopt + ENV["RUBYOPT"] += " #{rubyopt}" if rubyopt run_test_scenario cmd, test_info end end @@ -301,10 +306,6 @@ def new_thread &block end end - def inject_lib_to_load_path - ENV['RUBYOPT'] = "-I #{__dir__}/../../lib" - end - def assert_empty_queue test_info, exception: nil message = "Expected all commands/assertions to be executed. Still have #{test_info.queue.length} left." if exception diff --git a/test/support/test_case.rb b/test/support/test_case.rb index 5ff8a2e27..2d1d26f96 100644 --- a/test/support/test_case.rb +++ b/test/support/test_case.rb @@ -180,6 +180,9 @@ def setup_remote_debuggee(cmd) msg1 = true when /\ADEBUGGER: wait for debugger connection/ msg2 = true + else + # unknown lines + STDERR.puts "> #{line}" end break if msg1 && msg2