diff options
Diffstat (limited to 'lib/irb/cmd/debug.rb')
| -rw-r--r-- | lib/irb/cmd/debug.rb | 112 |
1 files changed, 0 insertions, 112 deletions
diff --git a/lib/irb/cmd/debug.rb b/lib/irb/cmd/debug.rb deleted file mode 100644 index 2c09c99cf0..0000000000 --- a/lib/irb/cmd/debug.rb +++ /dev/null @@ -1,112 +0,0 @@ -require_relative "nop" - -module IRB - # :stopdoc: - - module ExtendCommand - class Debug < Nop - BINDING_IRB_FRAME_REGEXPS = [ - '<internal:prelude>', - binding.method(:irb).source_location.first, - ].map { |file| /\A#{Regexp.escape(file)}:\d+:in `irb'\z/ } - IRB_DIR = File.expand_path('..', __dir__) - - def execute(pre_cmds: nil, do_cmds: nil) - unless binding_irb? - puts "`debug` command is only available when IRB is started with binding.irb" - return - end - - unless setup_debugger - puts <<~MSG - You need to install the debug gem before using this command. - If you use `bundle exec`, please add `gem "debug"` into your Gemfile. - MSG - return - end - - options = { oneshot: true, hook_call: false } - if pre_cmds || do_cmds - options[:command] = ['irb', pre_cmds, do_cmds] - end - if DEBUGGER__::LineBreakpoint.instance_method(:initialize).parameters.include?([:key, :skip_src]) - options[:skip_src] = true - end - - # To make debugger commands like `next` or `continue` work without asking - # the user to quit IRB after that, we need to exit IRB first and then hit - # a TracePoint on #debug_break. - file, lineno = IRB::Irb.instance_method(:debug_break).source_location - DEBUGGER__::SESSION.add_line_breakpoint(file, lineno + 1, **options) - # exit current Irb#run call - throw :IRB_EXIT - end - - private - - def binding_irb? - caller.any? do |frame| - BINDING_IRB_FRAME_REGEXPS.any? do |regexp| - frame.match?(regexp) - end - end - end - - def setup_debugger - unless defined?(DEBUGGER__::SESSION) - begin - require "debug/session" - rescue LoadError # debug.gem is not written in Gemfile - return false unless load_bundled_debug_gem - end - DEBUGGER__.start(nonstop: true) - end - - unless DEBUGGER__.respond_to?(:capture_frames_without_irb) - DEBUGGER__.singleton_class.send(:alias_method, :capture_frames_without_irb, :capture_frames) - - def DEBUGGER__.capture_frames(*args) - frames = capture_frames_without_irb(*args) - frames.reject! do |frame| - frame.realpath&.start_with?(IRB_DIR) || frame.path == "<internal:prelude>" - end - frames - end - end - - true - end - - # This is used when debug.gem is not written in Gemfile. Even if it's not - # installed by `bundle install`, debug.gem is installed by default because - # it's a bundled gem. This method tries to activate and load that. - def load_bundled_debug_gem - # Discover latest debug.gem under GEM_PATH - debug_gem = Gem.paths.path.flat_map { |path| Dir.glob("#{path}/gems/debug-*") }.select do |path| - File.basename(path).match?(/\Adebug-\d+\.\d+\.\d+(\w+)?\z/) - end.sort_by do |path| - Gem::Version.new(File.basename(path).delete_prefix('debug-')) - end.last - return false unless debug_gem - - # Discover debug/debug.so under extensions for Ruby 3.2+ - debug_so = Gem.paths.path.flat_map do |path| - Dir.glob("#{path}/extensions/**/#{File.basename(debug_gem)}/debug/debug.so") - end.first - - # Attempt to forcibly load the bundled gem - if debug_so - $LOAD_PATH << debug_so.delete_suffix('/debug/debug.so') - end - $LOAD_PATH << "#{debug_gem}/lib" - begin - require "debug/session" - puts "Loaded #{File.basename(debug_gem)}" - true - rescue LoadError - false - end - end - end - end -end |
