diff -r f0955d95ac02 -r d12ded643482 .hgignore
--- a/.hgignore Mon Jul 02 13:54:33 2012 -0700
+++ b/.hgignore Tue Jul 03 03:43:34 2012 +0200
@@ -88,3 +88,6 @@
.coverage
coverage/
htmlcov/
+Include/pydtrace.h
+Include/pydtrace_offsets
+Include/pydtrace_offsets.h
diff -r f0955d95ac02 -r d12ded643482 Doc/library/debug.rst
--- a/Doc/library/debug.rst Mon Jul 02 13:54:33 2012 -0700
+++ b/Doc/library/debug.rst Tue Jul 03 03:43:34 2012 +0200
@@ -15,3 +15,4 @@
profile.rst
timeit.rst
trace.rst
+ dtrace.rst
diff -r f0955d95ac02 -r d12ded643482 Doc/library/dtrace.rst
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Doc/library/dtrace.rst Tue Jul 03 03:43:34 2012 +0200
@@ -0,0 +1,183 @@
+:mod:`dtrace` --- DTrace probes for Python
+===============================================
+
+.. module:: dtrace
+ :synopsis: DTrace probes for Python.
+
+**Source code:** :source:`Lib/dtrace.py`
+
+--------------
+
+The :mod:`dtrace` module indicates if the CPython executable currently
+running has been compiled with DTrace probes support.
+
+.. impl-detail::
+
+ DTrace probes are implementation details of the CPython interpreter!
+ No garantees are made about probe compatibility between versions of
+ CPython. DTrace scripts can stop working or work incorrectly without
+ warning when changing CPython versions.
+
+The :mod:`dtrace` module defines the following variable:
+
+
+.. data:: available
+
+ The variable will be ``True`` if the current CPython interpreter was
+ compiled with DTrace probe support. ``False`` if not.
+
+
+DTrace probes
+-------------
+
+DTrace scripts are run externally to CPython. DTrace probes export
+selected events inside CPython interpreter in order to make them
+accessible to external scripts.
+
+The probes are exported through the "python" provider. The available
+probes are defined in the file :file:`Include/pydtrace.d`.
+
+To learn how to use DTrace, read `DTrace User Guide
+`_.
+
+.. opcode:: function-entry (arg0, arg1, arg2)
+
+ Fires when python code enters a new function. *arg0* is sourcecode
+ file path, *arg1* is the name of the funcion called, and *arg2* is
+ line number.
+
+ The probe is not fired if Python code calls C functions.
+
+.. opcode:: function-return (arg0, arg1, arg2)
+
+ Fires when Python code finishes execution of a function. Parameters
+ are the same as in ``function-entry``.
+
+ The probe is not fired if the finishing function is written in C.
+
+.. opcode:: line (arg0, arg1, arg2)
+
+ Fires when Python code changes the execution line. Parameters are the
+ same as in ``function-entry``.
+
+ The probe is not fired in C functions.
+
+.. opcode:: gc-start (arg0)
+
+ Fires when the Python interpreter starts a garbage collection cycle.
+ *arg0* is the generation to scan, like :func:`gc.collect()`.
+
+.. opcode:: gc-done (arg0)
+
+ Fires when the Python interpreter finishes a garbage collection
+ cycle. *arg0* is the number of collected objects.
+
+.. opcode:: instance-new-start (arg0, arg1)
+
+ Fires when an object instanciation starts. *arg0* is the class name,
+ *arg1* is the filename where the class is defined.
+
+ The probe is not fired for most C code object creations.
+
+.. opcode:: instance-new-done (arg0, arg1)
+
+ Fires when an object instanciation finishes. Parameters are the same
+ as in ``instance-new-done``.
+
+ The probe is not fired for most C code object creations.
+
+.. opcode:: instance-delete-start (arg0, arg1)
+
+ Fires when an object instance is going to be destroyed. Parameters
+ are the same as in ``instance-new-done``.
+
+ The probe is not fired for most C code object destructions.
+
+.. opcode:: instance-delete-done (arg0, arg1)
+
+ Fires when an object instance has been destroyed. parameters are the
+ same as in ``instance-new-done``.
+
+ Between an ``instance-delete-start`` and corresponding
+ ``instance-delete-done`` others probes can fire if, for instance,
+ deletion of an instance creates a deletion cascade.
+
+ The probe is not fired for most C code object destructions.
+
+
+Python stack
+------------
+
+When a DTrace probe is fired, the DTrace script can examine the stack.
+Since CPython is a Python interpreter coded in C, the stack will show C
+functions, with no direct relation to the Python code currently being
+executed.
+
+Using the special "jstack()" DTrace function, the user will be given
+hints about the python program stack, if possible. In particular, the
+augmented stack will show python function calls, filename, name
+of the function or method, and the line number.
+
+DTrace scripts examples
+-----------------------
+
+DTrace python provider is suffixed by the pid of the process to monitor.
+In the examples, the pid will be 9876.
+
+Show the time spent doing garbage collection (in nanoseconds)::
+
+ python9876:::gc-start
+ {
+ self->t = timestamp;
+ }
+
+ python9876:::gc-done
+ /self->t/
+ {
+ printf("%d", timestamp-self->t);
+ self->t = 0;
+ }
+
+Count how many instances are created of each class::
+
+ python9876:::instance-new-start
+ {
+ @v[copyinstr(arg1), copyinstr(arg0)] = count();
+ }
+
+Observe time spent in object destruction, useful if datastructures are
+complicated and deletion of an object can create a cascade effect::
+
+ python9876:::instance-delete-start
+ /self->t==0/
+ {
+ self->t = timestamp;
+ self->level = 0;
+ }
+
+ python9876:::instance-delete-start
+ /self->t/
+ {
+ self->level += 1;
+ }
+
+ python9876:::instance-delete-done
+ /(self->level) && (self->t)/
+ {
+ self->level -= 1;
+ }
+
+ python9876:::instance-delete-done
+ /(self->level==0) && (self->t)/
+ {
+ @time = quantize(timestamp-self->t);
+ self->t = 0;
+ }
+
+To know which python source code lines create new TCP/IP connections::
+
+ pid9876::sock_connect:entry
+ {
+ @conn[jstack()] = count();
+ }
+
diff -r f0955d95ac02 -r d12ded643482 Include/code.h
--- a/Include/code.h Mon Jul 02 13:54:33 2012 -0700
+++ b/Include/code.h Tue Jul 03 03:43:34 2012 +0200
@@ -7,6 +7,8 @@
extern "C" {
#endif
+#include "pyconfig.h"
+
/* Bytecode object */
typedef struct {
PyObject_HEAD
@@ -28,6 +30,9 @@
int co_firstlineno; /* first source line number */
PyObject *co_lnotab; /* string (encoding addr<->lineno mapping) See
Objects/lnotab_notes.txt for details. */
+#ifdef WITH_DTRACE
+ unsigned short *co_linenos; /* dtrace stack helper */
+#endif
void *co_zombieframe; /* for optimization only (see frameobject.c) */
PyObject *co_weakreflist; /* to support weakrefs to code objects */
} PyCodeObject;
diff -r f0955d95ac02 -r d12ded643482 Include/pydtrace.d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Include/pydtrace.d Tue Jul 03 03:43:34 2012 +0200
@@ -0,0 +1,177 @@
+provider python {
+ probe function__entry(const char *, const char *, int);
+ probe function__return(const char *, const char *, int);
+ probe instance__new__start(const char *, const char *);
+ probe instance__new__done(const char *, const char *);
+ probe instance__delete__start(const char *, const char *);
+ probe instance__delete__done(const char *, const char *);
+ probe line(const char *, const char *, int);
+ probe gc__start(int);
+ probe gc__done(long);
+};
+
+#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
+
+
+
+#ifdef PYDTRACE_STACK_HELPER
+/*
+ * Python ustack helper. This relies on the first argument (PyFrame *) being
+ * on the stack; see Python/ceval.c for the contortions we go through to ensure
+ * this is the case.
+ *
+ * On x86, the PyFrame * is two slots up from the frame pointer; on SPARC, it's
+ * eight.
+ *
+ * Some details about this in "Python and DTrace in build 65":
+ * http://blogs.oracle.com/levon/entry/python_and_dtrace_in_build
+ */
+
+/*
+ * Yes, this is as gross as it looks. DTrace cannot handle static functions,
+ * and our stat_impl.h has them in ILP32.
+ */
+#define _SYS_STAT_H
+
+/*
+** When compiling in 32 bits:
+** - Early inclusion to avoid problems with
+** _FILE_OFFSET_BITS redefined.
+** - Also, we must "undef" _POSIX_PTHREAD_SEMANTICS
+** to avoid error compiling this source.
+*/
+#include "pyconfig.h"
+#undef _POSIX_PTHREAD_SEMANTICS
+
+#include
+#include
+
+#include "pyport.h"
+#include "pyatomic.h"
+/* "string" type is used in dtrace */
+#define string stringDTRACE
+#include "object.h"
+#include "pystate.h"
+#include "pyarena.h"
+#include "pythonrun.h"
+#include "compile.h"
+#include "frameobject.h"
+/* Avoid a compile error because a symbol (equivalent) redefinition */
+#undef __STDC__
+/* "self" has an special meaning for dtrace */
+#define self selfDTRACE
+#include "unicodeobject.h"
+#undef string
+#undef self
+
+#include "pydtrace_offsets.h"
+
+#if defined(__i386)
+#define startframe PyEval_EvalFrameEx
+#define endframe AFTER_PyEval_EvalFrameEx
+#elif defined(__amd64)
+#define startframe PyEval_EvalFrameExReal
+#define endframe AFTER_PyEval_EvalFrameExReal
+#elif defined(__sparc)
+#define startframe PyEval_EvalFrameExReal
+#define endframe AFTER_PyEval_EvalFrameExReal
+#endif
+
+#ifdef __sparcv9
+#define STACK_BIAS (2048-1)
+#else
+#define STACK_BIAS 0
+#endif
+
+#define at_evalframe(addr) \
+ ((uintptr_t)addr >= ((uintptr_t)&``startframe) && \
+ (uintptr_t)addr < ((uintptr_t)&``endframe))
+#define probe dtrace:helper:ustack:
+#define print_result(r) (r)
+
+#if defined(__i386) || defined(__amd64)
+#define frame_ptr_addr ((uintptr_t)arg1 + sizeof(uintptr_t) * 2)
+#elif defined(__sparc)
+#define frame_ptr_addr ((uintptr_t)arg1 + STACK_BIAS + sizeof(uintptr_t) * 8)
+#else
+#error unknown architecture
+#endif
+
+/* startframe and endframe are macro-expansions */
+extern uintptr_t startframe;
+extern uintptr_t endframe;
+
+
+#define copyin_obj(addr, obj) ((obj *)copyin((uintptr_t)(addr), sizeof(obj)))
+
+/*
+** Check if the string is ASCII. Don't use bitfields, because the
+** packing in GCC and D are different. BEWARE!!!.
+** The size of the structures are also different!. That is the reason for
+** the negative offset. BEWARE!!!
+*/
+#define pystr_len(addr) ((*(((char *)addr)+PYDTRACE_ASCII_OFFSET)) & PYDTRACE_ASCII_MASK ? \
+ (addr)->_base.length : \
+ *(Py_ssize_t *)(((char *)(addr)) + PYDTRACE_UTF8_LENGTH_OFFSET))
+#define pystr_addr(addr, addr2) ((*(((char *)addr)+PYDTRACE_ASCII_OFFSET)) & PYDTRACE_ASCII_MASK ? \
+ (char *)(((char *)(addr2)) + PYDTRACE_PyASCIIObject_SIZE) : \
+ (char *)*(uintptr_t *)(((char *)(addr)) + PYDTRACE_UTF8_OFFSET))
+
+#define add_digit(nr, div) (((nr) / div) ? \
+ (this->result[this->pos++] = '0' + (((nr) / div) % 10)) : \
+ (this->result[this->pos] = '\0'))
+#define add_char(c) (this->result[this->pos++] = c)
+
+probe /at_evalframe(arg0)/
+{
+ this->framep = *(uintptr_t *)copyin(frame_ptr_addr, sizeof(uintptr_t));
+ this->frameo = copyin_obj(this->framep, PyFrameObject);
+ this->codep = this->frameo->f_code;
+ this->codeo = copyin_obj(this->codep, PyCodeObject);
+ /* If we just enter a function, show the definition line */
+ this->lineno = this->codeo->co_firstlineno +
+ (this->frameo->f_lasti == -1 ? 0 :
+ *copyin_obj(this->codeo->co_linenos + this->frameo->f_lasti,
+ unsigned short));
+ this->filenameo = copyin_obj(this->codeo->co_filename, PyCompactUnicodeObject);
+ this->len_filename = pystr_len(this->filenameo);
+ this->nameo = copyin_obj(this->codeo->co_name, PyCompactUnicodeObject);
+ this->len_name = pystr_len(this->nameo);
+ this->len = 1 + (this->len_filename) + 1 + 5 + 2 +
+ (this->len_name) + 1 + 1;
+
+ this->result = (char *)alloca(this->len);
+ this->pos = 0;
+ add_char('@');
+
+ copyinto((uintptr_t)pystr_addr(this->filenameo, this->codeo->co_filename), this->len_filename, this->result+this->pos);
+ this->pos += this->len_filename;
+
+ add_char(':');
+ add_digit(this->lineno, 10000);
+ add_digit(this->lineno, 1000);
+ add_digit(this->lineno, 100);
+ add_digit(this->lineno, 10);
+ add_digit(this->lineno, 1);
+ add_char(' ');
+ add_char('(');
+
+ copyinto((uintptr_t)pystr_addr(this->nameo, this->codeo->co_name), this->len_name, this->result+this->pos);
+ this->pos += this->len_name;
+
+ add_char(')');
+ this->result[this->pos] = '\0';
+ print_result(stringof(this->result));
+}
+
+probe /!at_evalframe(arg0)/
+{
+ NULL;
+}
+
+#endif /* PYDTRACE_STACK_HELPER */
+
diff -r f0955d95ac02 -r d12ded643482 Include/pydtrace_offsets.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Include/pydtrace_offsets.c Tue Jul 03 03:43:34 2012 +0200
@@ -0,0 +1,40 @@
+#include "Python.h"
+#include "unicodeobject.h"
+#include
+#include
+
+int main(int argc, const char* argv[]) {
+ PyCompactUnicodeObject o;
+ unsigned char *p = (unsigned char *)(&o);
+
+ if (argc != 3) {
+ printf("Parameter number incorrect\n");
+ exit(1);
+ }
+
+ memset(&o, 0, sizeof(o));
+ o._base.state.ascii = 1;
+ while (!*p) p++;
+
+ printf("/* File autogenerated. DO NOT MODIFY MANUALLY */\n");
+ printf("\n");
+ printf("#ifndef PYDTRACE_OFFSETS_H\n");
+ printf("#define PYDTRACE_OFFSETS_H\n");
+ printf("\n");
+ printf("#define PYDTRACE_ASCII_OFFSET %d\n",
+ p-(unsigned char *)(&o));
+ printf("#define PYDTRACE_ASCII_MASK %d\n", *p);
+ printf("#define PYDTRACE_PyASCIIObject_SIZE %d\n",
+ sizeof(PyASCIIObject));
+ printf("#define PYDTRACE_UTF8_LENGTH_OFFSET %d\n",
+ offsetof(PyCompactUnicodeObject, utf8_length));
+ printf("#define PYDTRACE_UTF8_OFFSET %d\n",
+ offsetof(PyCompactUnicodeObject, utf8));
+ printf("\n");
+ printf("#define AFTER_PyEval_EvalFrameEx %s\n", argv[1]);
+ printf("#define AFTER_PyEval_EvalFrameExReal %s\n", argv[2]);
+ printf("\n");
+ printf("#endif\n");
+ return 0;
+}
+
diff -r f0955d95ac02 -r d12ded643482 Include/pydtrace_offsets.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Include/pydtrace_offsets.sh Tue Jul 03 03:43:34 2012 +0200
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+DTRACE_NM=$1
+CEVAL_O=$2
+PYDTRACE_OFFSETS=$3
+if test "$DTRACE_NM" = "OTHER" ; then
+ $PYDTRACE_OFFSETS \
+ "`nm -n $CEVAL_O | grep \" T \" | \
+ sed -n \"/ T PyEval_EvalFrameEx$/{n;p;}\" | \
+ sed \"s/.* T \(.*\)$/\1/\"`" \
+ "`nm -n $CEVAL_O | grep \" T \" | \
+ sed -n \"/ T PyEval_EvalFrameExReal$/{n;p;}\" | \
+ sed \"s/.* T \(.*\)$/\1/\"`"
+fi
+if test "$DTRACE_NM" = "SOLARIS_10" ; then
+ $PYDTRACE_OFFSETS \
+ "`/usr/ccs/bin/nm -n $CEVAL_O | \
+ /usr/bin/grep \"\\|FUNC \\|\" | \
+ /usr/bin/grep -v \"\\|IGNORE \\|\" | \
+ /usr/bin/tr -d \"\\[\\]\\|\" | sort -n | \
+ sed -n \"/ PyEval_EvalFrameEx$/{n;p;}\" | \
+ sed \"s/.* \([a-zA-Z0-9_]*\)$/\1/\"`" \
+ "`/usr/ccs/bin/nm -n $CEVAL_O | \
+ /usr/bin/grep \"\\|FUNC \\|\" | \
+ /usr/bin/grep -v \"\\|IGNORE \\|\" | \
+ /usr/bin/tr -d \"\\[\\]\\|\" | sort -n | \
+ sed -n \"/ PyEval_EvalFrameExReal$/{n;p;}\" | \
+ sed \"s/.* \([a-zA-Z0-9_]*\)$/\1/\"`"
+fi
+
diff -r f0955d95ac02 -r d12ded643482 Lib/test/dtrace_sample.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Lib/test/dtrace_sample.py Tue Jul 03 03:43:34 2012 +0200
@@ -0,0 +1,80 @@
+# Sample script for use by test_dtrace.py
+# DO NOT MODIFY THIS FILE IN ANY WAY WITHOUT UPDATING test_dtrace.py!!!!!
+
+import gc
+
+def function_1() :
+ pass
+
+# Check stacktrace
+def function_2() :
+ function_1()
+
+# CALL_FUNCTION_VAR
+def function_3(dummy, dummy2) :
+ pass
+
+# CALL_FUNCTION_KW
+def function_4(**dummy) :
+ pass
+
+# CALL_FUNCTION_VAR_KW
+def function_5(dummy, dummy2, **dummy3) :
+ pass
+
+def test_entry_return_and_stack() :
+ function_1()
+ function_2()
+ function_3(*(1,2))
+ function_4(**{"test":42})
+ function_5(*(1,2), **{"test":42})
+
+def test_line() :
+ a = 1 # Preamble
+ for i in range(2) :
+ a = i
+ b = i+2
+ c = i+3
+ d = a + b +c
+ a = 1 # Epilogue
+
+def test_unicode_entry_return_and_stack() :
+ def únícódé() :
+ pass
+ únícódé()
+
+def test_instance_creation_destruction() :
+ class old_style_class() :
+ pass
+ class new_style_class(object) :
+ pass
+
+ a = old_style_class()
+ del a
+ gc.collect()
+ b = new_style_class()
+ del b
+ gc.collect()
+
+ a = old_style_class()
+ del old_style_class
+ gc.collect()
+ b = new_style_class()
+ del new_style_class
+ gc.collect()
+ del a
+ gc.collect()
+ del b
+ gc.collect()
+
+def test_garbage_collection() :
+ gc.collect()
+
+
+if __name__ == "__main__":
+ test_entry_return_and_stack()
+ test_line()
+ test_unicode_entry_return_and_stack()
+ test_instance_creation_destruction()
+ test_garbage_collection()
+
diff -r f0955d95ac02 -r d12ded643482 Lib/test/test_dtrace.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Lib/test/test_dtrace.py Tue Jul 03 03:43:34 2012 +0200
@@ -0,0 +1,434 @@
+import sys, unittest, subprocess, os.path, dis, types
+import dtrace
+from test.support import TESTFN, run_unittest, findfile
+
+sample = os.path.abspath(findfile("dtrace_sample.py"))
+if not dtrace.available :
+ raise unittest.SkipTest("dtrace support not compiled in")
+
+def normalize(data) :
+ # DTRACE keeps a per-CPU buffer, and when showing the fired probes,
+ # buffers are concatenated. So if the operating system moves our
+ # thread around, the straight result can be "non causal".
+ # So we add timestamps to the probe firing, and sort by that field.
+ try :
+ result = data if isinstance(data, str) else data.decode("ascii")
+ result = [i.split("\t") \
+ for i in result.replace("\r", "").split("\n") if len(i)]
+ result.sort(key = lambda i: int(i[0]))
+ result = "".join((i[1] for i in result))
+ result = result.replace(" ", "")
+ except :
+ # If something goes wrong, rebuild the value so we can see the
+ # real result when the assert fails.
+ result = data if isinstance(data, str) else data.decode("ascii")
+ result = result.replace("\r", "").replace("\n", "")
+ return result
+
+dscript = """
+pid$target::PyEval_EvalCode:entry
+"""
+dscript = dscript.replace("\r", "").replace("\n", "")
+result, _ = subprocess.Popen(["dtrace", "-q", "-l", "-n", dscript,
+ "-c", "%s %s" %(sys.executable, sample)], stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT).communicate()
+if result.decode("ascii").split("\n")[1].split()[-2:] != \
+ ["PyEval_EvalCode", "entry"] :
+ result2 = repr(result)
+ raise unittest.SkipTest("dtrace seems not to be working. " + \
+ "Please, check your privileges. " +
+ "Result: " +result2)
+
+class DTraceTestsNormal(unittest.TestCase) :
+ def setUp(self) :
+ self.optimize = False
+
+ def test_function_entry_return(self) :
+ dscript = """
+python$target:::function-entry
+/(copyinstr(arg0)=="%(path)s") &&
+(copyinstr(arg1)=="test_entry_return_and_stack")/
+{
+ self->trace = 1;
+}
+python$target:::function-entry,python$target:::function-return
+/(copyinstr(arg0)=="%(path)s") && (self->trace)/
+{
+ printf("%%d\t**%%s*%%s*%%s*%%d\\n", timestamp,
+ probename, copyinstr(arg0),
+ copyinstr(arg1), arg2);
+}
+python$target:::function-return
+/(copyinstr(arg0)=="%(path)s") &&
+(copyinstr(arg1)=="test_entry_return_and_stack")/
+{
+ self->trace = 0;
+}
+""" %{"path":sample}
+
+ dscript = dscript.replace("\r", "").replace("\n", "")
+ expected_result = """
+ **function-entry*%(path)s*test_entry_return_and_stack*25
+ **function-entry*%(path)s*function_1*6
+ **function-return*%(path)s*function_1*7
+ **function-entry*%(path)s*function_2*10
+ **function-entry*%(path)s*function_1*6
+ **function-return*%(path)s*function_1*7
+ **function-return*%(path)s*function_2*11
+ **function-entry*%(path)s*function_3*14
+ **function-return*%(path)s*function_3*15
+ **function-entry*%(path)s*function_4*18
+ **function-return*%(path)s*function_4*19
+ **function-entry*%(path)s*function_5*22
+ **function-return*%(path)s*function_5*23
+ **function-return*%(path)s*test_entry_return_and_stack*30
+ """ %{"path":sample}
+
+ command = "%s %s" %(sys.executable, sample)
+ if self.optimize :
+ command = "%s -OO %s" %(sys.executable, sample)
+ actual_result, _ = subprocess.Popen(["dtrace", "-q", "-n",
+ dscript,
+ "-c", command],
+ stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()
+
+ actual_result = normalize(actual_result)
+ expected_result = expected_result.replace("\r", "").replace("\n",
+ "").replace(" ", "")
+ self.assertEqual(actual_result, expected_result)
+
+ @unittest.skipIf(sys.platform == 'darwin',
+ "MacOS X doesn't support jstack()")
+ def test_stack(self) :
+ dscript = """
+python$target:::function-entry
+/(copyinstr(arg0)=="%(path)s") &&
+(copyinstr(arg1)=="test_entry_return_and_stack")/
+{
+ self->trace = 1;
+}
+python$target:::function-entry
+/(copyinstr(arg0)=="%(path)s") && (self->trace)/
+{
+ printf("[x]");
+ jstack();
+}
+python$target:::function-return
+/(copyinstr(arg0)=="%(path)s") &&
+(copyinstr(arg1)=="test_entry_return_and_stack")/
+{
+ self->trace = 0;
+}
+""" %{"path":sample}
+
+ dscript = dscript.replace("\r", "").replace("\n", "")
+ expected_result = """
+ [x]
+ [%(path)s:25(test_entry_return_and_stack)]
+ [x]
+ [%(path)s:6(function_1)]
+ [%(path)s:26(test_entry_return_and_stack)]
+ [x]
+ [%(path)s:10(function_2)]
+ [%(path)s:27(test_entry_return_and_stack)]
+ [x]
+ [%(path)s:6(function_1)]
+ [%(path)s:11(function_2)]
+ [%(path)s:27(test_entry_return_and_stack)]
+ [x]
+ [%(path)s:14(function_3)]
+ [%(path)s:28(test_entry_return_and_stack)]
+ [x]
+ [%(path)s:18(function_4)]
+ [%(path)s:29(test_entry_return_and_stack)]
+ [x]
+ [%(path)s:22(function_5)]
+ [%(path)s:30(test_entry_return_and_stack)]
+ """ %{"path":sample}
+
+ command = "%s %s" %(sys.executable, sample)
+ if self.optimize :
+ command = "%s -OO %s" %(sys.executable, sample)
+ actual_result, _ = subprocess.Popen(["dtrace", "-q", "-n",
+ dscript,
+ "-c", command],
+ stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()
+
+ actual_result = [i for i in actual_result.decode("ascii").split("\n") \
+ if (("[" in i) and not i.endswith(" () ]"))]
+ actual_result = "".join(actual_result)
+ actual_result = actual_result.replace("\r", "").replace("\n",
+ "").replace(" ", "")
+ expected_result = expected_result.replace("\r", "").replace("\n",
+ "").replace(" ", "")
+ self.assertEqual(actual_result, expected_result)
+
+ def test_garbage_collection(self) :
+ dscript = """
+python$target:::gc-start,python$target:::gc-done
+{
+ printf("%d\t**%s(%ld)\\n", timestamp, probename, arg0);
+}
+"""
+
+ dscript = dscript.replace("\r", "").replace("\n", "")
+ command = "%s %s" %(sys.executable, sample)
+ if self.optimize :
+ command = "%s -OO %s" %(sys.executable, sample)
+ actual_result, _ = subprocess.Popen(["dtrace", "-q", "-n",
+ dscript,
+ "-c", command],
+ stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()
+
+ actual_result = normalize(actual_result)
+ for i in range(10) :
+ actual_result = actual_result.replace(str(i), "")
+ expected_result = "**gc-start()**gc-done()" * \
+ actual_result.count("**gc-start()**")
+
+ self.assertEqual(actual_result, expected_result)
+
+ def test_verify_opcodes(self) :
+ # Verify that we are checking:
+ opcodes = set(["CALL_FUNCTION", "CALL_FUNCTION_VAR",
+ "CALL_FUNCTION_KW", "CALL_FUNCTION_VAR_KW"])
+ obj = compile(open(sample, encoding="utf-8").read(), "sample", "exec")
+ class dump() :
+ def __init__(self) :
+ self.buf = []
+ def write(self, v) :
+ self.buf.append(v)
+
+ dump = dump()
+ stdout = sys.stdout
+ sys.stdout = dump
+ for i in obj.co_consts :
+ if isinstance(i, types.CodeType) and \
+ (i.co_name == 'test_entry_return_and_stack') :
+ dis.dis(i)
+ sys.stdout = stdout
+ dump = "\n".join(dump.buf)
+ dump = dump.replace("\r", "").replace("\n", "").split()
+ for i in dump :
+ opcodes.discard(i)
+ # Are we verifying all the relevant opcodes?
+ self.assertEqual(set(), opcodes) # Are we verifying all opcodes?
+
+ def test_line(self) :
+ dscript = """
+python$target:::line
+/(copyinstr(arg0)=="%(path)s") &&
+(copyinstr(arg1)=="test_line")/
+{
+ printf("%%d\t**%%s*%%s*%%s*%%d\\n", timestamp,
+ probename, copyinstr(arg0),
+ copyinstr(arg1), arg2);
+}
+""" %{"path":sample}
+
+ dscript = dscript.replace("\r", "").replace("\n", "")
+ expected_result = """
+ **line*%(path)s*test_line*33
+ **line*%(path)s*test_line*34
+ **line*%(path)s*test_line*35
+ **line*%(path)s*test_line*36
+ **line*%(path)s*test_line*37
+ **line*%(path)s*test_line*38
+ **line*%(path)s*test_line*34
+ **line*%(path)s*test_line*35
+ **line*%(path)s*test_line*36
+ **line*%(path)s*test_line*37
+ **line*%(path)s*test_line*38
+ **line*%(path)s*test_line*34
+ **line*%(path)s*test_line*39
+ """ %{"path":sample}
+
+ command = "%s %s" %(sys.executable, sample)
+ if self.optimize :
+ command = "%s -OO %s" %(sys.executable, sample)
+ actual_result, _ = subprocess.Popen(["dtrace", "-q", "-n",
+ dscript,
+ "-c", command],
+ stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()
+
+ actual_result = normalize(actual_result)
+ expected_result = expected_result.replace("\r", "").replace("\n",
+ "").replace(" ", "")
+ self.assertEqual(actual_result, expected_result)
+
+ def test_instance_creation_destruction(self) :
+ dscript = """
+python$target:::function-entry
+/(copyinstr(arg0)=="%(path)s") &&
+(copyinstr(arg1)=="test_instance_creation_destruction")/
+{
+ self->trace = 1;
+}
+
+python$target:::instance-new-start,
+python$target:::instance-new-done,
+python$target:::instance-delete-start,
+python$target:::instance-delete-done
+/self->trace/
+{
+ printf("%%d\t**%%s* (%%s.%%s)\\n", timestamp,
+ probename, copyinstr(arg1), copyinstr(arg0));
+}
+
+python$target:::function-return
+/(copyinstr(arg0)=="%(path)s") &&
+(copyinstr(arg1)=="test_instance_creation_destruction")/
+{
+ self->trace = 0;
+}
+""" %{"path":sample}
+
+ dscript = dscript.replace("\r", "").replace("\n", "")
+ expected_result = """
+ **instance-new-start*(__main__.old_style_class)
+ **instance-new-done*(__main__.old_style_class)
+ **instance-delete-start*(__main__.old_style_class)
+ **instance-delete-done*(__main__.old_style_class)
+ **instance-new-start*(__main__.new_style_class)
+ **instance-new-done*(__main__.new_style_class)
+ **instance-delete-start*(__main__.new_style_class)
+ **instance-delete-done*(__main__.new_style_class)
+ **instance-new-start*(__main__.old_style_class)
+ **instance-new-done*(__main__.old_style_class)
+ **instance-new-start*(__main__.new_style_class)
+ **instance-new-done*(__main__.new_style_class)
+ **instance-delete-start*(__main__.old_style_class)
+ **instance-delete-done*(__main__.old_style_class)
+ **instance-delete-start*(__main__.new_style_class)
+ **instance-delete-done*(__main__.new_style_class)
+ """
+
+ command = "%s %s" %(sys.executable, sample)
+ if self.optimize :
+ command = "%s -OO %s" %(sys.executable, sample)
+ actual_result, _ = subprocess.Popen(["dtrace", "-q", "-n",
+ dscript,
+ "-c", command],
+ stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()
+
+ actual_result = normalize(actual_result)
+ expected_result = expected_result.replace("\r", "").replace("\n",
+ "").replace(" ", "")
+ self.assertEqual(actual_result, expected_result)
+
+ def test_unicode_function_entry_return(self) :
+ dscript = """
+python$target:::function-entry
+/(copyinstr(arg0)=="%(path)s") &&
+(copyinstr(arg1)=="test_unicode_entry_return_and_stack")/
+{
+ self->trace = 1;
+}
+python$target:::function-entry,python$target:::function-return
+/(copyinstr(arg0)=="%(path)s") && (self->trace)/
+{
+ printf("%%d\t**%%s*%%s*%%s*%%d\\n", timestamp,
+ probename, copyinstr(arg0),
+ copyinstr(arg1), arg2);
+}
+python$target:::function-return
+/(copyinstr(arg0)=="%(path)s") &&
+(copyinstr(arg1)=="test_unicode_entry_return_and_stack")/
+{
+ self->trace = 0;
+}
+""" %{"path":sample}
+
+ dscript = dscript.replace("\r", "").replace("\n", "")
+ expected_result = """
+ **function-entry*%(path)s*test_unicode_entry_return_and_stack*41
+ **function-entry*%(path)s*únícódé*42
+ **function-return*%(path)s*únícódé*43
+ **function-return*%(path)s*test_unicode_entry_return_and_stack*44
+ """ %{"path":sample}
+
+ command = "%s %s" %(sys.executable, sample)
+ if self.optimize :
+ command = "%s -OO %s" %(sys.executable, sample)
+ actual_result, _ = subprocess.Popen(["dtrace", "-q", "-n",
+ dscript,
+ "-c", command],
+ stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()
+
+ actual_result = actual_result.decode("utf8")
+ actual_result = normalize(actual_result)
+ expected_result = expected_result.replace("\r", "").replace("\n",
+ "").replace(" ", "")
+ self.assertEqual(actual_result, expected_result)
+
+ @unittest.skipIf(sys.platform == 'darwin',
+ "MacOS X doesn't support jstack()")
+ def test_unicode_stack(self) :
+ dscript = """
+python$target:::function-entry
+/(copyinstr(arg0)=="%(path)s") &&
+(copyinstr(arg1)=="test_unicode_entry_return_and_stack")/
+{
+ self->trace = 1;
+}
+python$target:::function-entry
+/(copyinstr(arg0)=="%(path)s") && (self->trace)/
+{
+ printf("[x]");
+ jstack();
+}
+python$target:::function-return
+/(copyinstr(arg0)=="%(path)s") &&
+(copyinstr(arg1)=="test_unicode_entry_return_and_stack")/
+{
+ self->trace = 0;
+}
+""" %{"path":sample}
+
+ dscript = dscript.replace("\r", "").replace("\n", "")
+ expected_result = """
+ [x]
+ [%(path)s:41(test_unicode_entry_return_and_stack)]
+ [x]
+ [%(path)s:42(únícódé)]
+ [%(path)s:44(test_unicode_entry_return_and_stack)]
+ """ %{"path":sample}
+
+ command = "%s %s" %(sys.executable, sample)
+ if self.optimize :
+ command = "%s -OO %s" %(sys.executable, sample)
+ actual_result, _ = subprocess.Popen(["dtrace", "-q", "-n",
+ dscript,
+ "-c", command],
+ stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()
+
+ actual_result = [i for i in actual_result.decode("utf8").split("\n") \
+ if (("[" in i) and not i.endswith(" () ]"))]
+ actual_result = "".join(actual_result)
+ actual_result = actual_result.replace("\r", "").replace("\n",
+ "").replace(" ", "")
+ expected_result = expected_result.replace("\r", "").replace("\n",
+ "").replace(" ", "")
+ self.assertEqual(actual_result, expected_result)
+
+
+
+# This class try to verify that dtrace probes
+# are still working with optimizations enabled in the bytecode.
+#
+# Some tests will not actually verify it. For instance,
+# source code compilation follows optimization status of
+# current working Python. So, you should run the test
+# both with an optimizing and a non optimizing Python.
+class DTraceTestsOptimize(DTraceTestsNormal) :
+ def setUp(self) :
+ self.optimize = True
+
+
+def test_main():
+ run_unittest(DTraceTestsNormal)
+ run_unittest(DTraceTestsOptimize)
+
+if __name__ == '__main__':
+ test_main()
+
diff -r f0955d95ac02 -r d12ded643482 Makefile.pre.in
--- a/Makefile.pre.in Mon Jul 02 13:54:33 2012 -0700
+++ b/Makefile.pre.in Tue Jul 03 03:43:34 2012 +0200
@@ -49,6 +49,13 @@
# Use this to make a link between python$(VERSION) and python in $(BINDIR)
LN= @LN@
+DTRACE= @DTRACE@
+DFLAGS= @DFLAGS@
+DTRACEOBJS= @DTRACEOBJS@
+DTRACE_NM= @DTRACE_NM@
+DTRACE_LINKER= @DTRACE_LINKER@
+
+
# Portable install script (configure doesn't always guess right)
INSTALL= @INSTALL@
INSTALL_PROGRAM=@INSTALL_PROGRAM@
@@ -464,7 +471,8 @@
# Build the interpreter
$(BUILDPYTHON): Modules/python.o $(LIBRARY) $(LDLIBRARY) $(PY3LIBRARY)
- $(LINKCC) $(PY_LDFLAGS) $(LINKFORSHARED) -o $@ Modules/python.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST)
+ $(LINKCC) $(PY_LDFLAGS) $(LINKFORSHARED) -o $@ Modules/python.o \
+ $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST)
platform: $(BUILDPYTHON) $(SYSCONFIGDATA)
$(RUNSHARED) $(PYTHON_FOR_BUILD) -c 'import sys ; from sysconfig import get_platform ; print(get_platform()+"-"+sys.version[0:3])' >platform
@@ -491,7 +499,7 @@
$(AR) $(ARFLAGS) $@ $(MODOBJS)
$(RANLIB) $@
-libpython$(LDVERSION).so: $(LIBRARY_OBJS)
+libpython$(LDVERSION).so: $(LIBRARY_OBJS) $(DTRACEOBJS)
if test $(INSTSONAME) != $(LDLIBRARY); then \
$(BLDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \
$(LN) -f $(INSTSONAME) $@; \
@@ -502,9 +510,8 @@
libpython3.so: libpython$(LDVERSION).so
$(BLDSHARED) $(NO_AS_NEEDED) -o $@ -Wl,-h$@ $^
-libpython$(LDVERSION).dylib: $(LIBRARY_OBJS)
- $(CC) -dynamiclib -Wl,-single_module $(PY_LDFLAGS) -undefined dynamic_lookup -Wl,-install_name,$(prefix)/lib/libpython$(LDVERSION).dylib -Wl,-compatibility_version,$(VERSION) -Wl,-current_version,$(VERSION) -o $@ $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \
-
+libpython$(LDVERSION).dylib: $(LIBRARY_OBJS) $(DTRACEOBJS)
+ $(CC) -dynamiclib -Wl,-single_module $(PY_LDFLAGS) -undefined dynamic_lookup -Wl,-install_name,$(prefix)/lib/libpython$(LDVERSION).dylib -Wl,-compatibility_version,$(VERSION) -Wl,-current_version,$(VERSION) -o $@ $(LIBRARY_OBJS) $(DTRACEOBJS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST)
libpython$(VERSION).sl: $(LIBRARY_OBJS)
$(LDSHARED) -o $@ $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST)
@@ -604,12 +611,18 @@
$(MODULE_OBJS) \
$(SIGNAL_OBJS) \
$(MODOBJS) \
+ $(DTRACEOBJS) \
$(srcdir)/Modules/getbuildinfo.c
$(CC) -c $(PY_CORE_CFLAGS) \
-DHGVERSION="\"`LC_ALL=C $(HGVERSION)`\"" \
-DHGTAG="\"`LC_ALL=C $(HGTAG)`\"" \
-DHGBRANCH="\"`LC_ALL=C $(HGBRANCH)`\"" \
-o $@ $(srcdir)/Modules/getbuildinfo.c
+ if test "$(DTRACEOBJS)" != "" ; then \
+ $(DTRACE_LINKER) --relocatable \
+ $@ $(DTRACEOBJS) -o $@.DTRACE ; \
+ mv $@.DTRACE $@ ; \
+ fi;
Modules/getpath.o: $(srcdir)/Modules/getpath.c Makefile
$(CC) -c $(PY_CORE_CFLAGS) -DPYTHONPATH='"$(PYTHONPATH)"' \
@@ -724,6 +737,35 @@
$(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
+Include/pydtrace.h: $(srcdir)/Include/pydtrace.d
+ if test "$(DTRACE)" != "" ; then \
+ $(DTRACE) -o $@ $(DFLAGS) \
+ -C -h -s $(srcdir)/Include/pydtrace.d ; \
+ else touch $@ ; \
+ fi;
+
+Include/pydtrace_offsets.h: $(srcdir)/Include/pydtrace_offsets.c $(srcdir)/Python/ceval.o
+ $(CC) $(PY_CORE_CFLAGS) -o $(srcdir)/Include/pydtrace_offsets \
+ $(srcdir)/Include/pydtrace_offsets.c
+ $(srcdir)/Include/pydtrace_offsets.sh $(DTRACE_NM) \
+ $(srcdir)/Python/ceval.o $(srcdir)/Include/pydtrace_offsets > \
+ $(srcdir)/Include/pydtrace_offsets.h
+
+Python/ceval.o: Include/pydtrace.h
+Modules/gcmodule.o: Include/pydtrace.h
+Objects/typeobject.o: Include/pydtrace.h
+
+Python/pydtrace.o: $(srcdir)/Include/pydtrace.d $(srcdir)/Include/pydtrace_offsets.h \
+ Python/ceval.o Modules/gcmodule.o Objects/typeobject.o
+ if test "$(DTRACE)" != "" ; then \
+ $(DTRACE) -o $@ -DPYDTRACE_STACK_HELPER \
+ $(DFLAGS) $(PY_CPPFLAGS) \
+ -C -G -s $(srcdir)/Include/pydtrace.d \
+ Python/ceval.o Modules/gcmodule.o \
+ Objects/typeobject.o; \
+ else touch $@ ; \
+ fi;
+
############################################################################
# Header files
@@ -1337,6 +1379,8 @@
find . -name '*.so.[0-9]*.[0-9]*' -exec rm -f {} ';'
find build -name 'fficonfig.h' -exec rm -f {} ';' || true
find build -name 'fficonfig.py' -exec rm -f {} ';' || true
+ rm -f Include/pydtrace.h
+ rm -f Include/pydtrace_offsets Include/pydtrace_offsets.h
-rm -f Lib/lib2to3/*Grammar*.pickle
-rm -f $(SYSCONFIGDATA)
-rm -f Modules/_testembed Modules/_freeze_importlib
@@ -1368,6 +1412,8 @@
-o -name '*.orig' -o -name '*.rej' \
-o -name '*.bak' ')' \
-exec rm -f {} ';'
+ rm -f Include/pydtrace.h
+ rm -f Include/pydtrace_offsets Include/pydtrace_offsets.h
# Check for smelly exported symbols (not starting with Py/_Py)
smelly: all
diff -r f0955d95ac02 -r d12ded643482 Modules/dtracemodule.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Modules/dtracemodule.c Tue Jul 03 03:43:34 2012 +0200
@@ -0,0 +1,39 @@
+#include "Python.h"
+
+static PyMethodDef dtrace_methods[] = {
+ {NULL, NULL} /* sentinel */
+};
+
+
+static struct PyModuleDef dtracemodule = {
+ PyModuleDef_HEAD_INIT,
+ "dtrace",
+ NULL,
+ -1,
+ dtrace_methods,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+PyMODINIT_FUNC
+PyInit_dtrace(void)
+{
+ PyObject *m, *v;
+
+ m = PyModule_Create(&dtracemodule);
+ if (m) {
+#ifdef WITH_DTRACE
+ v = Py_True;
+#else
+ v = Py_False;
+#endif
+ Py_INCREF(v);
+ if (PyModule_AddObject(m, "available", v) < 0) {
+ Py_DECREF(m);
+ return NULL;
+ }
+ }
+ return m;
+}
diff -r f0955d95ac02 -r d12ded643482 Modules/gcmodule.c
--- a/Modules/gcmodule.c Mon Jul 02 13:54:33 2012 -0700
+++ b/Modules/gcmodule.c Tue Jul 03 03:43:34 2012 +0200
@@ -26,6 +26,10 @@
#include "Python.h"
#include "frameobject.h" /* for PyFrame_ClearFreeList */
+#ifdef WITH_DTRACE
+#include "pydtrace.h"
+#endif
+
/* Get an object's GC head */
#define AS_GC(o) ((PyGC_Head *)(o)-1)
@@ -841,7 +845,12 @@
/* This is the main function. Read this to understand how the
* collection process works. */
static Py_ssize_t
-collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable)
+#ifdef WITH_DTRACE
+collect2
+#else
+collect
+#endif
+(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable)
{
int i;
Py_ssize_t m = 0; /* # objects collected */
@@ -1000,6 +1009,49 @@
return n+m;
}
+#ifdef WITH_DTRACE
+static void
+dtrace_gc_start(int collection)
+{
+ PYTHON_GC_START(collection);
+
+ /*
+ * Currently a USDT tail-call will not receive the correct arguments.
+ * Disable the tail call here.
+ */
+#if defined(__sparc)
+ asm("nop");
+#endif
+}
+
+static void
+dtrace_gc_done(Py_ssize_t value)
+{
+ PYTHON_GC_DONE((long) value);
+
+ /*
+ * Currently a USDT tail-call will not receive the correct arguments.
+ * Disable the tail call here.
+ */
+#if defined(__sparc)
+ asm("nop");
+#endif
+}
+
+static Py_ssize_t
+collect(int collection, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable)
+{
+ Py_ssize_t value;
+
+ if (PYTHON_GC_START_ENABLED())
+ dtrace_gc_start(collection);
+ value = collect2(collection, n_collected, n_uncollectable);
+ if (PYTHON_GC_DONE_ENABLED())
+ dtrace_gc_done(value);
+ return value;
+}
+#endif /* WITH_DTRACE */
+
/* Invoke progress callbacks to notify clients that garbage collection
* is starting or stopping
*/
diff -r f0955d95ac02 -r d12ded643482 Objects/codeobject.c
--- a/Objects/codeobject.c Mon Jul 02 13:54:33 2012 -0700
+++ b/Objects/codeobject.c Tue Jul 03 03:43:34 2012 +0200
@@ -147,6 +147,37 @@
co->co_lnotab = lnotab;
co->co_zombieframe = NULL;
co->co_weakreflist = NULL;
+
+#ifdef WITH_DTRACE
+ /*
+ ** Cache UTF8 internally, available
+ ** for the pythonframe stack walker.
+ */
+ PyUnicode_AsUTF8(filename);
+ PyUnicode_AsUTF8(name);
+
+ i = PyBytes_Size(co->co_code);
+ co->co_linenos = PyMem_Malloc(sizeof(unsigned short) * i);
+ if (co->co_linenos) {
+ unsigned short *p = (unsigned short *)(co->co_linenos);
+ unsigned char *p2 = (unsigned char*)PyBytes_AsString(co->co_lnotab);
+ int size = PyBytes_Size(co->co_lnotab) / 2;
+ int i2;
+ unsigned short offset = 0;
+
+ while (size) {
+ size -= 1;
+ i2 = *p2++;
+ i-=i2;
+ while (i2--)
+ *p++ = offset;
+ offset += *p2++;
+ }
+ while(i--)
+ *p++ = offset;
+ }
+#endif
+
return co;
}
diff -r f0955d95ac02 -r d12ded643482 Objects/frameobject.c
--- a/Objects/frameobject.c Mon Jul 02 13:54:33 2012 -0700
+++ b/Objects/frameobject.c Tue Jul 03 03:43:34 2012 +0200
@@ -714,6 +714,15 @@
f->f_lineno = code->co_firstlineno;
f->f_iblock = 0;
+#ifdef WITH_DTRACE
+ /*
+ ** Cache UTF8 internally, available
+ ** for the pythonframe stack walker.
+ */
+ PyUnicode_AsUTF8(f->f_code->co_filename);
+ PyUnicode_AsUTF8(f->f_code->co_name);
+#endif
+
_PyObject_GC_TRACK(f);
return f;
}
diff -r f0955d95ac02 -r d12ded643482 Objects/typeobject.c
--- a/Objects/typeobject.c Mon Jul 02 13:54:33 2012 -0700
+++ b/Objects/typeobject.c Tue Jul 03 03:43:34 2012 +0200
@@ -4,6 +4,10 @@
#include "frameobject.h"
#include "structmember.h"
+#ifdef WITH_DTRACE
+#include "pydtrace.h"
+#endif
+
#include
@@ -741,8 +745,29 @@
PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)
{
PyObject *obj;
- const size_t size = _PyObject_VAR_SIZE(type, nitems+1);
+ size_t size;
+
+#ifdef WITH_DTRACE
+ PyObject *mod;
+ char *mod_name;
+
+ if (PYTHON_INSTANCE_NEW_START_ENABLED()) {
+ if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
+ mod = PyDict_GetItemString(type->tp_dict, "__module__");
+ if (mod == NULL || !PyUnicode_Check(mod)) {
+ mod_name = "?";
+ } else {
+ mod_name = PyUnicode_AsUTF8(mod);
+ if (!mod_name)
+ mod_name = "?";
+ }
+ PYTHON_INSTANCE_NEW_START((char *)(type->tp_name), mod_name);
+ }
+ }
+#endif
+
/* note that we need to add one, for the sentinel */
+ size = _PyObject_VAR_SIZE(type, nitems+1);
if (PyType_IS_GC(type))
obj = _PyObject_GC_Malloc(size);
@@ -764,6 +789,23 @@
if (PyType_IS_GC(type))
_PyObject_GC_TRACK(obj);
+
+#ifdef WITH_DTRACE
+ if (PYTHON_INSTANCE_NEW_DONE_ENABLED()) {
+ if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
+ mod = PyDict_GetItemString(type->tp_dict, "__module__");
+ if (mod == NULL || !PyUnicode_Check(mod)) {
+ mod_name = "?";
+ } else {
+ mod_name = PyUnicode_AsUTF8(mod);
+ if (!mod_name)
+ mod_name = "?";
+ }
+ PYTHON_INSTANCE_NEW_DONE((char *)(type->tp_name), mod_name);
+ }
+ }
+#endif
+
return obj;
}
@@ -884,9 +926,56 @@
return 0;
}
+#ifdef WITH_DTRACE
+static void subtype_dealloc2(PyObject *); /* Forward declaration */
+
static void
subtype_dealloc(PyObject *self)
{
+ PyObject *mod;
+ char *mod_name;
+ PyTypeObject *type;
+
+ type = Py_TYPE(self);
+ Py_INCREF(type);
+
+ if (PYTHON_INSTANCE_DELETE_START_ENABLED()) {
+ mod = PyDict_GetItemString(type->tp_dict, "__module__");
+ if (mod == NULL || !PyUnicode_Check(mod)) {
+ mod_name = "?";
+ } else {
+ mod_name = PyUnicode_AsUTF8(mod);
+ if (!mod_name)
+ mod_name = "?";
+ }
+ PYTHON_INSTANCE_DELETE_START((char *)(type->tp_name), mod_name);
+ }
+
+ subtype_dealloc2(self);
+
+ if (PYTHON_INSTANCE_DELETE_DONE_ENABLED()) {
+ mod = PyDict_GetItemString(type->tp_dict, "__module__");
+ if (mod == NULL || !PyUnicode_Check(mod)) {
+ mod_name = "?";
+ } else {
+ mod_name = PyUnicode_AsUTF8(mod);
+ if (!mod_name)
+ mod_name = "?";
+ }
+ PYTHON_INSTANCE_DELETE_DONE((char *)(type->tp_name), mod_name);
+ }
+ Py_DECREF(type);
+}
+#endif
+
+static void
+#ifdef WITH_DTRACE
+subtype_dealloc2
+#else
+subtype_dealloc
+#endif
+(PyObject *self)
+{
PyTypeObject *type, *base;
destructor basedealloc;
diff -r f0955d95ac02 -r d12ded643482 Python/ceval.c
--- a/Python/ceval.c Mon Jul 02 13:54:33 2012 -0700
+++ b/Python/ceval.c Tue Jul 03 03:43:34 2012 +0200
@@ -18,6 +18,13 @@
#include
+#ifdef WITH_DTRACE
+#include "pydtrace.h"
+#else
+/* We can not have conditional compilation inside macros */
+#define PYTHON_LINE_ENABLED() (0)
+#endif
+
#ifndef WITH_TSC
#define READ_TIMESTAMP(var)
@@ -119,6 +126,12 @@
#define CALL_FLAG_VAR 1
#define CALL_FLAG_KW 2
+#ifdef WITH_DTRACE
+static void maybe_dtrace_line(PyFrameObject *frame,
+ int *instr_lb, int *instr_ub,
+ int *instr_prev);
+#endif
+
#ifdef LLTRACE
static int lltrace;
static int prtrace(PyObject *, char *);
@@ -776,6 +789,49 @@
NULL, NULL);
}
+#ifdef WITH_DTRACE
+static void
+dtrace_entry(PyFrameObject *f)
+{
+ char *filename;
+ char *name;
+ int lineno;
+
+ filename = PyUnicode_AsUTF8(f->f_code->co_filename);
+ name = PyUnicode_AsUTF8(f->f_code->co_name);
+ lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);
+ PYTHON_FUNCTION_ENTRY(filename, name, lineno);
+
+ /*
+ * Currently a USDT tail-call will not receive the correct arguments.
+ * Disable the tail call here.
+ */
+#if defined(__sparc)
+ asm("nop");
+#endif
+}
+
+static void
+dtrace_return(PyFrameObject *f)
+{
+ char *filename;
+ char *name;
+ int lineno;
+
+ filename = PyUnicode_AsUTF8(f->f_code->co_filename);
+ name = PyUnicode_AsUTF8(f->f_code->co_name);
+ lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);
+ PYTHON_FUNCTION_RETURN(filename, name, lineno);
+
+ /*
+ * Currently a USDT tail-call will not receive the correct arguments.
+ * Disable the tail call here.
+ */
+#if defined(__sparc)
+ asm("nop");
+#endif
+}
+#endif
/* Interpreter main loop */
@@ -787,8 +843,16 @@
return PyEval_EvalFrameEx(f, 0);
}
+
PyObject *
+#if defined(WITH_DTRACE) && defined(__amd64)
+PyEval_EvalFrameExReal(long a1, long a2, long a3, long a4, long a5, long a6,
+ PyFrameObject *f, int throwflag)
+#elif defined(WITH_DTRACE) && defined(__sparc)
+PyEval_EvalFrameExReal(PyFrameObject *f, int throwflag)
+#else
PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
+#endif
{
#ifdef DXPAIRS
int lastopcode = 0;
@@ -915,7 +979,7 @@
#ifdef LLTRACE
#define FAST_DISPATCH() \
{ \
- if (!lltrace && !_Py_TracingPossible) { \
+ if (!lltrace && !_Py_TracingPossible) && !PYTHON_LINE_ENABLED()) { \
f->f_lasti = INSTR_OFFSET(); \
goto *opcode_targets[*next_instr++]; \
} \
@@ -924,7 +988,7 @@
#else
#define FAST_DISPATCH() \
{ \
- if (!_Py_TracingPossible) { \
+ if (!_Py_TracingPossible && !PYTHON_LINE_ENABLED()) { \
f->f_lasti = INSTR_OFFSET(); \
goto *opcode_targets[*next_instr++]; \
} \
@@ -1160,6 +1224,11 @@
}
}
+#ifdef WITH_DTRACE
+ if (PYTHON_FUNCTION_ENTRY_ENABLED())
+ dtrace_entry(f);
+#endif
+
co = f->f_code;
names = co->co_names;
consts = co->co_consts;
@@ -1347,6 +1416,12 @@
/* Main switch on opcode */
READ_TIMESTAMP(inst0);
+#ifdef WITH_DTRACE
+ if (PYTHON_LINE_ENABLED()) {
+ maybe_dtrace_line(f, &instr_lb, &instr_ub, &instr_prev);
+ }
+#endif
+
switch (opcode) {
/* BEWARE!
@@ -3077,6 +3152,10 @@
/* pop frame */
exit_eval_frame:
+#ifdef WITH_DTRACE
+ if (PYTHON_FUNCTION_RETURN_ENABLED())
+ dtrace_return(f);
+#endif
Py_LeaveRecursiveCall();
tstate->frame = f->f_back;
@@ -3766,6 +3845,57 @@
return result;
}
+/*
+ * These shenanigans look like utter madness, but what we're actually doing is
+ * making sure that the ustack helper will see the PyFrameObject pointer on the
+ * stack. We have two tricky cases:
+ *
+ * amd64
+ *
+ * We use up the six registers for passing arguments, meaning the call can't
+ * use a register for passing 'f', and has to push it onto the stack in a known
+ * location.
+ *
+ * And how does "throwflag" figure in to this? -PN
+ *
+ * SPARC
+ *
+ * Here the problem is that (on 32-bit) the compiler is re-using %i0 before
+ * some calls inside PyEval_EvalFrameReal(), which means that when it's saved,
+ * it's just some junk value rather than the real first argument. So, instead,
+ * we trace our proxy PyEval_EvalFrame(), where we 'know' the compiler won't
+ * decide to re-use %i0. We also need to defeat optimization of our proxy.
+ */
+
+#if defined(WITH_DTRACE)
+
+#if defined(__amd64)
+
+PyObject *
+PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
+{
+ volatile PyObject *f2;
+ f2 = PyEval_EvalFrameExReal(0, 0, 0, 0, 0, 0, f, throwflag);
+ return (PyObject *)f2;
+}
+
+#elif defined(__sparc)
+
+volatile int dummy;
+
+PyObject *
+PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
+{
+ volatile PyObject *f2;
+ f2 = PyEval_EvalFrameExReal(f, throwflag);
+ dummy = f->ob_refcnt;
+ return (PyObject *)f2;
+}
+
+#endif
+#endif
+
+
PyObject *
_PyEval_CallTracing(PyObject *func, PyObject *args)
{
@@ -3784,6 +3914,51 @@
return result;
}
+#ifdef WITH_DTRACE
+/* See Objects/lnotab_notes.txt for a description of how tracing works. */
+/* Practically a ripoff of "maybe_call_line_trace" function. */
+static void
+maybe_dtrace_line(PyFrameObject *frame,
+ int *instr_lb, int *instr_ub, int *instr_prev)
+{
+ int line = frame->f_lineno;
+ char *co_filename, *co_name;
+
+ /* If the last instruction executed isn't in the current
+ instruction window, reset the window.
+ */
+ if (frame->f_lasti < *instr_lb || frame->f_lasti >= *instr_ub) {
+ PyAddrPair bounds;
+ line = _PyCode_CheckLineNumber(frame->f_code, frame->f_lasti,
+ &bounds);
+ *instr_lb = bounds.ap_lower;
+ *instr_ub = bounds.ap_upper;
+ }
+ /* If the last instruction falls at the start of a line or if
+ it represents a jump backwards, update the frame's line
+ number and call the trace function. */
+ if (frame->f_lasti == *instr_lb || frame->f_lasti < *instr_prev) {
+ frame->f_lineno = line;
+ co_filename = PyUnicode_AsUTF8(frame->f_code->co_filename);
+ if (!co_filename)
+ co_filename = "?";
+ co_name = PyUnicode_AsUTF8(frame->f_code->co_name);
+ if (!co_name)
+ co_name = "?";
+ PYTHON_LINE(co_filename, co_name, line);
+ }
+ *instr_prev = frame->f_lasti;
+
+ /*
+ * Currently a USDT tail-call will not receive the correct arguments.
+ * Disable the tail call here.
+ */
+#if defined(__sparc)
+ asm("nop");
+#endif
+}
+#endif
+
/* See Objects/lnotab_notes.txt for a description of how tracing works. */
static int
maybe_call_line_trace(Py_tracefunc func, PyObject *obj,
diff -r f0955d95ac02 -r d12ded643482 configure
--- a/configure Mon Jul 02 13:54:33 2012 -0700
+++ b/configure Tue Jul 03 03:43:34 2012 +0200
@@ -1,13 +1,11 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for python 3.3.
+# Generated by GNU Autoconf 2.69 for python 3.3.
#
# Report bugs to .
#
#
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
-# Foundation, Inc.
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
#
#
# This configure script is free software; the Free Software Foundation
@@ -136,6 +134,31 @@
# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
if test "x$CONFIG_SHELL" = x; then
as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
emulate sh
@@ -169,7 +192,8 @@
else
exitcode=1; echo positional parameters were not saved.
fi
-test x\$exitcode = x0 || exit 1"
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
@@ -214,21 +238,25 @@
if test "x$CONFIG_SHELL" != x; then :
- # We cannot yet assume a decent shell, so we have to provide a
- # neutralization value for shells without unset; and this also
- # works around shells that cannot unset nonexistent variables.
- # Preserve -v and -x to the replacement shell.
- BASH_ENV=/dev/null
- ENV=/dev/null
- (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
- export CONFIG_SHELL
- case $- in # ((((
- *v*x* | *x*v* ) as_opts=-vx ;;
- *v* ) as_opts=-v ;;
- *x* ) as_opts=-x ;;
- * ) as_opts= ;;
- esac
- exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"}
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
fi
if test x$as_have_required = xno; then :
@@ -331,6 +359,14 @@
} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
@@ -452,6 +488,10 @@
chmod +x "$as_me.lineno" ||
{ $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
# Don't try to exec as it changes $[0], causing all sort of problems
# (the dirname of $[0] is not the place where we might find the
# original and so on. Autoconf is especially sensitive to this).
@@ -486,16 +526,16 @@
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
+ # In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -p'
- fi
-else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@@ -507,28 +547,8 @@
as_mkdir_p=false
fi
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in #(
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -618,6 +638,11 @@
MACHDEP_OBJS
DYNLOADFILE
DLINCLDIR
+DTRACEOBJS
+DTRACE_LINKER
+DTRACE_NM
+DFLAGS
+DTRACE
THREADOBJ
LDLAST
USE_THREAD_MODULE
@@ -779,6 +804,7 @@
with_tsc
with_pymalloc
with_valgrind
+with_dtrace
with_fpectl
with_libm
with_libc
@@ -1249,8 +1275,6 @@
if test "x$host_alias" != x; then
if test "x$build_alias" = x; then
cross_compiling=maybe
- $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
- If a cross compiler is detected then cross compile mode will be used" >&2
elif test "x$build_alias" != "x$host_alias"; then
cross_compiling=yes
fi
@@ -1456,6 +1480,7 @@
--with(out)-tsc enable/disable timestamp counter profile
--with(out)-pymalloc disable/enable specialized mallocs
--with-valgrind Enable Valgrind support
+ --with(out)-dtrace disable/enable dtrace support
--with-fpectl enable SIGFPE catching
--with-libm=STRING math library
--with-libc=STRING C library
@@ -1540,9 +1565,9 @@
if $ac_init_version; then
cat <<\_ACEOF
python configure 3.3
-generated by GNU Autoconf 2.68
-
-Copyright (C) 2010 Free Software Foundation, Inc.
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
@@ -1618,7 +1643,7 @@
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
- $as_test_x conftest$ac_exeext
+ test -x conftest$ac_exeext
}; then :
ac_retval=0
else
@@ -1916,7 +1941,8 @@
main ()
{
static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
@@ -1970,7 +1996,8 @@
main ()
{
static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
@@ -1986,7 +2013,8 @@
{
static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1)
< ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
@@ -2036,7 +2064,8 @@
main ()
{
static int test_array [1 - 2 * !(($2) >= 0)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
@@ -2052,7 +2081,8 @@
main ()
{
static int test_array [1 - 2 * !(($2) <= $ac_mid)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
@@ -2078,7 +2108,8 @@
main ()
{
static int test_array [1 - 2 * !(($2) < 0)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
@@ -2094,7 +2125,8 @@
main ()
{
static int test_array [1 - 2 * !(($2) >= $ac_mid)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
@@ -2128,7 +2160,8 @@
main ()
{
static int test_array [1 - 2 * !(($2) <= $ac_mid)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
@@ -2371,7 +2404,7 @@
running configure, to aid debugging if configure makes a mistake.
It was created by python $as_me 3.3, which was
-generated by GNU Autoconf 2.68. Invocation command line was
+generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2741,7 +2774,7 @@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_HAS_HG="found"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3530,7 +3563,7 @@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3570,7 +3603,7 @@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3623,7 +3656,7 @@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}cc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3664,7 +3697,7 @@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
ac_prog_rejected=yes
continue
@@ -3722,7 +3755,7 @@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -3766,7 +3799,7 @@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4212,8 +4245,7 @@
/* end confdefs.h. */
#include
#include
-#include
-#include
+struct stat;
/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
struct buf { int x; };
FILE * (*rcsopen) (struct buf *, struct stat *, int);
@@ -4353,7 +4385,7 @@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_CXX="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4396,7 +4428,7 @@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_ac_pt_CXX="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4451,7 +4483,7 @@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_CXX="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4494,7 +4526,7 @@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_ac_pt_CXX="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4549,7 +4581,7 @@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_CXX="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4592,7 +4624,7 @@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_ac_pt_CXX="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4655,7 +4687,7 @@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4699,7 +4731,7 @@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CXX="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -4942,7 +4974,7 @@
for ac_prog in grep ggrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+ as_fn_executable_p "$ac_path_GREP" || continue
# Check for GNU ac_path_GREP and select it if it is found.
# Check for GNU $ac_path_GREP
case `"$ac_path_GREP" --version 2>&1` in
@@ -5008,7 +5040,7 @@
for ac_prog in egrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+ as_fn_executable_p "$ac_path_EGREP" || continue
# Check for GNU ac_path_EGREP and select it if it is found.
# Check for GNU $ac_path_EGREP
case `"$ac_path_EGREP" --version 2>&1` in
@@ -5215,8 +5247,8 @@
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-# define __EXTENSIONS__ 1
- $ac_includes_default
+# define __EXTENSIONS__ 1
+ $ac_includes_default
int
main ()
{
@@ -5612,7 +5644,7 @@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5652,7 +5684,7 @@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_RANLIB="ranlib"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5707,7 +5739,7 @@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5751,7 +5783,7 @@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_AR="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5815,7 +5847,7 @@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_READELF="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5859,7 +5891,7 @@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_READELF="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5923,7 +5955,7 @@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_HAS_PYTHON="found"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -5996,7 +6028,7 @@
# by default.
for ac_prog in ginstall scoinst install; do
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
if test $ac_prog = install &&
grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
# AIX install. It has an incompatible calling convention.
@@ -6065,7 +6097,7 @@
test -z "$as_dir" && as_dir=.
for ac_prog in mkdir gmkdir; do
for ac_exec_ext in '' $ac_executable_extensions; do
- { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+ as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
'mkdir (GNU coreutils) '* | \
'mkdir (coreutils) '* | \
@@ -8957,7 +8989,7 @@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -9000,7 +9032,7 @@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -10062,6 +10094,128 @@
OPT="-DDYNAMIC_ANNOTATIONS_ENABLED=1 $OPT"
fi
+# Check for dtrace support
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-dtrace" >&5
+$as_echo_n "checking for --with-dtrace... " >&6; }
+
+# Check whether --with-dtrace was given.
+if test "${with_dtrace+set}" = set; then :
+ withval=$with_dtrace;
+fi
+
+
+
+
+
+
+DTRACE=
+DFLAGS=
+if test ! -z "$with_dtrace"
+then
+ DTRACE_NM=OTHER
+ DTRACE_LINKER=ld
+ DTRACEOBJS="Python/pydtrace.o"
+ DTRACE=dtrace
+ # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
+$as_echo_n "checking size of long... " >&6; }
+if ${ac_cv_sizeof_long+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (long)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
+$as_echo "$ac_cv_sizeof_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+ if test "$ac_cv_sizeof_long" -eq 8
+ then
+ DFLAGS="-64"
+ else
+ DFLAGS="-32"
+ fi
+ case $ac_sys_system/$ac_sys_release in
+ SunOS/5.10)
+ DTRACE_NM=SOLARIS_10
+ DTRACE_LINKER=/usr/ccs/bin/ld
+
+ ;;
+ Darwin/*)
+ DTRACEOBJS="" # Not needed in Mac
+ # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
+$as_echo_n "checking size of long... " >&6; }
+if ${ac_cv_sizeof_long+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot compute sizeof (long)
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ ac_cv_sizeof_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
+$as_echo "$ac_cv_sizeof_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+ if test "$ac_cv_sizeof_long" -eq 8
+ then
+ DFLAGS="-arch i386"
+ else
+ DFLAGS="-arch x86_64"
+ fi
+ ;;
+ esac
+
+$as_echo "#define WITH_DTRACE 1" >>confdefs.h
+
+ with_dtrace="yes"
+else
+ with_dtrace="no"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_dtrace" >&5
+$as_echo "$with_dtrace" >&6; }
+
+
# -I${DLINCLDIR} is added to the compile rule for importdl.o
DLINCLDIR=.
@@ -10607,7 +10761,7 @@
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_TRUE="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
@@ -12044,7 +12198,8 @@
main ()
{
static int test_array [1 - 2 * !(((char) -1) < 0)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
@@ -12075,11 +12230,11 @@
int
main ()
{
-/* FIXME: Include the comments suggested by Paul. */
+
#ifndef __cplusplus
- /* Ultrix mips cc rejects this. */
+ /* Ultrix mips cc rejects this sort of thing. */
typedef int charset[2];
- const charset cs;
+ const charset cs = { 0, 0 };
/* SunOS 4.1.1 cc rejects this. */
char const *const *pcpcc;
char **ppc;
@@ -12096,8 +12251,9 @@
++pcpcc;
ppc = (char**) pcpcc;
pcpcc = (char const *const *) ppc;
- { /* SCO 3.2v4 cc rejects this. */
- char *t;
+ { /* SCO 3.2v4 cc rejects this sort of thing. */
+ char tx;
+ char *t = &tx;
char const *s = 0 ? (char *) 0 : (char const *) 0;
*t++ = 0;
@@ -12113,10 +12269,10 @@
iptr p = 0;
++p;
}
- { /* AIX XL C 1.02.0.0 rejects this saying
+ { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying
"k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
- struct s { int j; const int *ap[3]; };
- struct s *b; b->j = 5;
+ struct s { int j; const int *ap[3]; } bx;
+ struct s *b = &bx; b->j = 5;
}
{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
const int foo = 10;
@@ -15444,16 +15600,16 @@
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
+ # In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -p'
- fi
-else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
+ fi
+else
+ as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
@@ -15513,28 +15669,16 @@
as_mkdir_p=false
fi
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in #(
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -15556,7 +15700,7 @@
# values after options handling.
ac_log="
This file was extended by python $as_me 3.3, which was
-generated by GNU Autoconf 2.68. Invocation command line was
+generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
@@ -15618,10 +15762,10 @@
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
python config.status 3.3
-configured by $0, generated by GNU Autoconf 2.68,
+configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
-Copyright (C) 2010 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
@@ -15711,7 +15855,7 @@
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
if \$ac_cs_recheck; then
- set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
shift
\$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
CONFIG_SHELL='$SHELL'
diff -r f0955d95ac02 -r d12ded643482 configure.ac
--- a/configure.ac Mon Jul 02 13:54:33 2012 -0700
+++ b/configure.ac Tue Jul 03 03:43:34 2012 +0200
@@ -2675,6 +2675,57 @@
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))
+
+AC_SUBST(DTRACE)
+AC_SUBST(DFLAGS)
+AC_SUBST(DTRACE_NM)
+AC_SUBST(DTRACE_LINKER)
+DTRACE=
+DFLAGS=
+if test ! -z "$with_dtrace"
+then
+ DTRACE_NM=OTHER
+ DTRACE_LINKER=ld
+ DTRACEOBJS="Python/pydtrace.o"
+ DTRACE=dtrace
+ AC_CHECK_SIZEOF([long])
+ if [test "$ac_cv_sizeof_long" -eq 8]
+ then
+ DFLAGS="-64"
+ else
+ DFLAGS="-32"
+ fi
+ case $ac_sys_system/$ac_sys_release in
+ SunOS/5.10)
+ DTRACE_NM=SOLARIS_10
+ DTRACE_LINKER=/usr/ccs/bin/ld
+
+ ;;
+ Darwin/*)
+ DTRACEOBJS="" # Not needed in Mac
+ AC_CHECK_SIZEOF([long])
+ if [test "$ac_cv_sizeof_long" -eq 8]
+ then
+ DFLAGS="-arch i386"
+ else
+ DFLAGS="-arch x86_64"
+ fi
+ ;;
+ esac
+ AC_DEFINE(WITH_DTRACE, 1,
+ [Define if you want to compile in Dtrace support])
+ with_dtrace="yes"
+else
+ with_dtrace="no"
+fi
+
+AC_MSG_RESULT($with_dtrace)
+AC_SUBST(DTRACEOBJS)
+
# -I${DLINCLDIR} is added to the compile rule for importdl.o
AC_SUBST(DLINCLDIR)
DLINCLDIR=.
diff -r f0955d95ac02 -r d12ded643482 pyconfig.h.in
--- a/pyconfig.h.in Mon Jul 02 13:54:33 2012 -0700
+++ b/pyconfig.h.in Tue Jul 03 03:43:34 2012 +0200
@@ -1291,6 +1291,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 -r f0955d95ac02 -r d12ded643482 setup.py
--- a/setup.py Mon Jul 02 13:54:33 2012 -0700
+++ b/setup.py Tue Jul 03 03:43:34 2012 +0200
@@ -621,6 +621,9 @@
# syslog daemon interface
exts.append( Extension('syslog', ['syslogmodule.c']) )
+ # jcea DTRACE probes
+ exts.append( Extension('dtrace', ['dtracemodule.c']) )
+
#
# Here ends the simple stuff. From here on, modules need certain
# libraries, are platform-specific, or present other surprises.