From: <cg...@us...> - 2008-01-13 09:20:15
|
Revision: 4023 http://jython.svn.sourceforge.net/jython/?rev=4023&view=rev Author: cgroves Date: 2008-01-13 01:20:13 -0800 (Sun, 13 Jan 2008) Log Message: ----------- Merged revisions 4022 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk sans the ThreadStateMapping changes since they just added generics. ........ r4022 | cgroves | 2008-01-13 01:07:10 -0800 (Sun, 13 Jan 2008) | 6 lines Make profilefunc and tracefunc per thread instead of per systemstate to match CPython. From patch #1841378 from paulj_edgewater. Should fix bug #1757127 and bug #1870039 which were both running into this difference in Pydev's debugger. ........ Modified Paths: -------------- branches/Release_2_2maint/jython/src/org/python/core/PyFrame.java branches/Release_2_2maint/jython/src/org/python/core/PySystemState.java branches/Release_2_2maint/jython/src/org/python/core/PyTableCode.java branches/Release_2_2maint/jython/src/org/python/core/PythonTraceFunction.java branches/Release_2_2maint/jython/src/org/python/core/ThreadState.java branches/Release_2_2maint/jython/src/org/python/util/InteractiveInterpreter.java Added Paths: ----------- branches/Release_2_2maint/jython/Lib/test/test_trace_threaded.py Property Changed: ---------------- branches/Release_2_2maint/ Property changes on: branches/Release_2_2maint ___________________________________________________________________ Name: svnmerge-integrated - /trunk:1-3437,3458,3461,3466-3467,3471-3474,3479-3480,3490,3492,3496,3498,3501-3506,3512-3513,3515-3517,3519-3520,3522,3524,3527,3538,3540,3542-3545,3547-3548,3551,3553,3555-3556,3559,3563,3570,3574-3575,3577-3590,3592-3603,3605-3629,3634-3638,3640,3643-3657,3659-3661,3663-3681,3684,3686-3687,3692,3695,3732-3734,3739,3742-3743,3745,3747-3748,3751,3753-3756,3761-3762,3785,3803,3820-3822,3825,3827-3836,3851-3864,3866,3871-3875,3879,3881-3885,3890-3892,3895-3896,3898-3900,3904,3912-3913 + /trunk:1-3437,3458,3461,3466-3467,3471-3474,3479-3480,3490,3492,3496,3498,3501-3506,3512-3513,3515-3517,3519-3520,3522,3524,3527,3538,3540,3542-3545,3547-3548,3551,3553,3555-3556,3559,3563,3570,3574-3575,3577-3590,3592-3603,3605-3629,3634-3638,3640,3643-3657,3659-3661,3663-3681,3684,3686-3687,3692,3695,3732-3734,3739,3742-3743,3745,3747-3748,3751,3753-3756,3761-3762,3785,3803,3820-3822,3825,3827-3836,3851-3864,3866,3871-3875,3879,3881-3885,3890-3892,3895-3896,3898-3900,3904,3912-3913,4022 Copied: branches/Release_2_2maint/jython/Lib/test/test_trace_threaded.py (from rev 4022, trunk/jython/Lib/test/test_trace_threaded.py) =================================================================== --- branches/Release_2_2maint/jython/Lib/test/test_trace_threaded.py (rev 0) +++ branches/Release_2_2maint/jython/Lib/test/test_trace_threaded.py 2008-01-13 09:20:13 UTC (rev 4023) @@ -0,0 +1,58 @@ +import sys +import threading +import time +import unittest + +from test import test_support + +class UntracedThread(threading.Thread): + def __init__(self): + threading.Thread.__init__(self) + + def run(self): + sys.settrace(None) + for i in range(10): + self.untracedcall() + + def untracedcall(self): + pass + +class TracedThread(threading.Thread): + def __init__(self, on_trace): + threading.Thread.__init__(self) + self.on_trace = on_trace + + def trace(self, frame, event, arg): + self.on_trace(frame.f_code.co_name) + + def tracedcall(self): + pass + + def run(self): + sys.settrace(self.trace) + for i in range(10): + self.tracedcall() + +class TracePerThreadTest(unittest.TestCase): + def testTracePerThread(self): + called = [] + def ontrace(co_name): + called.append(str(co_name)) + + untraced = UntracedThread() + traced = TracedThread(ontrace) + untraced.start() + traced.start() + untraced.join() + traced.join() + + self.assertEquals(10, called.count('tracedcall'), + "10 tracedcall should be in %s" % called) + self.assert_('untracedcall' not in called, + "untracedcall shouldn't be in %s" % called) + +def test_main(): + test_support.run_unittest(TracePerThreadTest) + +if __name__ == "__main__": + test_main() Modified: branches/Release_2_2maint/jython/src/org/python/core/PyFrame.java =================================================================== --- branches/Release_2_2maint/jython/src/org/python/core/PyFrame.java 2008-01-13 09:07:10 UTC (rev 4022) +++ branches/Release_2_2maint/jython/src/org/python/core/PyFrame.java 2008-01-13 09:20:13 UTC (rev 4023) @@ -146,6 +146,13 @@ return f_locals; } + // + // Track the current line number. Called by generated code. + // + // This is not to be confused with the CPython method + // frame_setlineno() which causes the interpreter to jump to + // the given line. + // public void setline(int line) { f_lineno = line; if (tracefunc != null) Modified: branches/Release_2_2maint/jython/src/org/python/core/PySystemState.java =================================================================== --- branches/Release_2_2maint/jython/src/org/python/core/PySystemState.java 2008-01-13 09:07:10 UTC (rev 4022) +++ branches/Release_2_2maint/jython/src/org/python/core/PySystemState.java 2008-01-13 09:20:13 UTC (rev 4023) @@ -769,25 +769,22 @@ packageManager.addJarDir(directoryPath, cache); } - public TraceFunction tracefunc = null; - public TraceFunction profilefunc = null; public void settrace(PyObject tracefunc) { - //InterpreterState interp = Py.getThreadState().interp; + ThreadState ts = Py.getThreadState(); if (tracefunc == Py.None) { - this.tracefunc = null; + ts.tracefunc = null; } else { - this.tracefunc = new PythonTraceFunction(tracefunc); + ts.tracefunc = new PythonTraceFunction(tracefunc); } } public void setprofile(PyObject profilefunc) { - //InterpreterState interp = Py.getThreadState().interp; - + ThreadState ts = Py.getThreadState(); if (profilefunc == Py.None) { - this.profilefunc = null; + ts.profilefunc = null; } else { - this.profilefunc = new PythonTraceFunction(profilefunc); + ts.profilefunc = new PythonTraceFunction(profilefunc); } } Modified: branches/Release_2_2maint/jython/src/org/python/core/PyTableCode.java =================================================================== --- branches/Release_2_2maint/jython/src/org/python/core/PyTableCode.java 2008-01-13 09:07:10 UTC (rev 4022) +++ branches/Release_2_2maint/jython/src/org/python/core/PyTableCode.java 2008-01-13 09:20:13 UTC (rev 4023) @@ -167,49 +167,14 @@ ts.frame = frame; // Handle trace function for debugging - PySystemState ss = ts.systemState; - if (ss.tracefunc != null) { - // Jython and CPython differ here. CPython actually lays down - // an extra SET_LINENO bytecode for function definition line. - // This is ostensibly so that a tuple unpacking failure in - // argument passing gets the right line number in the - // traceback. It also means that when tracing a function, - // you'll see two 'line' events, one for the def line and then - // immediately after, one for the first line of the function. - // - // Jython on the other hand only lays down a call in the - // generated Java function to set the line number for the first - // line of the function (i.e. not the def line). This - // difference in behavior doesn't seem to affect arg tuple - // unpacking tracebacks, but it does mean that function tracing - // gives slightly different behavior. Is this bad? Until - // someone complains... no. - // - // The second commented out line fixes this but it is probably - // not the right solution. Better would be to fix the code - // generator to lay down two calls to setline() in the - // classfile. This would allow that call to be optimized out - // when using the -O option. I suppose on the other hand we - // could test that flag here and not call the setline below. - // In either case, it probably doesn't make sense to slow down - // function calling even by this miniscule amount until it's - // shown to have a detrimental effect. - // - // Note also that if you were to print out frame.f_lineno in - // the `call' event handler of your trace function, you'd see - // zero instead of the line of the def. That's what the first - // commented line fixes. - // - // 9-Sep-1999 baw - // -// frame.f_lineno = co_firstlineno; - frame.tracefunc = ss.tracefunc.traceCall(frame); - frame.setline(co_firstlineno); + if (ts.tracefunc != null) { + frame.f_lineno = co_firstlineno; + frame.tracefunc = ts.tracefunc.traceCall(frame); } // Handle trace function for profiling - if (ss.profilefunc != null) { - ss.profilefunc.traceCall(frame); + if (ts.profilefunc != null) { + ts.profilefunc.traceCall(frame); } PyObject ret; @@ -239,8 +204,8 @@ if (frame.tracefunc != null) { frame.tracefunc.traceException(frame, e); } - if (ss.profilefunc != null) { - ss.profilefunc.traceException(frame, e); + if (ts.profilefunc != null) { + ts.profilefunc.traceException(frame, e); } //Rethrow the exception to the next stack frame @@ -253,8 +218,8 @@ frame.tracefunc.traceReturn(frame, ret); } // Handle trace function for profiling - if (ss.profilefunc != null) { - ss.profilefunc.traceReturn(frame, ret); + if (ts.profilefunc != null) { + ts.profilefunc.traceReturn(frame, ret); } // Restore previously defined exception Modified: branches/Release_2_2maint/jython/src/org/python/core/PythonTraceFunction.java =================================================================== --- branches/Release_2_2maint/jython/src/org/python/core/PythonTraceFunction.java 2008-01-13 09:07:10 UTC (rev 4022) +++ branches/Release_2_2maint/jython/src/org/python/core/PythonTraceFunction.java 2008-01-13 09:20:13 UTC (rev 4023) @@ -24,8 +24,8 @@ ret = tracefunc.__call__(frame, new PyString(label), arg); } catch(PyException exc) { frame.tracefunc = null; - ts.systemState.tracefunc = null; - ts.systemState.profilefunc = null; + ts.tracefunc = null; + ts.profilefunc = null; throw exc; } finally { ts.tracing = false; Modified: branches/Release_2_2maint/jython/src/org/python/core/ThreadState.java =================================================================== --- branches/Release_2_2maint/jython/src/org/python/core/ThreadState.java 2008-01-13 09:07:10 UTC (rev 4022) +++ branches/Release_2_2maint/jython/src/org/python/core/ThreadState.java 2008-01-13 09:20:13 UTC (rev 4023) @@ -28,6 +28,9 @@ public int recursion_depth = 0; + public TraceFunction tracefunc; + public TraceFunction profilefunc; + public PyInstance getInitializingProxy() { if (this.initializingProxies == null || this.initializingProxies.empty()) { Modified: branches/Release_2_2maint/jython/src/org/python/util/InteractiveInterpreter.java =================================================================== --- branches/Release_2_2maint/jython/src/org/python/util/InteractiveInterpreter.java 2008-01-13 09:07:10 UTC (rev 4022) +++ branches/Release_2_2maint/jython/src/org/python/util/InteractiveInterpreter.java 2008-01-13 09:20:13 UTC (rev 4023) @@ -118,11 +118,11 @@ **/ public void interrupt(ThreadState ts) { TraceFunction breaker = new BreakTraceFunction(); - TraceFunction oldTrace = ts.systemState.tracefunc; - ts.systemState.tracefunc = breaker; + TraceFunction oldTrace = ts.tracefunc; + ts.tracefunc = breaker; if (ts.frame != null) ts.frame.tracefunc = breaker; - ts.systemState.tracefunc = oldTrace; + ts.tracefunc = oldTrace; //ts.thread.join(); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |