Skip to content

Loading debug gem breaks blankslate gem #757

Description

@jvilk-stripe

Your environment

  • ruby -v: ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux]
  • rdbg -v: rdbg 1.6.2

Describe the bug

The debug gem undefines and redefines singleton_method_added.

The blankslate gem provides a "abstract base class with no predefined methods" except for some core Ruby builtins. "BlankSlate is useful as a base class when writing classes that depend upon method_missing (e.g. dynamic proxies)", so it only works if singleton_method_added is available. However, it hides singleton_method_added because it's redefined by the debug gem.

This problem does not occur when the debug gem is not required.

To Reproduce

require 'debug'
require 'blankslate'

BlankSlate.new.singleton_method_added

Buggy output -- the method isn't defined:

Traceback (most recent call last):
repro.rb:4:in `<main>': undefined method `singleton_method_added' for #<BlankSlate:0x000055a654b12fb0> (NoMethodError)

Expected behavior

The method is defined, but private:

Traceback (most recent call last):
repro.rb:3:in `<main>': private method `singleton_method_added' called for #<BlankSlate:0x000055d758dcd540> (NoMethodError)

Workaround

We can work around the bug by explicilty unhiding this method, or by requiring blankslate before debug:

BlankSlate.reveal(:singleton_method_added)

Additional context

The problem is caused by this code in the debug gem:

debug/lib/debug/session.rb

Lines 1686 to 1689 in 19b4dde

class ::BasicObject
undef singleton_method_added
def singleton_method_added mid; end
end

Why does the debug gem redefine this method?

Activity

  1. changed the title [-]Loading `debug` gem breaks `BlankSlate`[/-] [+]Loading `debug` gem breaks `blankslate` gem[/+] on Sep 21, 2022
  2. jvilk-stripe commented on Sep 21, 2022

    @jvilk-stripe
    Author

    This problem breaks one of Stripe's services in development because we start a debug session when it starts up, before it requires the blankslate gem. We are working around the issue, but it would be great if it could be fixed!

  3. ko1 commented on Oct 4, 2022

    @ko1
    Collaborator

    Thank you for the report.
    I didn't know the blankslate but could you make a smaller repro-code without the blankslate gem?
    Otherwise I'll try to make it.

  4. dentarg commented on Apr 4, 2023

    @dentarg

    minitest also breaks, see minitest/minitest#929

  5. zenspider commented on Nov 10, 2023

    @zenspider
    Member

    Here is blankslate torn all the way down to a minimal repro:

    #!/usr/bin/env ruby -vw
    
    class BlankSlate
      def self.hide(name)
        return unless instance_methods.include? name
        undef_method name
      end
    
      hide :singleton_method_added
    end
    
    begin
      BlankSlate.new.singleton_method_added
    rescue NoMethodError => e
      p e.message.include?("private method") ? :GOOD : :BAD
    else
      p :BAD
    end
    
    __END__
    % ruby -rdebug debug_blankslate.rb
    :BAD
    % ruby debug_blankslate.rb
    :GOOD

    run w/o ruby -rdebug to output GOOD and run with ruby -rdebug to output BAD...

    It essentially boils down to "is singleton_method_added defined?"

    for minitest/mock, not too dissimilar:

    #!/usr/bin/env ruby -vw
    
    class Mock
      overridden_methods = %w[
        ===
        class
        inspect
        instance_eval
        instance_variables
        object_id
        public_send
        respond_to_missing?
        send
        to_s
      ]
    
      instance_methods.each do |m|
        undef_method m unless overridden_methods.include?(m.to_s) || m =~ /^__/
      end
    
      def method_missing sym, *args, **kwargs, &block # :nodoc:
        raise NoMethodError, "unmocked method %p" % [sym]
      end
    end
    
    foo = Mock.new
    def foo.bar = 'very awesome foo'
    
    p :GOOD
  6. zenspider commented on Nov 10, 2023

    @zenspider
    Member

    I think in my case I'm going to add singleton_method_added to overridden_methods if DEBUGGER__ is defined.

  7. added
    bugSomething isn't working
    on Dec 28, 2023
  8. added this to the v1.9.2 milestone on Dec 28, 2023
  9. modified the milestones: v1.9.2, v1.9.3 on Mar 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions