Marshal dump format error and inconsistencies with MRI
------------------------------------------------------

                 Key: JRUBY-5123
                 URL: http://jira.codehaus.org/browse/JRUBY-5123
             Project: JRuby
          Issue Type: Bug
          Components: Ruby 1.8.7, Standard Library
         Environment: jruby 1.5.3 (ruby 1.8.7 patchlevel 249) (2010-09-28 
7ca06d7) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_20) [x86_64-java]

            Reporter: Loren Segal


There seems to be some different behaviour between JRuby and MRI when 
unmarshalling user-marshalled objects. The following is an IRB session across 
Ruby 1.8.7, 1.9.2, MacRuby 0.7 and JRuby 1.5.3 in unmarshalling some dumped 
objects which include user-marshalled objects. This marshal dumped data is used 
in YARD's test suite to test loading of Registries, it can be found at 
http://github.com/lsegal/yard/tree/master/spec/serializers/data/serialized_yardoc/objects/Foo.dat

    yard (master)$ ruby-switch-8
    yard (master)$ ruby -v
    ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin10.0.0]
    yard (master)$ irb
    >> require 'lib/yard'; 
Marshal.load(File.read_binary('spec/serializers/data/serialized_yardoc/objects/Foo.dat'))
    Calling CodeObject("").root?()
    => #<yardoc class Foo>
    >> exit

    yard (master)$ ruby-switch-92
    yard (master)$ ruby -v
    ruby 1.9.2p0 (2010-08-18) [x86_64-darwin10.4.0]
    yard (master)$ irb
    >> require 'lib/yard'; 
Marshal.load(File.read_binary('spec/serializers/data/serialized_yardoc/objects/Foo.dat'))
    Calling CodeObject("").root?()
    => #<yardoc class Foo>
    >> exit

    yard (master)$ ruby-switch-mac 
    yard (master)$ ruby -v
    MacRuby 0.7 (ruby 1.9.2) [universal-darwin10.0, x86_64]
    yard (master)$ irb
    >> require 'lib/yard'; 
Marshal.load(File.read_binary('spec/serializers/data/serialized_yardoc/objects/Foo.dat'))
    Calling CodeObject("").class()
    Calling CodeObject("").root?()
    => #<yardoc class Foo>
    >> exit

    yard (master)$ ruby-switch-jruby 
    yard (master)$ ruby -v
    jruby 1.5.3 (ruby 1.8.7 patchlevel 249) (2010-09-28 7ca06d7) (Java 
HotSpot(TM) 64-Bit Server VM 1.6.0_20) [x86_64-java]
    yard (master)$ irb
    >> require 'lib/yard'; 
Marshal.load(File.read_binary('spec/serializers/data/serialized_yardoc/objects/Foo.dat'))
    Calling CodeObject("Foo#baz").respond_to?(":to_str")
    TypeError: #<YARD::StubProxy:0x2c42a818 @object=nil, @transient=false, 
@path="Foo#baz"> is not a string
        from (irb):1:in `load'
        from (irb):1

This Marshal.load error turns into a "dump format error" when other objects are 
unmarshalled:

    >> YARD::Registry.load!('spec/serializers/data/serialized_yardoc')
    ArgumentError: dump format error()
        from 
/Users/jinx/Development/Ruby/yard/lib/yard/serializers/yardoc_serializer.rb:72:in
 `load'
        from 
/Users/jinx/Development/Ruby/yard/lib/yard/serializers/yardoc_serializer.rb:72:in
 `deserialize'
        from 
/Users/jinx/Development/Ruby/yard/lib/yard/registry_store.rb:220:in `load_root'
        from 
/Users/jinx/Development/Ruby/yard/lib/yard/registry_store.rb:190:in 
`load_yardoc'
        from /Users/jinx/Development/Ruby/yard/lib/yard/registry_store.rb:90:in 
`load'
        from 
/Users/jinx/Development/Ruby/yard/lib/yard/registry_store.rb:101:in `load!'
        from /Users/jinx/Development/Ruby/yard/lib/yard/registry.rb:116:in 
`load!'
        from (irb):2
    >> 

The "Calling <...>" debugging statement was captured from method_missing inside 
of the object that was being unmarshalled during a self._load() call. The 
following is the user-marshalled class:

    class StubProxy
      instance_methods.each {|m| undef_method(m) unless m.to_s =~ 
/^__|^object_id$/ }

      def _dump(depth) @path end
      def self._load(str) new(str) end
      def hash; @path.hash end
    
      def initialize(path, transient = false) 
        @path = path
        @transient = transient
      end
    
      def method_missing(meth, *args, &block)
        return true if meth == :respond_to? && args.first == :_dump
        puts "Calling 
CodeObject(#[email protected]}).#{meth}(#{args.map{|x|x.inspect}.inspect[1...-1]})"
        @object = nil if @transient
        @object ||= Registry.at(@path)
        @object.send(meth, *args, &block)
      rescue NoMethodError => e
        e.backtrace.delete_if {|l| l[0, __FILE__.size] == __FILE__ }
        raise
      end
    end

The source (minus the debugging statement) can be found at 
http://github.com/lsegal/yard/blob/master/lib/yard/serializers/yardoc_serializer.rb

Unfortunately, I was unable to create a minimal test case for this issue, it 
seems to have something to do with the way YARD does things coupled with a 
difference in the way JRuby does things. I can however confirm that if the 
user-marshalled objects are taken out of the equation, the data is loaded just 
fine, so I'm pretty sure it's related to user-marshalled objects. Again, I 
should reiterate that most other Ruby implementations (even MacRuby) seem able 
to handle loading/unloading of the dump file, so there is something wonky going 
on with JRuby, even if YARD might be "helping". 

Hopefully someone can help narrow this issue down-- as it stands, YARD is 
unable to load the data it caches to disk between parsing, which is affecting 
its ability to function properly. I'd be glad to answer any other questions and 
help find the problem, but I spent (at least) a few hours with this and I'm at 
a loss as to what it could be. I'd really like to see it fixed.

Regards,

Loren

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: 
http://jira.codehaus.org/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply via email to