[#5563] Non-overridable and non-redefinable methods — Eric Mahurin <eric_mahurin@...>

Lately, I've been thinking about the future of ruby

44 messages 2005/08/19
[#5564] Re: Non-overridable and non-redefinable methods — Austin Ziegler <halostatue@...> 2005/08/19

On 8/19/05, Eric Mahurin <eric_mahurin@yahoo.com> wrote:

[#5571] Re: Non-overridable and non-redefinable methods — Eric Mahurin <eric_mahurin@...> 2005/08/19

--- Austin Ziegler <halostatue@gmail.com> wrote:

[#5574] Re: Non-overridable and non-redefinable methods — TRANS <transfire@...> 2005/08/20

Just wanted to add a few things.

[#5581] Re: Non-overridable and non-redefinable methods — Austin Ziegler <halostatue@...> 2005/08/20

On 8/19/05, TRANS <transfire@gmail.com> wrote:

[#5583] Re: Non-overridable and non-redefinable methods — "David A. Black" <dblack@...> 2005/08/20

Hi --

[#5585] Re: Non-overridable and non-redefinable methods — Eric Mahurin <eric_mahurin@...> 2005/08/20

--- "David A. Black" <dblack@wobblini.net> wrote:

[#5609] Pathname#walk for traversing path nodes (patch) — ES <ruby-ml@...>

Here is a small addition to Pathname against 1.9, probably suited

20 messages 2005/08/22

[PATCH] FW: Ruby 1.8.2 DTrace Support

From: Paul Duncan <pabs@...>
Date: 2005-08-18 19:36:36 UTC
List: ruby-core #5557
Hi everyone,

Richard Lowe (richlowe@richlowe.net) wrote this patch to add a DTrace
provider into Ruby.  He's not subscribed to ruby-core, so he asked me to
forward the patch and his description on to the list.

The patch is attached, and his description is below.  I don't know
anything about DTrace or the patch, so please forward questions or
comments directly to him (discussion can stay here, he can read the
archives like anyone else :D).

Hopefully this is useful to some people.  He showed me the output and it
looked pretty interesting.

----- Forwarded message from Richard Lowe <richlowe@richlowe.net> -----

Date: Thu, 18 Aug 2005 10:59:33 -0400
User-Agent: Mozilla/5.0 (X11; U; SunOS i86pc; en-US; rv:1.7) Gecko/20050704
From: Richard Lowe <richlowe@richlowe.net>
To: pabs@pablotron.org
Subject: DTrace support.

[I'm not subscribed, so please CC me on replies]

I spent the last couple of days hacking a DTrace
(http://www.sun.com/bigadmin/content/dtrace/) provider into ruby.

What I have right now is basically functioning, but I don't have the
understanding of the ruby internals necessary to improve upon it further
or maintain it.  I don't want to leave it to rot on my disk, so if
anybody wants to use it, clean it up, maintain it, integrate it, or
whatever, the patch (against ruby 1.8.2) is attached.

Solaris patch(1) fails to apply it because of the file creation, GNU
patch applies it just fine (removing the 'dtrace.d' hunk from the diff,
and creating that file by hand should let Solaris patch(1) apply it).

I hope it's useful to somebody :)

I've tested it under Solaris Express on x86, 64bit builds of ruby will
need the the -32 argument to dtrace in the Makefile replaced with -64.
(I couldn't find a sensible way to autoconfize that).

It defines two probes, ruby$pid:::function-entry (called before a method
call is entered), and ruby$pid:::function-return (called after a method
call returns). (where $pid is the process ID of a running ruby)

The arguments to each are the classname, methodname, source file name,
and line number.

----- End forwarded message -----

-- 
Paul Duncan <pabs@pablotron.org>        OpenPGP Key ID: 0x82C29562
http://www.pablotron.org/               http://www.paulduncan.org/

Attachments (2)

ruby-1.8.2-dtrace.diff (13.9 KB, text/x-diff)
Index: Makefile.in
===================================================================
--- Makefile.in	(.../clean)	(revision 23)
+++ Makefile.in	(.../diff-tree)	(revision 23)
@@ -103,6 +103,8 @@
 		version.@OBJEXT@ \
 		$(MISSING)
 
+DTRACE_OBJS   = @DTRACE_OBJS@
+
 MANTYPE	      = @MANTYPE@
 
 SCRIPT_ARGS   =	--dest-dir="$(DESTDIR)" \
@@ -124,13 +126,13 @@
 # We must `rm' the library each time this rule is invoked because "updating" a
 # MAB library on Apple/NeXT (see --enable-fat-binary in configure) is not
 # supported.
-$(LIBRUBY_A):	$(OBJS) $(DMYEXT)
+$(LIBRUBY_A):	$(OBJS) $(DMYEXT) $(DTRACE_OBJS)
 		@rm -f $@
-		@AR@ rcu $@ $(OBJS) $(DMYEXT)
+		@AR@ rcu $@ $(DTRACE_OBJS) $(OBJS) $(DMYEXT)
 		@-@RANLIB@ $@ 2> /dev/null || true
 
-$(LIBRUBY_SO):	$(OBJS) $(DLDOBJS) miniruby$(EXEEXT) $(PREP)
-		$(LDSHARED) $(DLDFLAGS) $(OBJS) $(DLDOBJS) $(SOLIBS) -o $@
+$(LIBRUBY_SO):	$(OBJS)  $(DLDOBJS) miniruby$(EXEEXT) $(PREP) $(DTRACE_OBJS)
+		$(LDSHARED) $(DLDFLAGS) $(DTRACE_OBJS) $(OBJS) $(DLDOBJS) $(SOLIBS) -o $@
 		@-$(MINIRUBY) -e 'ARGV.each{|link| File.delete link if File.exist? link; \
 						  File.symlink "$(LIBRUBY_SO)", link}' \
 				$(LIBRUBY_ALIASES) || true
@@ -378,3 +380,6 @@
   missing.h env.h node.h st.h util.h
 version.@OBJEXT@: version.c ruby.h config.h defines.h intern.h missing.h \
   version.h
+
+dtrace.@OBJEXT@: dtrace.d $(OBJS) $(MAINOBJ) 
+	/usr/sbin/dtrace -G -32 -o $@ -s dtrace.d $(OBJS) $(MAINOBJ)
Index: configure.in
===================================================================
--- configure.in	(.../clean)	(revision 23)
+++ configure.in	(.../diff-tree)	(revision 23)
@@ -383,6 +383,12 @@
 		 sys/mkdev.h sys/utime.h netinet/in_systm.h float.h ieeefp.h pthread.h \
 		 ucontext.h intrinsics.h)
 
+
+AC_CHECK_HEADER(sys/sdt.h)
+if test "$ac_cv_header_sys_sdt_h" == "yes"; then
+   AC_DEFINE(HAVE_SDT_H)
+fi
+
 dnl Checks for typedefs, structures, and compiler characteristics.
 AC_TYPE_UID_T
 AC_TYPE_SIZE_T
@@ -415,6 +421,18 @@
     AC_DEFINE(USE_SETREUID)
     AC_DEFINE(USE_SETREGID)
 fi
+
+AC_ARG_ENABLE(dtrace,
+       [  --enable-dtrace       Enable DTrace support.],
+       [enable_dtrace=$enableval])
+if test "$enable_dtrace" == "yes" -a "$ac_cv_header_sys_sdt_h" == "yes"; then
+    AC_DEFINE(ENABLE_DTRACE)
+    DTRACE_OBJS="dtrace.o"
+else
+    DTRACE_OBJS=""
+fi
+AC_SUBST(DTRACE_OBJS)
+
 AC_STRUCT_TIMEZONE
 AC_CACHE_CHECK(for struct tm.tm_gmtoff, rb_cv_member_struct_tm_tm_gmtoff,
   [AC_TRY_COMPILE([#include <time.h>],
Index: configure
===================================================================
--- configure	(.../clean)	(revision 23)
+++ configure	(.../diff-tree)	(revision 23)
@@ -308,7 +308,7 @@
 # include <unistd.h>
 #endif"
 
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS MAJOR MINOR TEENY build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC ac_ct_CC CFLAGS LDFLAGS CPPFLAGS EXEEXT OBJEXT CPP EGREP GNU_LD CPPOUTFILE OUTFLAG YACC RANLIB ac_ct_RANLIB AR ac_ct_AR NM ac_ct_NM WINDRES ac_ct_WINDRES DLLWRAP ac_ct_DLLWRAP LN_S SET_MAKE LIBOBJS ALLOCA DLDFLAGS ARCH_FLAG STATIC CCDLFLAGS LDSHARED DLEXT DLEXT2 LIBEXT LINK_SO LIBPATHFLAG RPATHFLAG TRY_LINK STRIP EXTSTATIC setup MINIRUBY PREP ARCHFILE RDOCTARGET XCFLAGS XLDFLAGS LIBRUBY_LDSHARED LIBRUBY_DLDFLAGS RUBY_INSTALL_NAME rubyw_install_name RUBYW_INSTALL_NAME RUBY_SO_NAME LIBRUBY_A LIBRUBY_SO LIBRUBY_ALIASES LIBRUBY LIBRUBYARG LIBRUBYARG_STATIC LIBRUBYARG_SHARED SOLIBS DLDLIBS ENABLE_SHARED MAINLIBS COMMON_LIBS COMMON_MACROS COMMON_HEADERS EXPORT_PREFIX MAKEFILES arch sitearch sitedir configure_args NROFF MANTYPE LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS MAJOR MINOR TEENY build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC ac_ct_CC CFLAGS LDFLAGS CPPFLAGS EXEEXT OBJEXT CPP EGREP GNU_LD CPPOUTFILE OUTFLAG YACC RANLIB ac_ct_RANLIB AR ac_ct_AR NM ac_ct_NM WINDRES ac_ct_WINDRES DLLWRAP ac_ct_DLLWRAP LN_S SET_MAKE LIBOBJS ALLOCA DTRACE_OBJS DLDFLAGS ARCH_FLAG STATIC CCDLFLAGS LDSHARED DLEXT DLEXT2 LIBEXT LINK_SO LIBPATHFLAG RPATHFLAG TRY_LINK STRIP EXTSTATIC setup MINIRUBY PREP ARCHFILE RDOCTARGET XCFLAGS XLDFLAGS LIBRUBY_LDSHARED LIBRUBY_DLDFLAGS RUBY_INSTALL_NAME rubyw_install_name RUBYW_INSTALL_NAME RUBY_SO_NAME LIBRUBY_A LIBRUBY_SO LIBRUBY_ALIASES LIBRUBY LIBRUBYARG LIBRUBYARG_STATIC LIBRUBYARG_SHARED SOLIBS DLDLIBS ENABLE_SHARED MAINLIBS COMMON_LIBS COMMON_MACROS COMMON_HEADERS EXPORT_PREFIX MAKEFILES arch sitearch sitedir configure_args NROFF MANTYPE LTLIBOBJS'
 ac_subst_files=''
 
 # Initialize some variables set by options.
@@ -863,6 +863,7 @@
   --disable-largefile     omit support for large files
   --enable-pthread        use pthread library.
   --enable-setreuid       use setreuid()/setregid() according to need even if obsolete.
+  --enable-dtrace       Enable DTrace support.
   --disable-rpath         embed run path into extension libraries.
   --enable-shared         build a shared library for Ruby.
   --enable-install-doc    build and install rdoc indexes during install
@@ -10146,6 +10147,152 @@
 done
 
 
+
+if test "${ac_cv_header_sys_sdt_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for sys/sdt.h" >&5
+echo $ECHO_N "checking for sys/sdt.h... $ECHO_C" >&6
+if test "${ac_cv_header_sys_sdt_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_sys_sdt_h" >&5
+echo "${ECHO_T}$ac_cv_header_sys_sdt_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking sys/sdt.h usability" >&5
+echo $ECHO_N "checking sys/sdt.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <sys/sdt.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking sys/sdt.h presence" >&5
+echo $ECHO_N "checking sys/sdt.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/sdt.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: sys/sdt.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: sys/sdt.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/sdt.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: sys/sdt.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: sys/sdt.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: sys/sdt.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/sdt.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: sys/sdt.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/sdt.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: sys/sdt.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/sdt.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: sys/sdt.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/sdt.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: sys/sdt.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: sys/sdt.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: sys/sdt.h: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for sys/sdt.h" >&5
+echo $ECHO_N "checking for sys/sdt.h... $ECHO_C" >&6
+if test "${ac_cv_header_sys_sdt_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_sys_sdt_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_sys_sdt_h" >&5
+echo "${ECHO_T}$ac_cv_header_sys_sdt_h" >&6
+
+fi
+
+
+if test "$ac_cv_header_sys_sdt_h" == "yes"; then
+   cat >>confdefs.h <<\_ACEOF
+#define HAVE_SDT_H 1
+_ACEOF
+
+fi
+
 echo "$as_me:$LINENO: checking for uid_t in sys/types.h" >&5
 echo $ECHO_N "checking for uid_t in sys/types.h... $ECHO_C" >&6
 if test "${ac_cv_type_uid_t+set}" = set; then
@@ -11773,6 +11920,23 @@
 _ACEOF
 
 fi
+
+# Check whether --enable-dtrace or --disable-dtrace was given.
+if test "${enable_dtrace+set}" = set; then
+  enableval="$enable_dtrace"
+  enable_dtrace=$enableval
+fi;
+if test "$enable_dtrace" == "yes" -a "$ac_cv_header_sys_sdt_h" == "yes"; then
+    cat >>confdefs.h <<\_ACEOF
+#define ENABLE_DTRACE 1
+_ACEOF
+
+    DTRACE_OBJS="dtrace.o"
+else
+    DTRACE_OBJS=""
+fi
+
+
 echo "$as_me:$LINENO: checking whether struct tm is in sys/time.h or time.h" >&5
 echo $ECHO_N "checking whether struct tm is in sys/time.h or time.h... $ECHO_C" >&6
 if test "${ac_cv_struct_tm+set}" = set; then
@@ -15810,6 +15974,7 @@
 s,@SET_MAKE@,$SET_MAKE,;t t
 s,@LIBOBJS@,$LIBOBJS,;t t
 s,@ALLOCA@,$ALLOCA,;t t
+s,@DTRACE_OBJS@,$DTRACE_OBJS,;t t
 s,@DLDFLAGS@,$DLDFLAGS,;t t
 s,@ARCH_FLAG@,$ARCH_FLAG,;t t
 s,@STATIC@,$STATIC,;t t
Index: eval.c
===================================================================
--- eval.c	(.../clean)	(revision 23)
+++ eval.c	(.../diff-tree)	(revision 23)
@@ -136,6 +136,10 @@
 
 #include <sys/stat.h>
 
+#ifdef ENABLE_DTRACE
+#include <sys/sdt.h>
+#endif /* ENABLE_DTRACE */
+
 VALUE rb_cProc;
 static VALUE rb_cBinding;
 static VALUE proc_invoke _((VALUE,VALUE,VALUE,VALUE));
@@ -1011,7 +1015,9 @@
 #define YIELD_FUNC_AVALUE 1
 #define YIELD_FUNC_SVALUE 2
 
-static VALUE rb_call _((VALUE,VALUE,ID,int,const VALUE*,int));
+/* DTrace cannot instrument a static function */
+VALUE rb_call _((VALUE,VALUE,ID,int,const VALUE*,int));
+
 static VALUE module_setup _((VALUE,NODE*));
 
 static VALUE massign _((VALUE,NODE*,VALUE,int));
@@ -5689,7 +5695,8 @@
     return result;
 }
 
-static VALUE
+/* DTrace cannot instrument a static function */
+VALUE
 rb_call(klass, recv, mid, argc, argv, scope)
     VALUE klass, recv;
     ID    mid;
@@ -5701,11 +5708,25 @@
     int    noex;
     ID     id = mid;
     struct cache_entry *ent;
+    VALUE  callret;
+    char *classname;
+    char *methodname;
 
     if (!klass) {
 	rb_raise(rb_eNotImpError, "method `%s' called on terminated object (0x%lx)",
 		 rb_id2name(mid), recv);
     }
+
+    classname = rb_class2name(klass);
+    methodname = rb_id2name(mid);
+    
+#ifdef ENABLE_DTRACE
+    /* Don't pass bad pointers into the probe routine */
+    if (classname && methodname && ruby_sourcefile)
+        DTRACE_PROBE4(ruby, function__entry, classname, methodname,
+                      ruby_sourcefile, ruby_sourceline);
+#endif /* ENABLE_DTRACE */
+    
     /* is it in the method cache? */
     ent = cache + EXPR1(klass, mid);
     if (ent->mid == mid && ent->klass == klass) {
@@ -5740,7 +5761,17 @@
 	}
     }
 
-    return rb_call0(klass, recv, mid, id, argc, argv, body, noex & NOEX_NOSUPER);
+
+    callret = rb_call0(klass, recv, mid, id, argc, argv, body, noex & NOEX_NOSUPER);
+
+#ifdef ENABLE_DTRACE
+    /* Don't pass bad pointers into the probe routine */
+    if (classname && methodname && ruby_sourcefile)
+        DTRACE_PROBE4(ruby, function__return, classname, methodname,
+                      ruby_sourcefile, ruby_sourceline);
+#endif /* ENABLE_DTRACE */
+
+    return (callret);
 }
 
 VALUE

signature.asc (189 Bytes, application/pgp-signature)

In This Thread

Prev Next