Gentoo Archives: gentoo-commits

From: Zac Medico <zmedico@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/portage:master commit in: pym/portage/util/_eventloop/
Date: Wed, 27 Jun 2018 03:06:03
Message-Id: 1530068678.6b50ba69f5a8e311fcddfb2e5c203631bd292c71.zmedico@gentoo
1 commit: 6b50ba69f5a8e311fcddfb2e5c203631bd292c71
2 Author: Zac Medico <zmedico <AT> gentoo <DOT> org>
3 AuthorDate: Thu Jun 21 21:03:38 2018 +0000
4 Commit: Zac Medico <zmedico <AT> gentoo <DOT> org>
5 CommitDate: Wed Jun 27 03:04:38 2018 +0000
6 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=6b50ba69
7
8 AsyncioEventLoop: exit after unhandled exception (bug 658684)
9
10 Fix portage commands to exit immediately for any unhandled
11 exceptions that are raised while the asyncio event loop is running
12 without a tty. If we have a tty then start the debugger,
13 since in might aid in diagnosis of the problem.
14
15 In order to avoid potential interference with API consumers, do not
16 call set_exception_handler unless portage._internal_caller is True.
17
18 Bug: https://bugs.gentoo.org/658684
19
20 pym/portage/util/_eventloop/asyncio_event_loop.py | 31 +++++++++++++++++++++++
21 1 file changed, 31 insertions(+)
22
23 diff --git a/pym/portage/util/_eventloop/asyncio_event_loop.py b/pym/portage/util/_eventloop/asyncio_event_loop.py
24 index c07b71103..ea0e03b23 100644
25 --- a/pym/portage/util/_eventloop/asyncio_event_loop.py
26 +++ b/pym/portage/util/_eventloop/asyncio_event_loop.py
27 @@ -2,7 +2,9 @@
28 # Distributed under the terms of the GNU General Public License v2
29
30 import os
31 +import pdb
32 import signal
33 +import sys
34
35 try:
36 import asyncio as _real_asyncio
37 @@ -53,6 +55,35 @@ class AsyncioEventLoop(_AbstractEventLoop):
38 self.get_debug = loop.get_debug
39 self._wakeup_fd = -1
40
41 + if portage._internal_caller:
42 + loop.set_exception_handler(self._internal_caller_exception_handler)
43 +
44 + @staticmethod
45 + def _internal_caller_exception_handler(loop, context):
46 + """
47 + An exception handler which drops to a pdb shell if std* streams
48 + refer to a tty, and otherwise kills the process with SIGTERM.
49 +
50 + In order to avoid potential interference with API consumers, this
51 + implementation is only used when portage._internal_caller is True.
52 + """
53 + loop.default_exception_handler(context)
54 + if 'exception' in context:
55 + # If we have a tty then start the debugger, since in might
56 + # aid in diagnosis of the problem. If there's no tty, then
57 + # exit immediately.
58 + if all(s.isatty() for s in (sys.stdout, sys.stderr, sys.stdin)):
59 + pdb.set_trace()
60 + else:
61 + # Normally emerge will wait for all coroutines to complete
62 + # after SIGTERM has been received. However, an unhandled
63 + # exception will prevent the interrupted coroutine from
64 + # completing, therefore use the default SIGTERM handler
65 + # in order to ensure that emerge exits immediately (though
66 + # uncleanly).
67 + signal.signal(signal.SIGTERM, signal.SIG_DFL)
68 + os.kill(os.getpid(), signal.SIGTERM)
69 +
70 def _create_future(self):
71 """
72 Provide AbstractEventLoop.create_future() for python3.4.