Thanks to visit codestin.com
Credit goes to github.com

Skip to content

OutOfMemoryError while constructing a NameError in the context of a large object #8384

@mrckzgl

Description

@mrckzgl

Causing a NameError within the scope of a large Object results in an OutOfMemoryError instead of the NameError, hiding the actual user space code location of the NameError and potentially crashing the process.

Environment Information

  • jruby 9.4.8.0 (3.1.4) 2024-07-02 4d41e55 OpenJDK 64-Bit Server VM 17.0.12+7-Ubuntu-1ubuntu222.04 on 17.0.12+7-Ubuntu-1ubuntu222.04 +jit [x86_64-linux]
  • Linux 6.8.0-47-generic #47~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Wed Oct 2 16:16:55 UTC 2 x86_64 x86_64 x86_64 GNU/Linux

Expected Behavior

The NameError should be shown.

Actual Behavior

All the memory of the process gets filled while collecting an inspect string of the large object. If not enough memory is available, an OutOfMemoryError is shown, hiding the actual NameError location.

Minimal Example

class Test
  def initialize()
    @obj = {}
    for t in 1..800000 do
      @obj[t.to_s] = Random.rand(10000000).to_s
    end
  end
  def error
    nameerror
  end
end

puts("generating large obj")
test = Test.new
puts("done")
test.error

Running with jruby -w -J-Xmx250M test2.rb results in:

generating large obj
done
Error: Your application used more memory than the safety cap of 250M.
Specify -J-Xmx####M to increase it (#### = cap size in MB).
java.lang.OutOfMemoryError: Java heap space
	at org.jruby.dist/org.jruby.util.ByteList.ensure(ByteList.java:362)
	at org.jruby.dist/org.jruby.util.io.EncodingUtils.strBufCat(EncodingUtils.java:1883)
	at org.jruby.dist/org.jruby.util.io.EncodingUtils.strBufCat(EncodingUtils.java:1868)
	at org.jruby.dist/org.jruby.util.io.EncodingUtils.encCrStrBufCat(EncodingUtils.java:1991)
	at org.jruby.dist/org.jruby.util.io.EncodingUtils.encStrBufCat(EncodingUtils.java:1894)
	at org.jruby.dist/org.jruby.RubyBasicObject.inspectObj(RubyBasicObject.java:1145)
	at org.jruby.dist/org.jruby.RubyBasicObject.hashyInspect(RubyBasicObject.java:1088)
	at org.jruby.dist/org.jruby.RubyBasicObject.inspect(RubyBasicObject.java:1072)
	at org.jruby.dist/org.jruby.RubyKernel.inspect(RubyKernel.java:2362)
	at org.jruby.dist/org.jruby.RubyKernel$INVOKER$s$0$0$inspect.call(RubyKernel$INVOKER$s$0$0$inspect.gen)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:456)
	at org.jruby.dist/org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:195)
	at org.jruby.dist/org.jruby.RubyBasicObject.rbInspect(RubyBasicObject.java:1097)
	at org.jruby.dist/org.jruby.RubyObject.inspect(RubyObject.java:452)
	at org.jruby.dist/org.jruby.RubyNameError$RubyNameErrorMessage.to_str(RubyNameError.java:129)
	at org.jruby.dist/org.jruby.RubyNameError$RubyNameErrorMessage$INVOKER$i$0$0$to_str.call(RubyNameError$RubyNameErrorMessage$INVOKER$i$0$0$to_str.gen)
	at org.jruby.dist/org.jruby.RubyClass.checkFuncallDefault(RubyClass.java:685)
	at org.jruby.dist/org.jruby.RubyClass.finvokeChecked(RubyClass.java:629)
	at org.jruby.dist/org.jruby.runtime.Helpers.invokeChecked(Helpers.java:757)
	at org.jruby.dist/org.jruby.RubyBasicObject.checkCallMethod(RubyBasicObject.java:341)
	at org.jruby.dist/org.jruby.util.TypeConverter.convertToType(TypeConverter.java:97)
	at org.jruby.dist/org.jruby.util.TypeConverter.convertToType(TypeConverter.java:128)
	at org.jruby.dist/org.jruby.RubyBasicObject.convertToString(RubyBasicObject.java:722)
	at org.jruby.dist/org.jruby.RubyNameError.to_s(RubyNameError.java:264)
	at org.jruby.dist/org.jruby.RubyNameError$INVOKER$i$0$0$to_s.call(RubyNameError$INVOKER$i$0$0$to_s.gen)
	at org.jruby.dist/org.jruby.internal.runtime.methods.JavaMethod$JavaMethodN.call(JavaMethod.java:841)
	at org.jruby.dist/org.jruby.ir.runtime.IRRuntimeHelpers.unresolvedSuper(IRRuntimeHelpers.java:1488)
	at org.jruby.dist/org.jruby.ir.instructions.UnresolvedSuperInstr.interpret(UnresolvedSuperInstr.java:123)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:363)
	at org.jruby.dist/org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:66)
	at org.jruby.dist/org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:76)
	at org.jruby.dist/org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:164)

This will be fixed regularly in JRuby 10 (ruby 3.3), this issue is for a potential fix in JRuby 9.4 with compatibility to ruby 3.1.
See also #216

best

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions