diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py
new file mode 100644
index 0000000..df8c56f
--- /dev/null
+++ b/Lib/test/test_sys_settrace.py
@@ -0,0 +1,789 @@
+# Testing the line trace facility.
+
+from test import test_support
+import unittest
+import sys
+import difflib
+import gc
+
+# A very basic example.  If this fails, we're in deep trouble.
+def basic():
+    return 1
+
+basic.events = [(0, 'call'),
+                (1, 'line'),
+                (1, 'return')]
+
+# Many of the tests below are tricky because they involve pass statements.
+# If there is implicit control flow around a pass statement (in an except
+# clause or else caluse) under what conditions do you set a line number
+# following that clause?
+
+
+# The entire "while 0:" statement is optimized away.  No code
+# exists for it, so the line numbers skip directly from "del x"
+# to "x = 1".
+def arigo_example():
+    x = 1
+    del x
+    while 0:
+        pass
+    x = 1
+
+arigo_example.events = [(0, 'call'),
+                        (1, 'line'),
+                        (2, 'line'),
+                        (5, 'line'),
+                        (5, 'return')]
+
+# check that lines consisting of just one instruction get traced:
+def one_instr_line():
+    x = 1
+    del x
+    x = 1
+
+one_instr_line.events = [(0, 'call'),
+                         (1, 'line'),
+                         (2, 'line'),
+                         (3, 'line'),
+                         (3, 'return')]
+
+def no_pop_tops():      # 0
+    x = 1               # 1
+    for a in range(2):  # 2
+        if a:           # 3
+            x = 1       # 4
+        else:           # 5
+            x = 1       # 6
+
+no_pop_tops.events = [(0, 'call'),
+                      (1, 'line'),
+                      (2, 'line'),
+                      (3, 'line'),
+                      (6, 'line'),
+                      (2, 'line'),
+                      (3, 'line'),
+                      (4, 'line'),
+                      (2, 'line'),
+                      (2, 'return')]
+
+def no_pop_blocks():
+    y = 1
+    while not y:
+        bla
+    x = 1
+
+no_pop_blocks.events = [(0, 'call'),
+                        (1, 'line'),
+                        (2, 'line'),
+                        (4, 'line'),
+                        (4, 'return')]
+
+def called(): # line -3
+    x = 1
+
+def call():   # line 0
+    called()
+
+call.events = [(0, 'call'),
+               (1, 'line'),
+               (-3, 'call'),
+               (-2, 'line'),
+               (-2, 'return'),
+               (1, 'return')]
+
+def raises():
+    raise Exception
+
+def test_raise():
+    try:
+        raises()
+    except Exception, exc:
+        x = 1
+
+test_raise.events = [(0, 'call'),
+                     (1, 'line'),
+                     (2, 'line'),
+                     (-3, 'call'),
+                     (-2, 'line'),
+                     (-2, 'exception'),
+                     (-2, 'return'),
+                     (2, 'exception'),
+                     (3, 'line'),
+                     (4, 'line'),
+                     (4, 'return')]
+
+def _settrace_and_return(tracefunc):
+    sys.settrace(tracefunc)
+    sys._getframe().f_back.f_trace = tracefunc
+def settrace_and_return(tracefunc):
+    _settrace_and_return(tracefunc)
+
+settrace_and_return.events = [(1, 'return')]
+
+def _settrace_and_raise(tracefunc):
+    sys.settrace(tracefunc)
+    sys._getframe().f_back.f_trace = tracefunc
+    raise RuntimeError
+def settrace_and_raise(tracefunc):
+    try:
+        _settrace_and_raise(tracefunc)
+    except RuntimeError, exc:
+        pass
+
+settrace_and_raise.events = [(2, 'exception'),
+                             (3, 'line'),
+                             (4, 'line'),
+                             (4, 'return')]
+
+# implicit return example
+# This test is interesting because of the else: pass
+# part of the code.  The code generate for the true
+# part of the if contains a jump past the else branch.
+# The compiler then generates an implicit "return None"
+# Internally, the compiler visits the pass statement
+# and stores its line number for use on the next instruction.
+# The next instruction is the implicit return None.
+def ireturn_example():
+    a = 5
+    b = 5
+    if a == b:
+        b = a+1
+    else:
+        pass
+
+ireturn_example.events = [(0, 'call'),
+                          (1, 'line'),
+                          (2, 'line'),
+                          (3, 'line'),
+                          (4, 'line'),
+                          (6, 'line'),
+                          (6, 'return')]
+
+# Tight loop with while(1) example (SF #765624)
+def tightloop_example():
+    items = range(0, 3)
+    try:
+        i = 0
+        while 1:
+            b = items[i]; i+=1
+    except IndexError:
+        pass
+
+tightloop_example.events = [(0, 'call'),
+                            (1, 'line'),
+                            (2, 'line'),
+                            (3, 'line'),
+                            (4, 'line'),
+                            (5, 'line'),
+                            (5, 'line'),
+                            (5, 'line'),
+                            (5, 'line'),
+                            (5, 'exception'),
+                            (6, 'line'),
+                            (7, 'line'),
+                            (7, 'return')]
+
+def tighterloop_example():
+    items = range(1, 4)
+    try:
+        i = 0
+        while 1: i = items[i]
+    except IndexError:
+        pass
+
+tighterloop_example.events = [(0, 'call'),
+                            (1, 'line'),
+                            (2, 'line'),
+                            (3, 'line'),
+                            (4, 'line'),
+                            (4, 'line'),
+                            (4, 'line'),
+                            (4, 'line'),
+                            (4, 'exception'),
+                            (5, 'line'),
+                            (6, 'line'),
+                            (6, 'return')]
+
+def generator_function():
+    try:
+        yield True
+        "continued"
+    finally:
+        "finally"
+def generator_example():
+    # any() will leave the generator before its end
+    x = any(generator_function())
+
+    # the following lines were not traced
+    for x in range(10):
+        y = x
+
+generator_example.events = ([(0, 'call'),
+                             (2, 'line'),
+                             (-6, 'call'),
+                             (-5, 'line'),
+                             (-4, 'line'),
+                             (-4, 'return'),
+                             (-4, 'call'),
+                             (-4, 'exception'),
+                             (-1, 'line'),
+                             (-1, 'return')] +
+                            [(5, 'line'), (6, 'line')] * 10 +
+                            [(5, 'line'), (5, 'return')])
+
+
+class Tracer:
+    def __init__(self):
+        self.events = []
+    def trace(self, frame, event, arg):
+        self.events.append((frame.f_lineno, event))
+        return self.trace
+    def traceWithGenexp(self, frame, event, arg):
+        (o for o in [1])
+        self.events.append((frame.f_lineno, event))
+        return self.trace
+
+class TraceTestCase(unittest.TestCase):
+
+    # Disable gc collection when tracing, otherwise the
+    # deallocators may be traced as well.
+    def setUp(self):
+        self.using_gc = gc.isenabled()
+        gc.disable()
+
+    def tearDown(self):
+        if self.using_gc:
+            gc.enable()
+
+    def compare_events(self, line_offset, events, expected_events):
+        events = [(l - line_offset, e) for (l, e) in events]
+        if events != expected_events:
+            self.fail(
+                "events did not match expectation:\n" +
+                "\n".join(difflib.ndiff([str(x) for x in expected_events],
+                                        [str(x) for x in events])))
+
+    def run_and_compare(self, func, events):
+        tracer = Tracer()
+        sys.settrace(tracer.trace)
+        func()
+        sys.settrace(None)
+        self.compare_events(func.func_code.co_firstlineno,
+                            tracer.events, events)
+
+    def run_test(self, func):
+        self.run_and_compare(func, func.events)
+
+    def run_test2(self, func):
+        tracer = Tracer()
+        func(tracer.trace)
+        sys.settrace(None)
+        self.compare_events(func.func_code.co_firstlineno,
+                            tracer.events, func.events)
+
+    def set_and_retrieve_none(self):
+        sys.settrace(None)
+        assert sys.gettrace() is None
+
+    def set_and_retrieve_func(self):
+        def fn(*args):
+            pass
+
+        sys.settrace(fn)
+        try:
+            assert sys.gettrace() is fn
+        finally:
+            sys.settrace(None)
+
+    def test_01_basic(self):
+        self.run_test(basic)
+    def test_02_arigo(self):
+        self.run_test(arigo_example)
+    def test_03_one_instr(self):
+        self.run_test(one_instr_line)
+    def test_04_no_pop_blocks(self):
+        self.run_test(no_pop_blocks)
+    def test_05_no_pop_tops(self):
+        self.run_test(no_pop_tops)
+    def test_06_call(self):
+        self.run_test(call)
+    def test_07_raise(self):
+        self.run_test(test_raise)
+
+    def test_08_settrace_and_return(self):
+        self.run_test2(settrace_and_return)
+    def test_09_settrace_and_raise(self):
+        self.run_test2(settrace_and_raise)
+    def test_10_ireturn(self):
+        self.run_test(ireturn_example)
+    def test_11_tightloop(self):
+        self.run_test(tightloop_example)
+    def test_12_tighterloop(self):
+        self.run_test(tighterloop_example)
+
+    def test_13_genexp(self):
+        self.run_test(generator_example)
+        # issue1265: if the trace function contains a generator,
+        # and if the traced function contains another generator
+        # that is not completely exhausted, the trace stopped.
+        # Worse: the 'finally' clause was not invoked.
+        tracer = Tracer()
+        sys.settrace(tracer.traceWithGenexp)
+        generator_example()
+        sys.settrace(None)
+        self.compare_events(generator_example.__code__.co_firstlineno,
+                            tracer.events, generator_example.events)
+
+    def test_14_onliner_if(self):
+        def onliners():
+            if True: False
+            else: True
+            return 0
+        self.run_and_compare(
+            onliners,
+            [(0, 'call'),
+             (1, 'line'),
+             (3, 'line'),
+             (3, 'return')])
+
+    def test_15_loops(self):
+        # issue1750076: "while" expression is skipped by debugger
+        def for_example():
+            for x in range(2):
+                pass
+        self.run_and_compare(
+            for_example,
+            [(0, 'call'),
+             (1, 'line'),
+             (2, 'line'),
+             (1, 'line'),
+             (2, 'line'),
+             (1, 'line'),
+             (1, 'return')])
+
+        def while_example():
+            # While expression should be traced on every loop
+            x = 2
+            while x > 0:
+                x -= 1
+        self.run_and_compare(
+            while_example,
+            [(0, 'call'),
+             (2, 'line'),
+             (3, 'line'),
+             (4, 'line'),
+             (3, 'line'),
+             (4, 'line'),
+             (3, 'line'),
+             (3, 'return')])
+
+    def test_16_blank_lines(self):
+        exec("def f():\n" + "\n" * 256 + "    pass")
+        self.run_and_compare(
+            f,
+            [(0, 'call'),
+             (257, 'line'),
+             (257, 'return')])
+
+
+class RaisingTraceFuncTestCase(unittest.TestCase):
+    def trace(self, frame, event, arg):
+        """A trace function that raises an exception in response to a
+        specific trace event."""
+        if event == self.raiseOnEvent:
+            raise ValueError # just something that isn't RuntimeError
+        else:
+            return self.trace
+
+    def f(self):
+        """The function to trace; raises an exception if that's the case
+        we're testing, so that the 'exception' trace event fires."""
+        if self.raiseOnEvent == 'exception':
+            x = 0
+            y = 1 // x
+        else:
+            return 1
+
+    def run_test_for_event(self, event):
+        """Tests that an exception raised in response to the given event is
+        handled OK."""
+        self.raiseOnEvent = event
+        try:
+            for i in xrange(sys.getrecursionlimit() + 1):
+                sys.settrace(self.trace)
+                try:
+                    self.f()
+                except ValueError:
+                    pass
+                else:
+                    self.fail("exception not thrown!")
+        except RuntimeError:
+            self.fail("recursion counter not reset")
+
+    # Test the handling of exceptions raised by each kind of trace event.
+    def test_call(self):
+        self.run_test_for_event('call')
+    def test_line(self):
+        self.run_test_for_event('line')
+    def test_return(self):
+        self.run_test_for_event('return')
+    def test_exception(self):
+        self.run_test_for_event('exception')
+
+    def test_trash_stack(self):
+        def f():
+            for i in range(5):
+                print i  # line tracing will raise an exception at this line
+
+        def g(frame, why, extra):
+            if (why == 'line' and
+                frame.f_lineno == f.func_code.co_firstlineno + 2):
+                raise RuntimeError, "i am crashing"
+            return g
+
+        sys.settrace(g)
+        try:
+            f()
+        except RuntimeError:
+            # the test is really that this doesn't segfault:
+            import gc
+            gc.collect()
+        else:
+            self.fail("exception not propagated")
+
+
+# 'Jump' tests: assigning to frame.f_lineno within a trace function
+# moves the execution position - it's how debuggers implement a Jump
+# command (aka. "Set next statement").
+
+class JumpTracer:
+    """Defines a trace function that jumps from one place to another,
+    with the source and destination lines of the jump being defined by
+    the 'jump' property of the function under test."""
+
+    def __init__(self, function):
+        self.function = function
+        self.jumpFrom = function.jump[0]
+        self.jumpTo = function.jump[1]
+        self.done = False
+
+    def trace(self, frame, event, arg):
+        if not self.done and frame.f_code == self.function.func_code:
+            firstLine = frame.f_code.co_firstlineno
+            if event == 'line' and frame.f_lineno == firstLine + self.jumpFrom:
+                # Cope with non-integer self.jumpTo (because of
+                # no_jump_to_non_integers below).
+                try:
+                    frame.f_lineno = firstLine + self.jumpTo
+                except TypeError:
+                    frame.f_lineno = self.jumpTo
+                self.done = True
+        return self.trace
+
+# The first set of 'jump' tests are for things that are allowed:
+
+def jump_simple_forwards(output):
+    output.append(1)
+    output.append(2)
+    output.append(3)
+
+jump_simple_forwards.jump = (1, 3)
+jump_simple_forwards.output = [3]
+
+def jump_simple_backwards(output):
+    output.append(1)
+    output.append(2)
+
+jump_simple_backwards.jump = (2, 1)
+jump_simple_backwards.output = [1, 1, 2]
+
+def jump_out_of_block_forwards(output):
+    for i in 1, 2:
+        output.append(2)
+        for j in [3]:  # Also tests jumping over a block
+            output.append(4)
+    output.append(5)
+
+jump_out_of_block_forwards.jump = (3, 5)
+jump_out_of_block_forwards.output = [2, 5]
+
+def jump_out_of_block_backwards(output):
+    output.append(1)
+    for i in [1]:
+        output.append(3)
+        for j in [2]:  # Also tests jumping over a block
+            output.append(5)
+        output.append(6)
+    output.append(7)
+
+jump_out_of_block_backwards.jump = (6, 1)
+jump_out_of_block_backwards.output = [1, 3, 5, 1, 3, 5, 6, 7]
+
+def jump_to_codeless_line(output):
+    output.append(1)
+    # Jumping to this line should skip to the next one.
+    output.append(3)
+
+jump_to_codeless_line.jump = (1, 2)
+jump_to_codeless_line.output = [3]
+
+def jump_to_same_line(output):
+    output.append(1)
+    output.append(2)
+    output.append(3)
+
+jump_to_same_line.jump = (2, 2)
+jump_to_same_line.output = [1, 2, 3]
+
+# Tests jumping within a finally block, and over one.
+def jump_in_nested_finally(output):
+    try:
+        output.append(2)
+    finally:
+        output.append(4)
+        try:
+            output.append(6)
+        finally:
+            output.append(8)
+        output.append(9)
+
+jump_in_nested_finally.jump = (4, 9)
+jump_in_nested_finally.output = [2, 9]
+
+# The second set of 'jump' tests are for things that are not allowed:
+
+def no_jump_too_far_forwards(output):
+    try:
+        output.append(2)
+        output.append(3)
+    except ValueError, e:
+        output.append('after' in str(e))
+
+no_jump_too_far_forwards.jump = (3, 6)
+no_jump_too_far_forwards.output = [2, True]
+
+def no_jump_too_far_backwards(output):
+    try:
+        output.append(2)
+        output.append(3)
+    except ValueError, e:
+        output.append('before' in str(e))
+
+no_jump_too_far_backwards.jump = (3, -1)
+no_jump_too_far_backwards.output = [2, True]
+
+# Test each kind of 'except' line.
+def no_jump_to_except_1(output):
+    try:
+        output.append(2)
+    except:
+        e = sys.exc_info()[1]
+        output.append('except' in str(e))
+
+no_jump_to_except_1.jump = (2, 3)
+no_jump_to_except_1.output = [True]
+
+def no_jump_to_except_2(output):
+    try:
+        output.append(2)
+    except ValueError:
+        e = sys.exc_info()[1]
+        output.append('except' in str(e))
+
+no_jump_to_except_2.jump = (2, 3)
+no_jump_to_except_2.output = [True]
+
+def no_jump_to_except_3(output):
+    try:
+        output.append(2)
+    except ValueError, e:
+        output.append('except' in str(e))
+
+no_jump_to_except_3.jump = (2, 3)
+no_jump_to_except_3.output = [True]
+
+def no_jump_to_except_4(output):
+    try:
+        output.append(2)
+    except (ValueError, RuntimeError), e:
+        output.append('except' in str(e))
+
+no_jump_to_except_4.jump = (2, 3)
+no_jump_to_except_4.output = [True]
+
+def no_jump_forwards_into_block(output):
+    try:
+        output.append(2)
+        for i in 1, 2:
+            output.append(4)
+    except ValueError, e:
+        output.append('into' in str(e))
+
+no_jump_forwards_into_block.jump = (2, 4)
+no_jump_forwards_into_block.output = [True]
+
+def no_jump_backwards_into_block(output):
+    try:
+        for i in 1, 2:
+            output.append(3)
+        output.append(4)
+    except ValueError, e:
+        output.append('into' in str(e))
+
+no_jump_backwards_into_block.jump = (4, 3)
+no_jump_backwards_into_block.output = [3, 3, True]
+
+def no_jump_into_finally_block(output):
+    try:
+        try:
+            output.append(3)
+            x = 1
+        finally:
+            output.append(6)
+    except ValueError, e:
+        output.append('finally' in str(e))
+
+no_jump_into_finally_block.jump = (4, 6)
+no_jump_into_finally_block.output = [3, 6, True]  # The 'finally' still runs
+
+def no_jump_out_of_finally_block(output):
+    try:
+        try:
+            output.append(3)
+        finally:
+            output.append(5)
+            output.append(6)
+    except ValueError, e:
+        output.append('finally' in str(e))
+
+no_jump_out_of_finally_block.jump = (5, 1)
+no_jump_out_of_finally_block.output = [3, True]
+
+# This verifies the line-numbers-must-be-integers rule.
+def no_jump_to_non_integers(output):
+    try:
+        output.append(2)
+    except ValueError, e:
+        output.append('integer' in str(e))
+
+no_jump_to_non_integers.jump = (2, "Spam")
+no_jump_to_non_integers.output = [True]
+
+# This verifies that you can't set f_lineno via _getframe or similar
+# trickery.
+def no_jump_without_trace_function():
+    try:
+        previous_frame = sys._getframe().f_back
+        previous_frame.f_lineno = previous_frame.f_lineno
+    except ValueError, e:
+        # This is the exception we wanted; make sure the error message
+        # talks about trace functions.
+        if 'trace' not in str(e):
+            raise
+    else:
+        # Something's wrong - the expected exception wasn't raised.
+        raise RuntimeError, "Trace-function-less jump failed to fail"
+
+
+class JumpTestCase(unittest.TestCase):
+    def compare_jump_output(self, expected, received):
+        if received != expected:
+            self.fail( "Outputs don't match:\n" +
+                       "Expected: " + repr(expected) + "\n" +
+                       "Received: " + repr(received))
+
+    def run_test(self, func):
+        tracer = JumpTracer(func)
+        sys.settrace(tracer.trace)
+        output = []
+        func(output)
+        sys.settrace(None)
+        self.compare_jump_output(func.output, output)
+
+    def test_01_jump_simple_forwards(self):
+        self.run_test(jump_simple_forwards)
+    def test_02_jump_simple_backwards(self):
+        self.run_test(jump_simple_backwards)
+    def test_03_jump_out_of_block_forwards(self):
+        self.run_test(jump_out_of_block_forwards)
+    def test_04_jump_out_of_block_backwards(self):
+        self.run_test(jump_out_of_block_backwards)
+    def test_05_jump_to_codeless_line(self):
+        self.run_test(jump_to_codeless_line)
+    def test_06_jump_to_same_line(self):
+        self.run_test(jump_to_same_line)
+    def test_07_jump_in_nested_finally(self):
+        self.run_test(jump_in_nested_finally)
+    def test_08_no_jump_too_far_forwards(self):
+        self.run_test(no_jump_too_far_forwards)
+    def test_09_no_jump_too_far_backwards(self):
+        self.run_test(no_jump_too_far_backwards)
+    def test_10_no_jump_to_except_1(self):
+        self.run_test(no_jump_to_except_1)
+    def test_11_no_jump_to_except_2(self):
+        self.run_test(no_jump_to_except_2)
+    def test_12_no_jump_to_except_3(self):
+        self.run_test(no_jump_to_except_3)
+    def test_13_no_jump_to_except_4(self):
+        self.run_test(no_jump_to_except_4)
+    def test_14_no_jump_forwards_into_block(self):
+        self.run_test(no_jump_forwards_into_block)
+    def test_15_no_jump_backwards_into_block(self):
+        self.run_test(no_jump_backwards_into_block)
+    def test_16_no_jump_into_finally_block(self):
+        self.run_test(no_jump_into_finally_block)
+    def test_17_no_jump_out_of_finally_block(self):
+        self.run_test(no_jump_out_of_finally_block)
+    def test_18_no_jump_to_non_integers(self):
+        self.run_test(no_jump_to_non_integers)
+    def test_19_no_jump_without_trace_function(self):
+        no_jump_without_trace_function()
+
+    def test_20_large_function(self):
+        d = {}
+        exec("""def f(output):        # line 0
+            x = 0                     # line 1
+            y = 1                     # line 2
+            '''                       # line 3
+            %s                        # lines 4-1004
+            '''                       # line 1005
+            x += 1                    # line 1006
+            output.append(x)          # line 1007
+            return""" % ('\n' * 1000,), d)
+        f = d['f']
+
+        f.jump = (2, 1007)
+        f.output = [0]
+        self.run_test(f)
+
+    def test_jump_to_firstlineno(self):
+        # This tests that PDB can jump back to the first line in a
+        # file.  See issue #1689458.  It can only be triggered in a
+        # function call if the function is defined on a single line.
+        code = compile("""
+# Comments don't count.
+output.append(2)  # firstlineno is here.
+output.append(3)
+output.append(4)
+""", "<fake module>", "exec")
+        class fake_function:
+            func_code = code
+            jump = (2, 0)
+        tracer = JumpTracer(fake_function)
+        sys.settrace(tracer.trace)
+        namespace = {"output": []}
+        exec code in namespace
+        sys.settrace(None)
+        self.compare_jump_output([2, 3, 2, 3, 4], namespace["output"])
+
+
+def test_main():
+    test_support.run_unittest(
+        TraceTestCase,
+        RaisingTraceFuncTestCase,
+        JumpTestCase
+    )
+
+if __name__ == "__main__":
+    test_main()
