Comma in the file name results in JIT compile error #961

Closed
jbeyer05 opened this Issue Aug 20, 2013 · 8 comments

Projects

None yet

4 participants

@jbeyer05

I'm seeing a very odd error that is present for 1.7.4, 1.7.2 and 1.7.0, but not 1.6.8.
jruby 1.7.4 (1.9.3p392) 2013-05-16 2390d3b on OpenJDK 64-Bit Server VM 1.7.0_09-b30 [linux-amd64]

Based on the exception, which is included below, it's difficult to trace this to a single line of code. jruby seems to be trying to turn the string "0.25" into an integer, but I can't identify any code of mine that is requesting this. It definitely seems to be that this is internal to jruby, and not my code. Again, I have run this code for many days in 1.6.8, and have never had this issue.
It would be very difficult to share the code that creates this issue, but I'm more than happy to try any suggestions you might have to help identify what the issue is with jruby.
It seems that the stack trace is unintelligible due to various optimizations. Is it possible to turn off some of those optimizations so that the stack trace is more meaningful?

Thanks in advance.

Cheers,
Jon

[ 2006-02-21 10:44:15.131 ] ERROR: GenericPairTrading: Exception - For input string: "0.25"
[ 2006-02-21 10:44:15.132 ] ERROR: GenericPairTrading: java.lang.NumberFormatException.forInputString(NumberFormatException.jav
a:65)
java.lang.Integer.parseInt(Integer.java:492)
java.lang.Integer.parseInt(Integer.java:527)
org.jruby.javasupport.util.RuntimeHelpers.createCompiledBlockBody19(RuntimeHelpers.java:241)
org.jruby.ast.executable.RuntimeCache.createBlockBody19(RuntimeCache.java:459)
org.jruby.ast.executable.RuntimeCache.getBlockBody19(RuntimeCache.java:84)
org.jruby.ast.executable.AbstractScript.getBlockBody190(AbstractScript.java:123)
rubyjit.GenericPairTrading$$execution_callback_CF62DCF686AD055F50B900221953DEA265423CAA1978026173.__file__(/mnt/ec2_work/001/TICKER_IWF,0.25,start_date,2006-02-20,STRATEGY_IWF,0.04,SIWF_KINK,2500,end_date,2006-03-30/GenericPairTrading.rb
:196)
rubyjit.GenericPairTrading$$execution_callback_CF62DCF686AD055F50B900221953DEA265423CAA1978026173.__file__(/mnt/ec2_work/001/TICKER_IWF,0.25,start_date,2006-02-20,STRATEGY_IWF,0.04,SIWF_KINK,2500,end_date,2006-03-30/GenericPairTrading.rb)
org.jruby.internal.runtime.methods.JittedMethod.call(JittedMethod.java:141)
org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:134)
org.jruby.ast.FCallNoArgNode.interpret(FCallNoArgNode.java:31)
org.jruby.ast.HashNode.interpret(HashNode.java:96)
org.jruby.ast.ArrayNode.interpretPrimitive(ArrayNode.java:94)
org.jruby.ast.CallManyArgsNode.interpret(CallManyArgsNode.java:57)
org.jruby.ast.DAsgnNode.interpret(DAsgnNode.java:110)
org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
org.jruby.ast.IfNode.interpret(IfNode.java:116)
org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
org.jruby.ast.IfNode.interpret(IfNode.java:116)
org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
org.jruby.evaluator.ASTInterpreter.INTERPRET_BLOCK(ASTInterpreter.java:112)
org.jruby.runtime.Interpreted19Block.evalBlockBody(Interpreted19Block.java:209)
org.jruby.runtime.Interpreted19Block.yield(Interpreted19Block.java:160)
org.jruby.runtime.Block.yield(Block.java:130)
org.jruby.RubyArray.eachCommon(RubyArray.java:1606)
org.jruby.RubyArray.each(RubyArray.java:1613)
org.jruby.RubyArray$INVOKER$i$0$0$each.call(RubyArray$INVOKER$i$0$0$each.gen)
org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:143)
org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:154)
org.jruby.ast.CallNoArgBlockNode.interpret(CallNoArgBlockNode.java:64)
org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
org.jruby.evaluator.ASTInterpreter.INTERPRET_BLOCK(ASTInterpreter.java:112)
org.jruby.runtime.Interpreted19Block.evalBlockBody(Interpreted19Block.java:209)
org.jruby.runtime.Interpreted19Block.yield(Interpreted19Block.java:160)
org.jruby.runtime.Block.yield(Block.java:130)
org.jruby.RubyHash$13.visit(RubyHash.java:1270)
org.jruby.RubyHash.visitAll(RubyHash.java:627)
org.jruby.RubyHash.iteratorVisitAll(RubyHash.java:1221)
org.jruby.RubyHash.each_pairCommon(RubyHash.java:1266)
org.jruby.RubyHash.each_pair(RubyHash.java:1282)
org.jruby.RubyHash$INVOKER$i$0$0$each_pair.call(RubyHash$INVOKER$i$0$0$each_pair.gen)
org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:143)
org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:154)
org.jruby.ast.CallNoArgBlockNode.interpret(CallNoArgBlockNode.java:64)
org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
org.jruby.ast.RescueNode.executeBody(RescueNode.java:224)
org.jruby.ast.RescueNode.interpret(RescueNode.java:119)
org.jruby.ast.BeginNode.interpret(BeginNode.java:83)
org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
org.jruby.ast.WhileNode.interpret(WhileNode.java:131)
org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:75)
org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:139)
org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:172)
org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:306)
org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:136)
$_dot_.TradingStrategy.__file__(./TradingStrategy.rb:431)
$_dot_.TradingStrategy.load(./TradingStrategy.rb)
org.jruby.Ruby.runScript(Ruby.java:810)
org.jruby.Ruby.runScript(Ruby.java:803)
org.jruby.Ruby.runNormally(Ruby.java:674)
org.jruby.Ruby.runFromMain(Ruby.java:523)
org.jruby.Main.doRunFromMain(Main.java:390)
org.jruby.Main.internalRun(Main.java:279)
org.jruby.Main.run(Main.java:221)
org.jruby.Main.main(Main.java:201)
@jbeyer05

