14032N/Adiff -Nru Python-2.5.1/Include/frameobject.h Python-2.5.1+dtrace/Include/frameobject.h
14032N/A--- Python-2.5.1/Include/frameobject.h 2006-06-11 22:11:18.000000000 -0400
14032N/A+++ Python-2.5.1+dtrace/Include/frameobject.h 2007-09-19 21:22:33.064323000 -0400
14032N/A@@ -41,6 +41,7 @@
14032N/A /* As of 2.3 f_lineno is only valid when tracing is active (i.e. when
14032N/A f_trace is set) -- at other times use PyCode_Addr2Line instead. */
14032N/A int f_lineno; /* Current line number */
14032N/A+ int f_calllineno; /* line number of call site */
14032N/A int f_iblock; /* index in f_blockstack */
14032N/A PyTryBlock f_blockstack[CO_MAXBLOCKS]; /* for try and loop blocks */
14032N/A PyObject *f_localsplus[1]; /* locals+stack, dynamically sized */
14032N/Adiff -Nru Python-2.5.1/Makefile.pre.in Python-2.5.1+dtrace/Makefile.pre.in
14032N/A--- Python-2.5.1/Makefile.pre.in 2006-12-08 15:46:13.000000000 -0500
14032N/A+++ Python-2.5.1+dtrace/Makefile.pre.in 2007-09-19 21:12:36.809125000 -0400
14032N/A@@ -192,6 +192,7 @@
14032N/A GRAMMAR_C= $(srcdir)/Python/graminit.c
14032N/A GRAMMAR_INPUT= $(srcdir)/Grammar/Grammar
14032N/A
14032N/A+DTRACE_OBJS=Python/dtrace.o Python/phelper.o
14032N/A
14032N/A ##########################################################################
14032N/A # Parser
14032N/A@@ -271,6 +272,7 @@
14032N/A Python/getopt.o \
14032N/A Python/pystrtod.o \
14032N/A Python/$(DYNLOADFILE) \
14032N/A+ $(DTRACE_OBJS) \
14032N/A $(MACHDEP_OBJS) \
14032N/A $(THREADOBJ)
14032N/A
14032N/A@@ -499,6 +501,17 @@
14032N/A Objects/unicodectype.o: $(srcdir)/Objects/unicodectype.c \
14032N/A $(srcdir)/Objects/unicodetype_db.h
14032N/A
14032N/A+Python/phelper.o: $(srcdir)/Python/phelper.d
14032N/A+ dtrace -o $@ -DPHELPER $(DFLAGS) $(CPPFLAGS) -C -G -s $(srcdir)/Python/phelper.d
14032N/A+
14032N/A+Python/python.h: $(srcdir)/Python/python.d
14032N/A+ dtrace -o $@ $(DFLAGS) -C -h -s $(srcdir)/Python/python.d
14032N/A+
14032N/A+Python/ceval.o: Python/python.h
14032N/A+
14032N/A+Python/dtrace.o: $(srcdir)/Python/python.d Python/ceval.o
14032N/A+ dtrace -o $@ $(DFLAGS) -C -G -s $(srcdir)/Python/python.d Python/ceval.o
14032N/A+
14032N/A ############################################################################
14032N/A # Header files
14032N/A
14032N/Adiff -Nru Python-2.5.1/Objects/frameobject.c Python-2.5.1+dtrace/Objects/frameobject.c
14032N/A--- Python-2.5.1/Objects/frameobject.c 2007-04-16 02:19:52.000000000 -0400
14032N/A+++ Python-2.5.1+dtrace/Objects/frameobject.c 2007-09-19 22:18:36.084885000 -0400
14032N/A@@ -670,6 +670,7 @@
14032N/A f->f_tstate = tstate;
14032N/A
14032N/A f->f_lasti = -1;
14032N/A+ f->f_calllineno = code->co_firstlineno;
14032N/A f->f_lineno = code->co_firstlineno;
14032N/A f->f_iblock = 0;
14032N/A
14032N/A--- Python-2.5.2/Python/ceval.c.orig 2008-08-27 16:12:16.153435885 +1200
14032N/A+++ Python-2.5.2/Python/ceval.c 2008-08-27 16:16:12.703912419 +1200
14032N/A@@ -19,6 +19,11 @@
14032N/A
14032N/A #include <ctype.h>
14032N/A
14032N/A+#define HAVE_DTRACE
14032N/A+#ifdef HAVE_DTRACE
14032N/A+#include "python.h"
14032N/A+#endif
14032N/A+
14032N/A #ifndef WITH_TSC
14032N/A
14032N/A #define READ_TIMESTAMP(var)
14032N/A@@ -499,6 +504,55 @@
14032N/A NULL);
14032N/A }
14032N/A
14032N/A+#ifdef HAVE_DTRACE
14032N/A+static void
14032N/A+dtrace_entry(PyFrameObject *f)
14032N/A+{
14032N/A+ const char *filename;
14032N/A+ const char *fname;
14032N/A+ int lineno;
14032N/A+
14032N/A+ filename = PyString_AsString(f->f_code->co_filename);
14032N/A+ fname = PyString_AsString(f->f_code->co_name);
14032N/A+ lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);
14032N/A+
14032N/A+ PYTHON_FUNCTION_ENTRY((char *)filename, (char *)fname, lineno);
14032N/A+
14032N/A+ /*
14032N/A+ * Currently a USDT tail-call will not receive the correct arguments.
14032N/A+ * Disable the tail call here.
14032N/A+ */
14032N/A+#if defined(__sparc)
14032N/A+ asm("nop");
14032N/A+#endif
14032N/A+}
14032N/A+
14032N/A+static void
14032N/A+dtrace_return(PyFrameObject *f)
14032N/A+{
14032N/A+ const char *filename;
14032N/A+ const char *fname;
14032N/A+ int lineno;
14032N/A+
14032N/A+ filename = PyString_AsString(f->f_code->co_filename);
14032N/A+ fname = PyString_AsString(f->f_code->co_name);
14032N/A+ lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);
14032N/A+ PYTHON_FUNCTION_RETURN((char *)filename, (char *)fname, lineno);
14032N/A+
14032N/A+ /*
14032N/A+ * Currently a USDT tail-call will not receive the correct arguments.
14032N/A+ * Disable the tail call here.
14032N/A+ */
14032N/A+#if defined(__sparc)
14032N/A+ asm("nop");
14032N/A+#endif
14032N/A+}
14032N/A+#else
14032N/A+#define PYTHON_FUNCTION_ENTRY_ENABLED 0
14032N/A+#define PYTHON_FUNCTION_RETURN_ENABLED 0
14032N/A+#define dtrace_entry()
14032N/A+#define dtrace_return()
14032N/A+#endif
14032N/A
14032N/A /* Interpreter main loop */
14032N/A
14032N/A@@ -509,9 +563,84 @@
14032N/A return PyEval_EvalFrameEx(f, 0);
14032N/A }
14032N/A
14032N/A+/*
14032N/A+ * These shenanigans look like utter madness, but what we're actually doing is
14032N/A+ * making sure that the ustack helper will see the PyFrameObject pointer on the
14032N/A+ * stack. We have two tricky cases:
14032N/A+ *
14032N/A+ * amd64
14032N/A+ *
14032N/A+ * We use up the six registers for passing arguments, meaning the call can't
14032N/A+ * use a register for passing 'f', and has to push it onto the stack in a known
14032N/A+ * location.
14032N/A+ *
14032N/A+ * And how does "throwflag" figure in to this? -PN
14032N/A+ *
14032N/A+ * SPARC
14032N/A+ *
14032N/A+ * Here the problem is that (on 32-bit) the compiler is re-using %i0 before
14032N/A+ * some calls inside PyEval_EvalFrameReal(), which means that when it's saved,
14032N/A+ * it's just some junk value rather than the real first argument. So, instead,
14032N/A+ * we trace our proxy PyEval_EvalFrame(), where we 'know' the compiler won't
14032N/A+ * decide to re-use %i0. We also need to defeat optimization of our proxy.
14032N/A+ */
14032N/A+
14032N/A+#if defined(HAVE_DTRACE)
14032N/A+
14032N/A+#if defined(__amd64)
14032N/A+PyObject *PyEval_EvalFrameExReal(long, long, long, long, long, long,
14032N/A+ PyFrameObject *, int throwflag);
14032N/A+
14032N/A+
14032N/A+
14032N/A+PyObject *
14032N/A+PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
14032N/A+{
14032N/A+ volatile PyObject *f2;
14032N/A+ f2 = PyEval_EvalFrameExReal(0, 0, 0, 0, 0, 0, f, throwflag);
14032N/A+ return (PyObject *)f2;
14032N/A+}
14032N/A+
14032N/A+PyObject *
14032N/A+PyEval_EvalFrameExReal(long a1, long a2, long a3, long a4, long a5, long a6,
14032N/A+ PyFrameObject *f, int throwflag)
14032N/A+{
14032N/A+
14032N/A+#elif defined(__sparc)
14032N/A+
14032N/A+PyObject *PyEval_EvalFrameExReal(PyFrameObject *f, int throwflag);
14032N/A+
14032N/A+volatile int dummy;
14032N/A+
14032N/A+PyObject *
14032N/A+PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
14032N/A+{
14032N/A+ volatile PyObject *f2;
14032N/A+ f2 = PyEval_EvalFrameExReal(f, throwflag);
14032N/A+ dummy = f->ob_refcnt;
14032N/A+ return (PyObject *)f2;
14032N/A+}
14032N/A+
14032N/A+PyObject *
14032N/A+PyEval_EvalFrameExReal(PyFrameObject *f, int throwflag)
14032N/A+{
14032N/A+
14032N/A+#else /* __amd64 || __sparc */
14032N/A+
14032N/A PyObject *
14032N/A PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
14032N/A {
14032N/A+
14032N/A+#endif /* __amd64 || __sparc */
14032N/A+
14032N/A+#else /* don't HAVE_DTRACE */
14032N/A+
14032N/A+PyObject *
14032N/A+PyEval_EvalFrameexEx(PyFrameObject *f, int throwflag))
14032N/A+{
14032N/A+
14032N/A+#endif /* HAVE_DTRACE */
14032N/A+
14032N/A #ifdef DXPAIRS
14032N/A int lastopcode = 0;
14032N/A #endif
14032N/A@@ -729,6 +858,9 @@
14032N/A }
14032N/A }
14032N/A
14032N/A+ if (PYTHON_FUNCTION_ENTRY_ENABLED())
14032N/A+ dtrace_entry(f);
14032N/A+
14032N/A co = f->f_code;
14032N/A names = co->co_names;
14032N/A consts = co->co_consts;
14032N/A@@ -2266,6 +2398,10 @@
14032N/A PyObject **sp;
14032N/A PCALL(PCALL_ALL);
14032N/A sp = stack_pointer;
14032N/A+#ifdef HAVE_DTRACE
14032N/A+ f->f_calllineno = PyCode_Addr2Line(f->f_code,
14032N/A+ f->f_lasti);
14032N/A+#endif
14032N/A #ifdef WITH_TSC
14032N/A x = call_function(&sp, oparg, &intr0, &intr1);
14032N/A #else
14032N/A@@ -2308,6 +2444,11 @@
14032N/A } else
14032N/A Py_INCREF(func);
14032N/A sp = stack_pointer;
14032N/A+#ifdef HAVE_DTRACE
14032N/A+ f->f_calllineno = PyCode_Addr2Line(f->f_code,
14032N/A+ f->f_lasti);
14032N/A+#endif
14032N/A+
14032N/A READ_TIMESTAMP(intr0);
14032N/A x = ext_do_call(func, &sp, flags, na, nk);
14032N/A READ_TIMESTAMP(intr1);
14032N/A@@ -2599,6 +2740,8 @@
14032N/A
14032N/A /* pop frame */
14032N/A exit_eval_frame:
14032N/A+ if (PYTHON_FUNCTION_RETURN_ENABLED())
14032N/A+ dtrace_return(f);
14032N/A Py_LeaveRecursiveCall();
14032N/A tstate->frame = f->f_back;
14032N/A
14032N/Adiff -Nru Python-2.5.1/Python/phelper.d Python-2.5.1+dtrace/Python/phelper.d
14032N/A--- Python-2.5.1/Python/phelper.d 1969-12-31 19:00:00.000000000 -0500
14032N/A+++ Python-2.5.1+dtrace/Python/phelper.d 2007-09-19 21:12:36.874777000 -0400
14141N/A@@ -0,0 +1,139 @@
14032N/A+
14032N/A+/*
14032N/A+ * Python ustack helper. This relies on the first argument (PyFrame *) being
14032N/A+ * on the stack; see Python/ceval.c for the contortions we go through to ensure
14032N/A+ * this is the case.
14032N/A+ *
14032N/A+ * On x86, the PyFrame * is two slots up from the frame pointer; on SPARC, it's
14032N/A+ * eight.
14032N/A+ */
14032N/A+
14032N/A+/*
14032N/A+ * Yes, this is as gross as it looks. DTrace cannot handle static functions,
14032N/A+ * and our stat_impl.h has them in ILP32.
14032N/A+ */
14032N/A+#define _SYS_STAT_H
14032N/A+
14032N/A+#include <stdio.h>
14032N/A+#include <sys/types.h>
14032N/A+
14032N/A+#include "pyport.h"
14032N/A+#include "object.h"
14032N/A+#include "pystate.h"
14032N/A+#include "pyarena.h"
14032N/A+#include "pythonrun.h"
14032N/A+#include "compile.h"
14032N/A+#include "frameobject.h"
14032N/A+#include "stringobject.h"
14032N/A+
14032N/A+#if defined(__i386)
14032N/A+#define startframe PyEval_EvalFrameEx
14032N/A+#define endframe PyEval_EvalCodeEx
14032N/A+#elif defined(__amd64)
14032N/A+#define PyEval_EvalFrameEx PyEval_EvalFrameExReal
14032N/A+#define startframe PyEval_EvalFrameExReal
14032N/A+#define endframe PyEval_EvalCodeEx
14032N/A+#elif defined(__sparc)
14141N/A+#define PyEval_EvalFrameEx PyEval_EvalFrameExReal
14032N/A+#define startframe PyEval_EvalFrameEx
14032N/A+#define endframe PyEval_EvalFrameExReal
14032N/A+#endif
14032N/A+
14032N/A+#ifdef __sparcv9
14032N/A+#define STACK_BIAS (2048-1)
14032N/A+#else
14032N/A+#define STACK_BIAS 0
14032N/A+#endif
14032N/A+
14032N/A+/*
14032N/A+ * Not defining PHELPER lets us test this code as a normal D script.
14032N/A+ */
14032N/A+#ifdef PHELPER
14032N/A+
14032N/A+#define at_evalframe(addr) \
14032N/A+ ((uintptr_t)addr >= ((uintptr_t)&``startframe) && \
14032N/A+ (uintptr_t)addr < ((uintptr_t)&``endframe))
14032N/A+#define probe dtrace:helper:ustack:
14032N/A+#define print_result(r) (r)
14032N/A+
14032N/A+#if defined(__i386) || defined(__amd64)
14032N/A+#define frame_ptr_addr ((uintptr_t)arg1 + sizeof(uintptr_t) * 2)
14032N/A+#elif defined(__sparc)
14032N/A+#define frame_ptr_addr ((uintptr_t)arg1 + STACK_BIAS + sizeof(uintptr_t) * 8)
14032N/A+#else
14032N/A+#error unknown architecture
14032N/A+#endif
14032N/A+
14032N/A+#else /* PHELPER */
14032N/A+
14032N/A+#define at_evalframe(addr) (1)
14032N/A+#define probe pid$target::PyEval_EvalFrame:entry
14032N/A+#define print_result(r) (trace(r))
14032N/A+
14032N/A+#if defined(__i386) || defined(__amd64)
14032N/A+#define frame_ptr_addr ((uintptr_t)uregs[R_SP] + sizeof(uintptr_t))
14032N/A+#elif defined(__sparc)
14032N/A+/*
14032N/A+ * Not implemented: we could just use R_I0, but what's the point?
14032N/A+ */
14032N/A+#else
14032N/A+#error unknown architecture
14032N/A+#endif
14032N/A+
14032N/A+#endif /* PHELPER */
14032N/A+
14032N/A+extern uintptr_t PyEval_EvalFrameEx;
14032N/A+extern uintptr_t PyEval_EvalCodeEx;
14032N/A+
14032N/A+#define copyin_obj(addr, obj) ((obj *)copyin((uintptr_t)addr, sizeof(obj)))
14032N/A+#define pystr_addr(addr) ((char *)addr + offsetof(PyStringObject, ob_sval))
14032N/A+#define copyin_str(dest, addr, obj) \
14032N/A+ (copyinto((uintptr_t)pystr_addr(addr), obj->ob_size, (dest)))
14032N/A+#define add_str(addr, obj) \
14032N/A+ copyin_str(this->result + this->pos, addr, obj); \
14032N/A+ this->pos += obj->ob_size; \
14032N/A+ this->result[this->pos] = '\0';
14032N/A+#define add_digit(nr, div) ((nr / div) ? \
14032N/A+ (this->result[this->pos++] = '0' + ((nr / div) % 10)) : \
14032N/A+ (this->result[this->pos] = '\0'))
14032N/A+#define add_char(c) (this->result[this->pos++] = c)
14032N/A+
14032N/A+probe /at_evalframe(arg0)/
14032N/A+{
14032N/A+ this->framep = *(uintptr_t *)copyin(frame_ptr_addr, sizeof(uintptr_t));
14032N/A+ this->frameo = copyin_obj(this->framep, PyFrameObject);
14032N/A+ this->codep = this->frameo->f_code;
14032N/A+ this->lineno = this->frameo->f_calllineno;
14032N/A+ this->codeo = copyin_obj(this->codep, PyCodeObject);
14032N/A+ this->filenamep = this->codeo->co_filename;
14032N/A+ this->fnamep = this->codeo->co_name;
14032N/A+ this->filenameo = copyin_obj(this->filenamep, PyStringObject);
14032N/A+ this->fnameo = copyin_obj(this->fnamep, PyStringObject);
14032N/A+
14032N/A+ this->len = 1 + this->filenameo->ob_size + 1 + 5 + 2 +
14032N/A+ this->fnameo->ob_size + 1 + 1;
14032N/A+
14032N/A+ this->result = (char *)alloca(this->len);
14032N/A+ this->pos = 0;
14032N/A+
14032N/A+ add_char('@');
14032N/A+ add_str(this->filenamep, this->filenameo);
14032N/A+ add_char(':');
14032N/A+ add_digit(this->lineno, 10000);
14032N/A+ add_digit(this->lineno, 1000);
14032N/A+ add_digit(this->lineno, 100);
14032N/A+ add_digit(this->lineno, 10);
14032N/A+ add_digit(this->lineno, 1);
14032N/A+ add_char(' ');
14032N/A+ add_char('(');
14032N/A+ add_str(this->fnamep, this->fnameo);
14032N/A+ add_char(')');
14032N/A+ this->result[this->pos] = '\0';
14032N/A+
14032N/A+ print_result(stringof(this->result));
14032N/A+}
14032N/A+
14032N/A+probe /!at_evalframe(arg0)/
14032N/A+{
14032N/A+ NULL;
14032N/A+}
14032N/Adiff -Nru Python-2.5.1/Python/python.d Python-2.5.1+dtrace/Python/python.d
14032N/A--- Python-2.5.1/Python/python.d 1969-12-31 19:00:00.000000000 -0500
14032N/A+++ Python-2.5.1+dtrace/Python/python.d 2007-09-19 21:12:36.874963000 -0400
14032N/A@@ -0,0 +1,10 @@
14032N/A+provider python {
14032N/A+ probe function__entry(const char *, const char *, int);
14032N/A+ probe function__return(const char *, const char *, int);
14032N/A+};
14032N/A+
14032N/A+#pragma D attributes Evolving/Evolving/Common provider python provider
14032N/A+#pragma D attributes Private/Private/Common provider python module
14032N/A+#pragma D attributes Private/Private/Common provider python function
14032N/A+#pragma D attributes Evolving/Evolving/Common provider python name
14032N/A+#pragma D attributes Evolving/Evolving/Common provider python args