Browse files

Fix JRUBY-6832

self is wrong in set_trace_func when raising NoMethodErrors

The default method_missing implementations still were being
framed, since they used to need that to get the name of the method
being called. However, at some point they just started to use the
name being passed through the call chain, which meant the frame
was unnecessary. The bug was caused by the fact that the binding's
self also comes from the frame, which in method_missing would be
the object against which the missing method was being called. That
caused both "self" and "s" in the bug report to point at the
String in question, since "self" came from m_m's frame and "s"
came from the caller's scopes (m_m did not get its own scope).
Removing the framing from m_m fixed the issue and did not
introduce others (since that frame was not actually being used
anymore).
  • Loading branch information...
1 parent a6d25ca commit 4246d96f63155aeb70694a9a0ace0eeb2c936065 @headius headius committed Aug 21, 2012
Showing with 22 additions and 7 deletions.
  1. +1 −7 src/org/jruby/RubyKernel.java
  2. +21 −0 test/tracing/test_trace_func.rb
View
8 src/org/jruby/RubyKernel.java
@@ -96,12 +96,7 @@ public MethodMissingMethod(RubyModule implementationClass) {
@Override
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args, Block block) {
- try {
- preFrameOnly(context, self, name, block);
- return methodMissing(context, self, clazz, name, args, block);
- } finally {
- postFrameOnly(context);
- }
+ return methodMissing(context, self, clazz, name, args, block);
}
public abstract IRubyObject methodMissing(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args, Block block);
@@ -271,7 +266,6 @@ protected static IRubyObject methodMissingDirect(ThreadContext context, IRubyObj
private static IRubyObject methodMissing(ThreadContext context, IRubyObject recv, String name, Visibility lastVis, CallType lastCallType, IRubyObject[] args, Block block) {
Ruby runtime = context.runtime;
- // TODO: pass this in?
RubySymbol symbol = runtime.newSymbol(name);
// create a lightweight thunk
View
21 test/tracing/test_trace_func.rb
@@ -227,5 +227,26 @@ def test_trace_over_system_call
assert_equal expected, output
end
+ # JRUBY-6832
+ def test_trace_over_nameerror
+ output = nil
+ set_trace_func(proc{ |event, file, line, method, binding, klass|
+ output = binding.eval("[self, s]") if event == "raise"
+ })
+
+ def hello
+ s = "snorkle"
+ s.desnrok
+ end
+
+ begin
+ hello
+ rescue NameError
+ end
+ set_trace_func nil
+
+ assert_equal output, [self, "snorkle"]
+ end
+
end

0 comments on commit 4246d96

Please sign in to comment.