From: Cory Banks Date: 2011-11-28T19:23:53+09:00 Subject: [ruby-core:41358] [ruby-trunk - Bug #4409] DRb: discrepency between DRb.here? and DRb.uri leads to failure to dereference a DrbObject Issue #4409 has been updated by Cory Banks. Nicolas, thank you for reporting this issue - http://roofracksforvan.com ---------------------------------------- Bug #4409: DRb: discrepency between DRb.here? and DRb.uri leads to failure to dereference a DrbObject http://redmine.ruby-lang.org/issues/4409 Author: Nicolas Bondoux Status: Closed Priority: Normal Assignee: Masatoshi Seki Category: lib Target version: 1.9.3 ruby -v: ruby 1.9.2p0 (2010-08-18 revision 29036) [i486-linux] =begin When a reference on a local object is sent back by a client to a server, it may not be recognised as a local object during marshalling: An object instance being sent as a reference is wrapped in a DRbObject built by make_proxy with DRbObject.new(obj); the DRbObject's uri will be the uri returned by DRb::uri. When this reference is sent back, DRbObject::_load checks if it matches uri of current server with DRb::here? method. The problem is that DRb.here? checks that a DRbObject uri is the same as the uri which was used by current DRbServer at his creation, while DRb.uri will return an uri created from the local socket from current thread's connection. So, when a DRbObject it sent back, it may not be recognized as referencing a local object Fixing DRb.here? so that it compares with the uri returned by DRb.uri should be enough to quick fix this problem, and seems safe to me. (I call it a quick fix because I am sure that even with this change, it is possible to build some less realistics cases with the same kind of problem, due to the fact that a same reference may be valid or not depending which client sent it back ...) Here is a very simple proof of concept: The server: #!/usr/bin/ruby require 'drb' class A include DRb::DRbUndumped end class TheServer include DRb::DRbUndumped def initialize @a = A.new end def get_a @a end def is_a(iA) puts "inside is_a: current DRb.uri:#{DRb.uri}; iA.class = #{iA.class} #{iA.__drburi if DRb::DRbObject === iA}" @a.eql? iA end def getToken retVal = @@token.clone @@token.inc return retVal end end theServer = TheServer.new DRb.start_service(nil,theServer) puts "DRb.uri just after start_service: #{DRb.uri}" DRb.thread.join ############# The client: #!/usr/bin/ruby require 'drb' theServer = DRb::DRbObject.new(nil,ARGV.shift) a = theServer.get_a puts "a.__drburi == #{a.__drburi}" puts "theServer.is_a(a) == #{theServer.is_a(a)}" ############# the outputs: server side: DRb.uri just after start_service: druby://Venus:60106 inside is_a: current DRb.uri:druby://127.0.0.1:60106; iA.class = DRb::DRbObject druby://127.0.0.1:60106 client side: a.__drburi == druby://127.0.0.1:60106 theServer.is_a(a) == false Cheers, Nicolas =end -- http://redmine.ruby-lang.org