diff -up Python-3.2b2/configure.in.systemtap Python-3.2b2/configure.in --- Python-3.2b2/configure.in.systemtap 2010-12-13 02:59:39.000000000 -0500 +++ Python-3.2b2/configure.in 2010-12-28 17:01:58.044059433 -0500 @@ -2470,6 +2470,38 @@ if test "$with_valgrind" != no; then OPT="-DDYNAMIC_ANNOTATIONS_ENABLED=1 $OPT" fi +# Check for dtrace support +AC_MSG_CHECKING(for --with-dtrace) +AC_ARG_WITH(dtrace, + AC_HELP_STRING(--with(out)-dtrace, disable/enable dtrace support)) + +if test ! -z "$with_dtrace" +then + if dtrace -G -o /dev/null -s $srcdir/Include/pydtrace.d 2>/dev/null + then + AC_DEFINE(WITH_DTRACE, 1, + [Define if you want to compile in Dtrace support]) + with_dtrace="Sun" + DTRACEOBJS="Python/dtrace.o" + DTRADEHDRS="" + elif dtrace -h -o /dev/null -s $srcdir/Include/pydtrace.d + then + AC_DEFINE(WITH_DTRACE, 1, + [Define if you want to compile in Dtrace support]) + with_dtrace="Apple" + DTRACEOBJS="" + DTRADEHDRS="pydtrace.h" + else + with_dtrace="no" + fi +else + with_dtrace="no" +fi + +AC_MSG_RESULT($with_dtrace) +AC_SUBST(DTRACEOBJS) +AC_SUBST(DTRACEHDRS) + # -I${DLINCLDIR} is added to the compile rule for importdl.o AC_SUBST(DLINCLDIR) DLINCLDIR=. diff -up Python-3.2b2/Include/pydtrace.d.systemtap Python-3.2b2/Include/pydtrace.d --- Python-3.2b2/Include/pydtrace.d.systemtap 2010-12-28 16:58:41.762936379 -0500 +++ Python-3.2b2/Include/pydtrace.d 2010-12-28 16:58:41.762936379 -0500 @@ -0,0 +1,10 @@ +provider python { + probe function__entry(const char *, const char *, int); + probe function__return(const char *, const char *, int); +}; + +#pragma D attributes Evolving/Evolving/Common provider python provider +#pragma D attributes Private/Private/Common provider python module +#pragma D attributes Private/Private/Common provider python function +#pragma D attributes Evolving/Evolving/Common provider python name +#pragma D attributes Evolving/Evolving/Common provider python args diff -up Python-3.2b2/Makefile.pre.in.systemtap Python-3.2b2/Makefile.pre.in --- Python-3.2b2/Makefile.pre.in.systemtap 2010-12-28 16:58:41.000000000 -0500 +++ Python-3.2b2/Makefile.pre.in 2010-12-28 17:00:58.607310089 -0500 @@ -328,6 +328,7 @@ PYTHON_OBJS= \ Python/formatter_unicode.o \ Python/fileutils.o \ Python/$(DYNLOADFILE) \ + @DTRACEOBJS@ \ $(LIBOBJS) \ $(MACHDEP_OBJS) \ $(THREADOBJ) @@ -632,6 +633,18 @@ Objects/typeobject.o: $(srcdir)/Objects/ $(srcdir)/Objects/typeslots.inc: $(srcdir)/Include/typeslots.h $(srcdir)/Objects/typeslots.py $(PYTHON) $(srcdir)/Objects/typeslots.py < $(srcdir)/Include/typeslots.h > $(srcdir)/Objects/typeslots.inc +# Only needed with --with-dtrace +buildinclude: + mkdir -p Include + +Include/pydtrace.h: buildinclude $(srcdir)/Include/pydtrace.d + dtrace -o $@ $(DFLAGS) -C -h -s $(srcdir)/Include/pydtrace.d + +Python/ceval.o: Include/pydtrace.h + +Python/dtrace.o: buildinclude $(srcdir)/Include/pydtrace.d Python/ceval.o + dtrace -o $@ $(DFLAGS) -C -G -s $(srcdir)/Include/pydtrace.d Python/ceval.o + ############################################################################ # Header files @@ -1282,7 +1295,7 @@ Python/thread.o: @THREADHEADERS@ .PHONY: frameworkinstall frameworkinstallframework frameworkinstallstructure .PHONY: frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools .PHONY: frameworkaltinstallunixtools recheck autoconf clean clobber distclean -.PHONY: smelly funny patchcheck +.PHONY: smelly funny patchcheck buildinclude .PHONY: gdbhooks # IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff -up Python-3.2b2/pyconfig.h.in.systemtap Python-3.2b2/pyconfig.h.in --- Python-3.2b2/pyconfig.h.in.systemtap 2010-11-20 05:29:12.000000000 -0500 +++ Python-3.2b2/pyconfig.h.in 2010-12-28 16:58:41.765937360 -0500 @@ -1092,6 +1092,9 @@ /* Define if you want documentation strings in extension modules */ #undef WITH_DOC_STRINGS +/* Define if you want to compile in Dtrace support */ +#undef WITH_DTRACE + /* Define if you want to use the new-style (Openstep, Rhapsody, MacOS) dynamic linker (dyld) instead of the old-style (NextStep) dynamic linker (rld). Dyld is necessary to support frameworks. */ diff -up Python-3.2b2/Python/ceval.c.systemtap Python-3.2b2/Python/ceval.c --- Python-3.2b2/Python/ceval.c.systemtap 2010-12-03 15:14:31.000000000 -0500 +++ Python-3.2b2/Python/ceval.c 2010-12-28 16:58:41.768935588 -0500 @@ -18,6 +18,10 @@ #include +#ifdef WITH_DTRACE +#include "pydtrace.h" +#endif + #ifndef WITH_TSC #define READ_TIMESTAMP(var) @@ -766,6 +770,70 @@ PyEval_EvalCode(PyObject *co, PyObject * } +#ifdef WITH_DTRACE +struct frame_marker_info +{ + char *filename; + char *name; + int lineno; + + PyObject *utf8_filename; + PyObject *utf8_name; +}; + +static void +get_frame_marker_info(PyFrameObject *f, struct frame_marker_info *fmi) +{ + fmi->utf8_filename = PyUnicode_AsUTF8String(f->f_code->co_filename); + if (fmi->utf8_filename) { + fmi->filename = PyBytes_AsString(fmi->utf8_filename); + } else { + fmi->filename = NULL; + /* FIXME: clear the exception? */ + } + + fmi->utf8_name = PyUnicode_AsUTF8String(f->f_code->co_name); + if (fmi->utf8_name) { + fmi->name = PyBytes_AsString(fmi->utf8_name); + } else { + fmi->name = NULL; + /* FIXME: clear the exception? */ + } + + fmi->lineno = PyCode_Addr2Line(f->f_code, f->f_lasti); +} + +static void +release_frame_marker_info(struct frame_marker_info *fmi) +{ + Py_XDECREF(fmi->utf8_filename); + Py_XDECREF(fmi->utf8_name); +} + +static void +dtrace_entry(PyFrameObject *f) +{ + struct frame_marker_info fmi; + get_frame_marker_info(f, &fmi); + PYTHON_FUNCTION_ENTRY(fmi.filename, fmi.name, fmi.lineno); + release_frame_marker_info(&fmi); +} + +static void +dtrace_return(PyFrameObject *f) +{ + struct frame_marker_info fmi; + get_frame_marker_info(f, &fmi); + PYTHON_FUNCTION_RETURN(fmi.filename, fmi.name, fmi.lineno); + release_frame_marker_info(&fmi); +} +#else +#define PYTHON_FUNCTION_ENTRY_ENABLED() 0 +#define PYTHON_FUNCTION_RETURN_ENABLED() 0 +#define dtrace_entry(f) +#define dtrace_return(f) +#endif + /* Interpreter main loop */ PyObject * @@ -1183,6 +1251,10 @@ PyEval_EvalFrameEx(PyFrameObject *f, int } } + if (PYTHON_FUNCTION_ENTRY_ENABLED()) { + dtrace_entry(f); + } + co = f->f_code; names = co->co_names; consts = co->co_consts; @@ -3048,6 +3120,9 @@ fast_yield: /* pop frame */ exit_eval_frame: + if (PYTHON_FUNCTION_RETURN_ENABLED()) { + dtrace_return(f); + } Py_LeaveRecursiveCall(); tstate->frame = f->f_back;