If I turn off JIT, everything runs fine.

@headius headius was assigned Aug 20, 2013
@sco11morgan

I see the same error on 1.7.3. If I switch the code listed at the rubyjit from an "each/inject" loop to a "for" loop the JIT error goes away.

@BanzaiMan
Member

Is there a way to reproduce this? It is not clear to me how we are making the decision to parse 0.25 as an Integer.

@jbeyer05

The code that I was running that generated this error was in a very complex
environment, with numerous files and libraries. So I fear that it would be
difficult for me to share reproducible code. If there is a stack trace, or
something similar that I could share to assist in fixing the issue, please
let me know how I could help.

Cheers,
Jon

On Mon, Sep 16, 2013 at 12:45 PM, Hiro Asari notifications@github.comwrote:

Is there a way to reproduce this? It is not clear to me how we are making
the decision to parse 0.25 as an Integer.


Reply to this email directly or view it on GitHubhttps://github.com/jruby/jruby/issues/961#issuecomment-24524972
.

@sco11morgan

I've only seen this error on Jenkins CI as part of a matrix build. In this setup Jenkins adds a comma to the directory it is creating to run the build. We discovered if we take the build out of the matrix (no commas) then the error does not happen.

Steps to reproduce:

  1. create demo.rb
mkdir /tmp/forInputString,foo=bar
cat << EOF >> /tmp/forInputString,foo=bar/demo.rb

class Demo
  def initialize
    ["one", "two", "three"].each do |e|
      puts e
    end
  end
end

Demo.new
EOF
  1. Run
jruby /tmp/forInputString,foo=bar/demo.rb
NumberFormatException.java:48:in `forInputString': java.lang.NumberFormatException: For input string: "foo=bar/demo.rb"
    from Integer.java:449:in `parseInt'
    from Integer.java:499:in `parseInt'
    from RuntimeHelpers.java:282:in `createCompiledBlockBody19'
    from RuntimeCache.java:442:in `createBlockBody19'
    from RuntimeCache.java:85:in `getBlockBody19'
    from AbstractScript.java:111:in `getBlockBody190'
    from /tmp/forInputString,foo=bar/demo.rb:4:in `method__1$RUBY$initialize'
    from tmp$forInputString_2c_foo_equal_bar$demo$method__1$RUBY$initialize:65535:in `call'
    from CachingCallSite.java:302:in `cacheAndCall'
    from CachingCallSite.java:144:in `callBlock'
    from CachingCallSite.java:148:in `call'
    from RubyClass.java:806:in `newInstance'
    from RubyClass$i$newInstance.gen:65535:in `call'
    from JavaMethod.java:249:in `call'
    from CachingCallSite.java:292:in `cacheAndCall'
    from CachingCallSite.java:135:in `call'
    from /tmp/forInputString,foo=bar/demo.rb:10:in `__file__'
    from /tmp/forInputString,foo=bar/demo.rb:-1:in `load'
    from Ruby.java:695:in `runScript'
    from Ruby.java:688:in `runScript'
    from Ruby.java:595:in `runNormally'
    from Ruby.java:444:in `runFromMain'
    from Main.java:321:in `doRunFromMain'
    from Main.java:241:in `internalRun'
    from Main.java:207:in `run'
    from Main.java:191:in `run'
    from Main.java:171:in `main'
@BanzaiMan
Member

Confirmed on master: https://github.com/jruby/jruby/blob/77a0453/core/src/main/java/org/jruby/runtime/Helpers.java#L203

This assumes that the method descriptor does not contain unexpected ,, and we proceed to parse components as Integer or Boolean.

The original report is probably a variation on this theme; somehow ,0.25 ended up in a method descriptor string.

Choosing a different (and less common) delimiter (say \f or \b) lessens the probability of mangling the descriptor (0b9b6e4), but it is not a fundamental solution.

@headius headius closed this in eb14141 Sep 17, 2013
@jbeyer05

Thank you guys! I did indeed have a comma in the path of a file name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment