Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unable to get value of object's fields in RubyMine debugger #2301

Closed
os97673 opened this issue Dec 10, 2014 · 31 comments
Closed

unable to get value of object's fields in RubyMine debugger #2301

os97673 opened this issue Dec 10, 2014 · 31 comments

Comments

@os97673
Copy link

os97673 commented Dec 10, 2014

Originally filed agains RubyMine (https://youtrack.jetbrains.com/issue/RUBY-15864)
Users basically unable to see value of object's fields.
Here is a simple example which shows how we (ruby-debug-base) try to get value of fields.
It looks like a bug for me, but if it is not please suggest a way to implement similar functionality for jruby.

class Foo
  attr_accessor :test
end

foo = Foo.new
foo.test = 'visible?'
puts foo.test

bindings = ["binding()", "Kernel::binding()", "Object.send(:binding)"].map {|b| foo.instance_eval(b)}
bindings.each do |b|
  puts "--#{eval("@test", b).nil?}--"
end
@os97673
Copy link
Author

os97673 commented Dec 10, 2014

@headius it would be nice to get your thoughts about the problem

@headius
Copy link
Member

headius commented Dec 10, 2014

Has this ever worked in JRuby? Why aren't you using instance_variable_get?

I suppose it could be a bug, but this is an incredibly weird way to get instance variables out of an object.

@os97673
Copy link
Author

os97673 commented Dec 11, 2014

Honestly, I do not know I've not seen this working, but I only tested with modern jruby while the code was written long time ago. If you know a better way to get field's value from an object I'm ok to change ruby-debug-base.

@headius
Copy link
Member

headius commented Dec 15, 2014

You should be able to use instance_variables and instance_variable_get on most objects (perhaps not BasicObject) to introspect instance variables. I'm guessing the eval form is done to avoid cases where those methods are unavailable or redefined (e.g. a blank slate object).

I think there's still a bug here, though, since it seems like at least one of these eval forms should have been able to see the @test variable.

@headius
Copy link
Member

headius commented Dec 15, 2014

Ok, a slightly reduced case that should work, but it shows that when we create a binding inside instance_eval it does not get the proper "self".

class Foo
  attr_accessor :test
end

foo = Foo.new
foo.test = 'visible?'
puts foo.test

p eval("self", foo.instance_eval("binding")) # => "main"
p eval("@test", foo.instance_eval("binding")) # => "nil"

@headius
Copy link
Member

headius commented Dec 15, 2014

This is also wrong on master, @enebo @subbuss.

@headius
Copy link
Member

headius commented Dec 15, 2014

I have a likely fix that basically just uses the instance_eval "self" as the frame "self" when pushing a frame in preExecuteUnder. It's a little scary to change, though.

@enebo
Copy link
Member

enebo commented Dec 15, 2014

Incidentally I am also posing removing that method altogether on master :) We are pushing 2 scopes in IR one from preExecuteUnder and one by IR interpreter...

@headius
Copy link
Member

headius commented Dec 15, 2014

@enebo that sounds fine too. I'm going to push my change to a test branch and see how Travis test runs handle it before doing something similar for release branches.

headius added a commit that referenced this issue Dec 15, 2014
This is a bit of a scary change, so pushing to a test branch for
now.
@headius
Copy link
Member

headius commented Dec 15, 2014

Pushed my change to branch "test-instance_eval-self-fix-2301" and the travis run is here: https://travis-ci.org/jruby/jruby/builds/44131805. If it passes, this may be an ok fix for both branches, but I will also defer to @enebo since he's working on eval right now on master.

@enebo enebo closed this as completed in b5b7305 Dec 17, 2014
@enebo enebo added this to the JRuby 1.7.18 milestone Dec 22, 2014
@ninkibah
Copy link

I got very excited about this this morning, and upgraded jruby-1.7.17 to jruby-1.7.18.

Sadly, it only fixes part of the problem. Class variables are shown properly, but instance variables are not. :-( I'll raise it again with the rubymine folks.

@headius: Thanks for all your efforts, and have a good Christmas.

@mount986
Copy link

mount986 commented Jan 2, 2015

@ninkibah: Can you please post a link to the follow-up issue if you raised one? I've been tracking this issue since #1758 and would like to know when it is fully up and working again. Thanks.

@ninkibah
Copy link

ninkibah commented Jan 2, 2015

@mount986 I have added a comment here: https://youtrack.jetbrains.com/issue/RUBY-15864

I don't know if the current fix is enough for @os97673 and his colleagues to be able to fix the RubyMine debugger.

@os97673
Copy link
Author

os97673 commented Jan 3, 2015

@ninkibah @mount986 I'm not sure the problem has been fixed, at least both my test and the test provided by @headius still don't work :(
@headius @enebo what the changes you've committed were supposed to change?

@os97673
Copy link
Author

os97673 commented Jan 15, 2015

@headius @enebo what the changes you've committed were supposed to change?

Guys, could you please answer the question. It looks like I've misunderstood your comments in the issue and I'm not sure what behavior to expect now and should I change something in ruby-debug-ide or not.

@headius headius reopened this Jan 26, 2015
@headius
Copy link
Member

headius commented Jan 26, 2015

Fix applied in b5b7305 does not appear to have been enough. Can you show the current failing test case? I'm not sure what we don't do at this point.

@os97673
Copy link
Author

os97673 commented Jan 27, 2015

@headius both the test you provided and my original tests still work the same way as before :(
Is it what you want or I need test in some special format?

@os97673
Copy link
Author

os97673 commented Apr 4, 2015

Any chance to get the problem fixed?

@headius
Copy link
Member

headius commented Apr 6, 2015

I think we have this working correctly in JRuby 9k, but 1.7.x still has the wrong output.

@headius headius closed this as completed in 7774be5 Apr 6, 2015
@headius
Copy link
Member

headius commented Apr 6, 2015

Hopefully it is now fixed to everyone's satisfaction. @os97673 Please try out a head or snapshot build with the latest fix and let us know if it's working properly.

@headius headius modified the milestones: JRuby 1.7.20, JRuby 1.7.18 Apr 6, 2015
@ninkibah
Copy link

ninkibah commented Apr 6, 2015

I'm trying out jruby-head, but from the install output, this branch is the new 9.0.0.0 branch. Is there a branch for the planned 1.7.20? The reason I ask is that when I use the 9.0.0.0.pre1 branch, I get errors in my tests, probably due to some difference in the postgresql adapter. It objects to doing inserts specifying nil values for columns with default values. This seems to work fine in 1.7.19, but not in 9.0.0.0.pre1.

I'll see if I can track down the cause a bit more. For now, I'm trying out jruby-head for the current bug.

@donv
Copy link
Member

donv commented Apr 7, 2015

Hi @ninkibah !

The branch for the upcoming 1.7.20 release is "jruby-1_7".

@os97673
Copy link
Author

os97673 commented Apr 7, 2015

@headius the original problem is fixed.
Unfortunately now ruby-debug-ide doesn't work correctly due to the following exception.
Please let me know if you need more information.

org.jruby.runtime.DynamicScope.getNextCapturedScope()Lorg/jruby/runtime/DynamicScope;
    org.jruby.debug.Context.contextCopyLocals(Context.java:448)
    org.jruby.debug.Context.frame_locals(Context.java:303)
    org.jruby.debug.Context$INVOKER$i$1$0$frame_locals_DBG.call(Context$INVOKER$i$1$0$frame_locals_DBG.gen)
    org.jruby.internal.runtime.methods.JavaMethod$JavaMethodOneOrNBlock.call(JavaMethod.java:364)
    org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:313)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:163)
    org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:288)
    org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:74)
    org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:77)
    org.jruby.internal.runtime.methods.InterpretedIRMethod.INTERPRET_METHOD(InterpretedIRMethod.java:152)
    org.jruby.internal.runtime.methods.InterpretedIRMethod.call(InterpretedIRMethod.java:139)
    org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:198)
    org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:293)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:131)
    org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:304)
    org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:74)
    org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:137)
    org.jruby.runtime.InterpretedIRBlockBody.commonYieldPath(InterpretedIRBlockBody.java:109)
    org.jruby.runtime.IRBlockBody.doYield(IRBlockBody.java:145)
    org.jruby.runtime.BlockBody.yield(BlockBody.java:82)
    org.jruby.runtime.Block.yield(Block.java:147)
    org.jruby.RubyArray.each(RubyArray.java:1570)
    org.jruby.RubyArray$INVOKER$i$0$0$each_DBG.call(RubyArray$INVOKER$i$0$0$each_DBG.gen)
    org.jruby.internal.runtime.methods.JavaMethod$JavaMethodZeroBlock.call(JavaMethod.java:472)
    org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:77)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:83)
    org.jruby.ir.instructions.CallBase.interpret(CallBase.java:416)
    org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:320)
    org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:74)
    org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:137)
    org.jruby.runtime.InterpretedIRBlockBody.commonYieldPath(InterpretedIRBlockBody.java:109)
    org.jruby.runtime.IRBlockBody.doYield(IRBlockBody.java:145)
    org.jruby.runtime.BlockBody.yield(BlockBody.java:82)
    org.jruby.runtime.Block.yield(Block.java:147)
    org.jruby.RubyContinuation.enter(RubyContinuation.java:107)
    org.jruby.RubyKernel.rbCatch19Common(RubyKernel.java:1132)
    org.jruby.RubyKernel.rbCatch19(RubyKernel.java:1125)
    org.jruby.RubyKernel$INVOKER$s$rbCatch19_DBG.call(RubyKernel$INVOKER$s$rbCatch19_DBG.gen)
    org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:171)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:177)
    org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:297)
    org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:74)
    org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:77)
    org.jruby.internal.runtime.methods.InterpretedIRMethod.INTERPRET_METHOD(InterpretedIRMethod.java:152)
    org.jruby.internal.runtime.methods.InterpretedIRMethod.call(InterpretedIRMethod.java:139)
    org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:198)
    org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:293)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:131)
    org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:304)
    org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:74)
    org.jruby.internal.runtime.methods.InterpretedIRMethod.INTERPRET_METHOD(InterpretedIRMethod.java:123)
    org.jruby.internal.runtime.methods.InterpretedIRMethod.call(InterpretedIRMethod.java:110)
    org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:273)
    org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:79)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:83)
    org.jruby.ir.instructions.CallBase.interpret(CallBase.java:416)
    org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:320)
    org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:74)
    org.jruby.internal.runtime.methods.InterpretedIRMethod.INTERPRET_METHOD(InterpretedIRMethod.java:123)
    org.jruby.internal.runtime.methods.InterpretedIRMethod.call(InterpretedIRMethod.java:110)
    org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:273)
    org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:79)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:83)
    org.jruby.ir.instructions.CallBase.interpret(CallBase.java:416)
    org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:320)
    org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:74)
    org.jruby.internal.runtime.methods.InterpretedIRMethod.INTERPRET_METHOD(InterpretedIRMethod.java:123)
    org.jruby.internal.runtime.methods.InterpretedIRMethod.call(InterpretedIRMethod.java:110)
    org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:180)
    org.jruby.RubyClass.finvoke(RubyClass.java:716)
    org.jruby.runtime.Helpers.invoke(Helpers.java:604)
    org.jruby.RubyBasicObject.callMethod(RubyBasicObject.java:381)
    org.jruby.debug.DebugEventHook.callAtLine(DebugEventHook.java:585)
    org.jruby.debug.DebugEventHook.callAtLine(DebugEventHook.java:571)
    org.jruby.debug.DebugEventHook.processEvent(DebugEventHook.java:199)
    org.jruby.debug.DebugEventHook.eventHandler(DebugEventHook.java:97)
    org.jruby.runtime.EventHook.event(EventHook.java:30)
    org.jruby.Ruby.callEventHooks(Ruby.java:3131)
    org.jruby.runtime.ThreadContext.trace(ThreadContext.java:627)
    org.jruby.ir.interpreter.InterpreterEngine.processBookKeepingOp(InterpreterEngine.java:367)
    org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:92)
    org.jruby.ir.interpreter.Interpreter.INTERPRET_ROOT(Interpreter.java:117)
    org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:104)
    org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:33)
    org.jruby.ir.IRTranslator.execute(IRTranslator.java:42)
    org.jruby.Ruby.runInterpreter(Ruby.java:855)
    org.jruby.Ruby.loadFile(Ruby.java:2911)
    org.jruby.runtime.load.LibrarySearcher$ResourceLibrary.loadScript(LibrarySearcher.java:260)
    org.jruby.runtime.load.LibrarySearcher$ResourceLibrary.load(LibrarySearcher.java:248)
    org.jruby.runtime.load.LibrarySearcher$FoundLibrary.load(LibrarySearcher.java:34)
    org.jruby.runtime.load.LoadService.load(LoadService.java:327)
    org.jruby.debug.Debugger.load(Debugger.java:145)
    org.jruby.debug.RubyDebugger.debug_load(RubyDebugger.java:204)
    org.jruby.debug.RubyDebugger$INVOKER$s$0$2$debug_load_DBG.call(RubyDebugger$INVOKER$s$0$2$debug_load_DBG.gen)
    org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:273)
    org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:79)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:83)
    org.jruby.ir.instructions.CallBase.interpret(CallBase.java:416)
    org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:320)
    org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:74)
    org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:83)
    org.jruby.internal.runtime.methods.InterpretedIRMethod.INTERPRET_METHOD(InterpretedIRMethod.java:180)
    org.jruby.internal.runtime.methods.InterpretedIRMethod.call(InterpretedIRMethod.java:167)
    org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:206)
    org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:313)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:163)
    org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:288)
    org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:74)
    org.jruby.ir.interpreter.Interpreter.INTERPRET_ROOT(Interpreter.java:117)
    org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:104)
    org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:33)
    org.jruby.ir.IRTranslator.execute(IRTranslator.java:42)
    org.jruby.Ruby.runInterpreter(Ruby.java:855)
    org.jruby.Ruby.loadFile(Ruby.java:2911)
    org.jruby.runtime.load.LibrarySearcher$ResourceLibrary.loadScript(LibrarySearcher.java:260)
    org.jruby.runtime.load.LibrarySearcher$ResourceLibrary.load(LibrarySearcher.java:248)
    org.jruby.runtime.load.LibrarySearcher$FoundLibrary.load(LibrarySearcher.java:34)
    org.jruby.runtime.load.LoadService.load(LoadService.java:327)
    org.jruby.RubyKernel.loadCommon(RubyKernel.java:992)
    org.jruby.RubyKernel.load19(RubyKernel.java:984)
    org.jruby.RubyKernel$INVOKER$s$0$1$load19_DBG.call(RubyKernel$INVOKER$s$0$1$load19_DBG.gen)
    org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:210)
    org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:206)
    org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:313)
    org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:163)
    org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:288)
    org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:74)
    org.jruby.ir.interpreter.Interpreter.INTERPRET_ROOT(Interpreter.java:117)
    org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:104)
    org.jruby.ir.interpreter.Interpreter.execute(Interpreter.java:33)
    org.jruby.ir.IRTranslator.execute(IRTranslator.java:42)
    org.jruby.Ruby.runInterpreter(Ruby.java:873)
    org.jruby.Ruby.runInterpreter(Ruby.java:881)
    org.jruby.Ruby.runNormally(Ruby.java:756)
    org.jruby.Ruby.runFromMain(Ruby.java:573)
    org.jruby.Main.doRunFromMain(Main.java:404)
    org.jruby.Main.internalRun(Main.java:299)
    org.jruby.Main.run(Main.java:226)
    org.jruby.Main.main(Main.java:198)

