From c8af302c3af0abb5bfd65ece24de36154937c642 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 22 Nov 2016 22:53:18 +0100 Subject: Issue #28770: Update python-gdb.py for fastcalls Frame.is_other_python_frame() now also handles _PyCFunction_FastCallDict() frames. Thanks to the new code to handle fast calls, python-gdb.py is now also able to detect the frame. (grafted from f41d02d7da373ccaff97a42b66b051260bd55996) --- Lib/test/test_gdb.py | 20 ++++++++++---------- Tools/gdb/libpython.py | 47 +++++++++++++++++++++++++++++++---------------- 2 files changed, 41 insertions(+), 26 deletions(-) diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py index 2bd4457..60f1d92 100644 --- a/Lib/test/test_gdb.py +++ b/Lib/test/test_gdb.py @@ -679,7 +679,7 @@ class StackNavigationTests(DebuggerTests): def test_pyup_command(self): 'Verify that the "py-up" command works' bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-up']) + cmds_after_breakpoint=['py-up', 'py-up']) self.assertMultilineMatches(bt, r'''^.* #[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 7, in bar \(a=1, b=2, c=3\) @@ -698,7 +698,7 @@ $''') def test_up_at_top(self): 'Verify handling of "py-up" at the top of the stack' bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-up'] * 4) + cmds_after_breakpoint=['py-up'] * 5) self.assertEndsWith(bt, 'Unable to find an older python frame\n') @@ -708,7 +708,7 @@ $''') def test_up_then_down(self): 'Verify "py-up" followed by "py-down"' bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-up', 'py-down']) + cmds_after_breakpoint=['py-up', 'py-up', 'py-down']) self.assertMultilineMatches(bt, r'''^.* #[0-9]+ Frame 0x-?[0-9a-f]+, for file .*gdb_sample.py, line 7, in bar \(a=1, b=2, c=3\) @@ -727,6 +727,7 @@ class PyBtTests(DebuggerTests): self.assertMultilineMatches(bt, r'''^.* Traceback \(most recent call first\): + File ".*gdb_sample.py", line 10, in baz id\(42\) File ".*gdb_sample.py", line 7, in bar @@ -815,7 +816,6 @@ id(42) ) self.assertIn('Garbage-collecting', gdb_output) - @unittest.skip("FIXME: builtin method is not shown in py-bt and py-bt-full") @unittest.skipIf(python_is_optimized(), "Python was compiled with optimizations") # Some older versions of gdb will fail with @@ -854,7 +854,7 @@ class PyPrintTests(DebuggerTests): def test_basic_command(self): 'Verify that the "py-print" command works' bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-print args']) + cmds_after_breakpoint=['py-up', 'py-print args']) self.assertMultilineMatches(bt, r".*\nlocal 'args' = \(1, 2, 3\)\n.*") @@ -863,7 +863,7 @@ class PyPrintTests(DebuggerTests): @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands") def test_print_after_up(self): bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-up', 'py-print c', 'py-print b', 'py-print a']) + cmds_after_breakpoint=['py-up', 'py-up', 'py-print c', 'py-print b', 'py-print a']) self.assertMultilineMatches(bt, r".*\nlocal 'c' = 3\nlocal 'b' = 2\nlocal 'a' = 1\n.*") @@ -871,7 +871,7 @@ class PyPrintTests(DebuggerTests): "Python was compiled with optimizations") def test_printing_global(self): bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-print __name__']) + cmds_after_breakpoint=['py-up', 'py-print __name__']) self.assertMultilineMatches(bt, r".*\nglobal '__name__' = '__main__'\n.*") @@ -879,7 +879,7 @@ class PyPrintTests(DebuggerTests): "Python was compiled with optimizations") def test_printing_builtin(self): bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-print len']) + cmds_after_breakpoint=['py-up', 'py-print len']) self.assertMultilineMatches(bt, r".*\nbuiltin 'len' = \n.*") @@ -888,7 +888,7 @@ class PyLocalsTests(DebuggerTests): "Python was compiled with optimizations") def test_basic_command(self): bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-locals']) + cmds_after_breakpoint=['py-up', 'py-locals']) self.assertMultilineMatches(bt, r".*\nargs = \(1, 2, 3\)\n.*") @@ -897,7 +897,7 @@ class PyLocalsTests(DebuggerTests): "Python was compiled with optimizations") def test_locals_after_up(self): bt = self.get_stack_trace(script=self.get_sample_script(), - cmds_after_breakpoint=['py-up', 'py-locals']) + cmds_after_breakpoint=['py-up', 'py-up', 'py-locals']) self.assertMultilineMatches(bt, r".*\na = 1\nb = 2\nc = 3\n.*") diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index e4d2c1e..798b062 100755 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -1492,23 +1492,38 @@ class Frame(object): ''' if self.is_waiting_for_gil(): return 'Waiting for the GIL' - elif self.is_gc_collect(): + + if self.is_gc_collect(): return 'Garbage-collecting' - else: - # Detect invocations of PyCFunction instances: - older = self.older() - if older and older._gdbframe.name() == 'PyCFunction_Call': - # Within that frame: - # "func" is the local containing the PyObject* of the - # PyCFunctionObject instance - # "f" is the same value, but cast to (PyCFunctionObject*) - # "self" is the (PyObject*) of the 'self' - try: - # Use the prettyprinter for the func: - func = older._gdbframe.read_var('func') - return str(func) - except RuntimeError: - return 'PyCFunction invocation (unable to read "func")' + + # Detect invocations of PyCFunction instances: + older = self.older() + if not older: + return False + + caller = older._gdbframe.name() + if not caller: + return False + + if caller == 'PyCFunction_Call': + # Within that frame: + # "func" is the local containing the PyObject* of the + # PyCFunctionObject instance + # "f" is the same value, but cast to (PyCFunctionObject*) + # "self" is the (PyObject*) of the 'self' + try: + # Use the prettyprinter for the func: + func = older._gdbframe.read_var('func') + return str(func) + except RuntimeError: + return 'PyCFunction invocation (unable to read "func")' + + elif caller == '_PyCFunction_FastCallDict': + try: + func = older._gdbframe.read_var('func_obj') + return str(func) + except RuntimeError: + return 'PyCFunction invocation (unable to read "func_obj")' # This frame isn't worth reporting: return False -- cgit v0.12 From 7ae5c9691b6bdc3516063667345563a010758ce3 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Fri, 16 Dec 2016 11:51:57 -0500 Subject: Merge 3.5 (issue #28990) --- Lib/asyncio/sslproto.py | 1 + Lib/test/test_asyncio/test_sslproto.py | 10 ++++++++++ Misc/NEWS | 4 ++++ 3 files changed, 15 insertions(+) diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py index 991c77b..7ad28d6 100644 --- a/Lib/asyncio/sslproto.py +++ b/Lib/asyncio/sslproto.py @@ -480,6 +480,7 @@ class SSLProtocol(protocols.Protocol): self._loop.call_soon(self._app_protocol.connection_lost, exc) self._transport = None self._app_transport = None + self._wakeup_waiter(exc) def pause_writing(self): """Called when the low-level transport's buffer goes over diff --git a/Lib/test/test_asyncio/test_sslproto.py b/Lib/test/test_asyncio/test_sslproto.py index 0ca6d1b..59ff0f6 100644 --- a/Lib/test/test_asyncio/test_sslproto.py +++ b/Lib/test/test_asyncio/test_sslproto.py @@ -85,5 +85,15 @@ class SslProtoHandshakeTests(test_utils.TestCase): # Restore error logging. log.logger.setLevel(log_level) + def test_connection_lost(self): + # From issue #472. + # yield from waiter hang if lost_connection was called. + waiter = asyncio.Future(loop=self.loop) + ssl_proto = self.ssl_protocol(waiter) + self.connection_made(ssl_proto) + ssl_proto.connection_lost(ConnectionAbortedError) + test_utils.run_briefly(self.loop) + self.assertIsInstance(waiter.exception(), ConnectionAbortedError) + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS b/Misc/NEWS index 5cf929f..dc8acc8 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -14,6 +14,10 @@ Core and Builtins must not convert combined table into split table. Patch written by INADA Naoki. +- Issue #28990: Fix SSL hanging if connection is closed before handshake + completed. + (Patch by HoHo-Ho) + Windows ------- -- cgit v0.12 From f6105a55cf148281105c5e5116560976a2e33677 Mon Sep 17 00:00:00 2001 From: Ned Deily Date: Fri, 16 Dec 2016 15:29:12 -0500 Subject: Tidy Misc/NEWS for 3.6.0rc1+ cherrypicks. --- Misc/NEWS | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index dc8acc8..26e3486 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -14,14 +14,18 @@ Core and Builtins must not convert combined table into split table. Patch written by INADA Naoki. -- Issue #28990: Fix SSL hanging if connection is closed before handshake - completed. - (Patch by HoHo-Ho) +- Issue #28990: Fix asynchio SSL hanging if connection is closed before + handshake is completed. (Patch by HoHo-Ho) + +Tools/Demos +----------- + +- Issue #28770: Fix python-gdb.py for fastcalls. Windows ------- -- Issue #28896: Deprecate WindowsRegistryFinder +- Issue #28896: Deprecate WindowsRegistryFinder. Build ----- -- cgit v0.12