[前][次][番号順一覧][スレッド一覧]

ruby-changes:25944

From: tenderlove <ko1@a...>
Date: Fri, 30 Nov 2012 02:56:09 +0900 (JST)
Subject: [ruby-changes:25944] tenderlove:r38001 (trunk): * vm.c: add a return hook when a method raises an exception.

tenderlove	2012-11-30 02:55:54 +0900 (Fri, 30 Nov 2012)

  New Revision: 38001

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=38001

  Log:
    * vm.c: add a return hook when a method raises an exception.
    
    * probes_helper.h: look up klass and method if none are provided.
    
    * eval.c: update macro usage.
    
    * vm_eval.c: ditto.
    
    * vm_insnhelper.c: ditto.
    
    * test/dtrace/test_function_entry.rb: test for change.

  Modified files:
    trunk/ChangeLog
    trunk/eval.c
    trunk/probes_helper.h
    trunk/test/dtrace/test_function_entry.rb
    trunk/vm.c
    trunk/vm_eval.c
    trunk/vm_insnhelper.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 38000)
+++ ChangeLog	(revision 38001)
@@ -1,3 +1,17 @@
+Fri Nov 30 02:53:47 2012  Aaron Patterson <aaron@t...>
+
+	* vm.c: add a return hook when a method raises an exception.
+
+	* probes_helper.h: look up klass and method if none are provided.
+
+	* eval.c: update macro usage.
+
+	* vm_eval.c: ditto.
+
+	* vm_insnhelper.c: ditto.
+
+	* test/dtrace/test_function_entry.rb: test for change.
+
 Fri Nov 30 02:27:12 2012  NARUSE, Yui  <naruse@r...>
 
 	* compile.c (compile_array_): refix r37991 remove assertion:
Index: vm_eval.c
===================================================================
--- vm_eval.c	(revision 38000)
+++ vm_eval.c	(revision 38001)
@@ -85,7 +85,7 @@
 	}
     }
     EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, ci->recv, ci->mid, ci->defined_class, val);
-    RUBY_DTRACE_METHOD_RETURN_HOOK(ci->defined_class, ci->mid);
+    RUBY_DTRACE_METHOD_RETURN_HOOK(th, ci->defined_class, ci->mid);
 
     return val;
 }
@@ -123,7 +123,7 @@
 	vm_pop_frame(th);
     }
     EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, recv, mid, defined_class, val);
-    RUBY_DTRACE_METHOD_RETURN_HOOK(defined_class, mid);
+    RUBY_DTRACE_METHOD_RETURN_HOOK(th, defined_class, mid);
 
     return val;
 }
@@ -1036,7 +1036,7 @@
 		    if (UNLIKELY(VM_FRAME_TYPE(th->cfp) == VM_FRAME_MAGIC_CFUNC)) {
 			const rb_method_entry_t *me = th->cfp->me;
 			EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, th->cfp->self, me->called_id, me->klass, Qnil);
-			RUBY_DTRACE_METHOD_RETURN_HOOK(me->klass, me->called_id);
+			RUBY_DTRACE_METHOD_RETURN_HOOK(th, me->klass, me->called_id);
 		    }
 
 		    th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
Index: eval.c
===================================================================
--- eval.c	(revision 38000)
+++ eval.c	(revision 38001)
@@ -18,7 +18,7 @@
 #include "ruby/encoding.h"
 #include "internal.h"
 #include "vm_core.h"
-#include "probes.h"
+#include "probes_helper.h"
 
 #define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
 
Index: probes_helper.h
===================================================================
--- probes_helper.h	(revision 38000)
+++ probes_helper.h	(revision 38001)
@@ -18,11 +18,19 @@
 	} \
     } \
 