@donv donv reopened this Apr 7, 2015
@enebo
Copy link
Member

enebo commented Apr 10, 2015

Re-added DynamicScope.getNextCapturedScope to not break ruby-debug-ide on master to address unrelated error @os97673 reported. jruby-1_7 still reports wrong output so I am leaving this issue open since it is fixed on master but not on jruby-1_7.

@headius
Copy link
Member

headius commented Apr 30, 2015

@ninkibah Sorry to hear you had issues with your app on 9k.pre1. If you still have those issues on pre2 we REALLY want to know about them.

@os97673 I think this should be working correctly now in 1.7.20 and @enebo's fix for master should be in 9k.pre2. Can you please confirm things are working with 9k.pre2 and a head build of jruby-1_7 branch?

@headius
Copy link
Member

headius commented Apr 30, 2015

Optimistically closing this because the spec passes and the 9k fix was cherry-picked over to 1.7.

@headius headius closed this as completed Apr 30, 2015
@ninkibah
Copy link

@headius I might try out 9k pre2 this weekend, as we have a bank holiday on Monday! When is 1.7.20 coming out?

@os97673
Copy link
Author

os97673 commented May 2, 2015

@os97673 I think this should be working correctly now in 1.7.20 and @enebo's fix for master should be in 9k.pre2. Can you please confirm things are working with 9k.pre2 and a head build of jruby-1_7 branch?

I've tried 9k.pre2 and everything works ok there.
I will try to build jruby-1_7 but it make take a time since I've never done it before.

@os97673
Copy link
Author

os97673 commented May 2, 2015

tried jruby-1_7 and the test works correctly.

@headius
Copy link
Member

headius commented May 5, 2015

@os97673 Thanks for the confirmation :-)

@cprice404
Copy link
Contributor

@headius just FYI; this patch turned out to be a pretty huge improvement in memory usage for us :) Prior to the patch the objects that were referenced by the Frame.self field included a lot of unnecessary scope, and thus if we had other code that held references to those, it meant that there was a huge amount of memory that could not be GC'd. With this patch the retained size for each one of the objects we created via a call to instance_eval went down from 7MB to less than 1kb. :)

Granted this probably has more to do with what our code is doing with these evals than what JRuby is, but thought you might be interested in that data point.

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

No branches or pull requests

7 participants