-#define RUBY_DTRACE_METHOD_RETURN_HOOK(klass, id) \
+#define RUBY_DTRACE_METHOD_RETURN_HOOK(th, klass, id) \
     if (RUBY_DTRACE_METHOD_RETURN_ENABLED()) { \
-	const char * classname  = rb_class2name((klass)); \
-	const char * methodname = rb_id2name((id)); \
-	const char * filename   = rb_sourcefile(); \
+	VALUE _klass = (klass); \
+	VALUE _id = (id); \
+	const char * classname; \
+	const char * methodname; \
+	const char * filename; \
+	if (!_klass) { \
+	    rb_thread_method_id_and_class((th), &_id, &_klass); \
+	} \
+	classname  = rb_class2name(_klass); \
+	methodname = rb_id2name(_id); \
+	filename   = rb_sourcefile(); \
 	if (classname && methodname && filename) { \
 	    RUBY_DTRACE_METHOD_RETURN( \
 		    classname, \
Index: vm.c
===================================================================
--- vm.c	(revision 38000)
+++ vm.c	(revision 38001)
@@ -1177,7 +1177,7 @@
 	    if (UNLIKELY(VM_FRAME_TYPE(th->cfp) == VM_FRAME_MAGIC_CFUNC)) {
 		const rb_method_entry_t *me = th->cfp->me;
 		EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, th->cfp->self, me->called_id, me->klass, Qnil);
-		RUBY_DTRACE_METHOD_RETURN_HOOK(me->klass, me->called_id);
+		RUBY_DTRACE_METHOD_RETURN_HOOK(th, me->klass, me->called_id);
 	    }
 	    th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
 	}
@@ -1350,6 +1350,7 @@
 
 	    switch (VM_FRAME_TYPE(th->cfp)) {
 	      case VM_FRAME_MAGIC_METHOD:
+		RUBY_DTRACE_METHOD_RETURN_HOOK(th, 0, 0)
 		EXEC_EVENT_HOOK(th, RUBY_EVENT_RETURN, th->cfp->self, 0, 0, Qnil);
 		break;
 	      case VM_FRAME_MAGIC_CLASS:
Index: vm_insnhelper.c
===================================================================
--- vm_insnhelper.c	(revision 38000)
+++ vm_insnhelper.c	(revision 38001)
@@ -1468,7 +1468,7 @@
     vm_pop_frame(th);
 
     EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, recv, me->called_id, me->klass, val);
-    RUBY_DTRACE_METHOD_RETURN_HOOK(me->klass, me->called_id);
+    RUBY_DTRACE_METHOD_RETURN_HOOK(th, me->klass, me->called_id);
 
     return val;
 }
@@ -1526,7 +1526,7 @@
     val = vm_call_cfunc_latter(th, reg_cfp, ci);
 
     EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, recv, me->called_id, me->klass, val);
-    RUBY_DTRACE_METHOD_RETURN_HOOK(me->klass, me->called_id);
+    RUBY_DTRACE_METHOD_RETURN_HOOK(th, me->klass, me->called_id);
 
     return val;
 }
@@ -1584,7 +1584,7 @@
     val = vm_invoke_proc(th, proc, ci->recv, ci->defined_class, ci->argc, argv, ci->blockptr);
 
     EXEC_EVENT_HOOK(th, RUBY_EVENT_RETURN, ci->recv, ci->me->called_id, ci->me->klass, val);
-    RUBY_DTRACE_METHOD_RETURN_HOOK(ci->me->klass, ci->me->called_id);
+    RUBY_DTRACE_METHOD_RETURN_HOOK(th, ci->me->klass, ci->me->called_id);
 
     return val;
 }
Index: test/dtrace/test_function_entry.rb
===================================================================
--- test/dtrace/test_function_entry.rb	(revision 38000)
+++ test/dtrace/test_function_entry.rb	(revision 38001)
@@ -44,6 +44,35 @@
       }
     end
 
+    def test_return_from_raise
+      program = <<-eoruby
+      class Foo
+        def bar; raise; end
+        def baz
+          bar
+        rescue
+        end
+      end
+
+      Foo.new.baz
+      eoruby
+
+      probe = <<-eoprobe
+ruby$target:::method-return
+/arg0 && arg1 && arg2/
+{
+  printf("%s %s %s %d\\n", copyinstr(arg0), copyinstr(arg1), copyinstr(arg2), arg3);
+}
+      eoprobe
+
+      trap_probe(probe, program) { |d_file, rb_file, probes|
+	foo_calls = probes.map { |line| line.split }.find_all { |row|
+	  row.first == 'Foo'  && row[1] == 'bar'
+	}
+        assert foo_calls.any?
+      }
+    end
+
     private
     def ruby_program
       <<-eoruby

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]