This is an automated email from the ASF dual-hosted git repository. michaelsmith pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/impala.git
commit 2b98e5fb95d9e892518af80af76b56992a8a6006 Author: Joe McDonnell <[email protected]> AuthorDate: Wed Jul 24 13:06:43 2024 -0700 IMPALA-13230: Dump stacktrace for impala-shell when it receives SIGUSR1 It can be useful to get a stacktrace for a running impala-shell for debugging. This uses Python 3's faulthandler to handle the SIGUSR1, so it prints a stacktrace for all threads when it receives SIGUSR1. This does not implement an equivalent functionality for Python 2. Python 2 doesn't have the faulthandler library, and hand tests showed that sending SIGUSR1 to Python 2 impala-shell can interrupt network calls and abort a running query. Testing: - Added a test that verifies the stacktrace is printed and a running query succeeds. Change-Id: If7dae2686b65a1a4f02488abadca3b3c90e48bf1 Reviewed-on: http://gerrit.cloudera.org:8080/21611 Reviewed-by: Yida Wu <[email protected]> Tested-by: Impala Public Jenkins <[email protected]> Reviewed-by: Michael Smith <[email protected]> --- shell/impala_shell.py | 7 +++++++ tests/shell/test_shell_interactive.py | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/shell/impala_shell.py b/shell/impala_shell.py index 7998fce53..6b76d260a 100755 --- a/shell/impala_shell.py +++ b/shell/impala_shell.py @@ -325,6 +325,13 @@ class ImpalaShell(cmd.Cmd, object): # requests between the handler and the main shell thread. signal.signal(signal.SIGINT, self._signal_handler) + # For debugging, it is useful to be able to get stacktraces from a running shell. + # When using Python 3, this hooks up Python 3's faulthandler to handle SIGUSR1. + # It will print stacktraces for all threads when receiving SIGUSR1. + if sys.version_info.major > 2: + import faulthandler + faulthandler.register(signal.SIGUSR1) + def __enter__(self): return self diff --git a/tests/shell/test_shell_interactive.py b/tests/shell/test_shell_interactive.py index 52b56af27..1d4fc121f 100755 --- a/tests/shell/test_shell_interactive.py +++ b/tests/shell/test_shell_interactive.py @@ -346,6 +346,25 @@ class TestImpalaShellInteractive(ImpalaTestSuite): result = p.get_result() assert "^C" in result.stderr + def test_sigusr1_stacktraces(self, vector): + if vector.get_value('strict_hs2_protocol'): + pytest.skip("Strict HS2 mode doesn't support sleep() function") + if vector.get_value('impala_shell') in ['dev', 'python2']: + pytest.skip("Python 2 doesn't support faulthandler") + command = "select sleep(5000); quit;" + p = ImpalaShell(vector) + p.send_cmd(command) + sleep(2) + os.kill(p.pid(), signal.SIGUSR1) + result = p.get_result() + # The stacktrace is printed to stderr. The main thread starts in impala_shell_main, + # so we expect that to be present. + assert "Current thread" in result.stderr, result.stderr + assert "impala_shell_main" in result.stderr, result.stderr + # The SIGUSR1 doesn't harm the running query. + assert "Fetched 1 row(s)" in result.stderr, result.stderr + assert result.rc == 0, result.stderr + @pytest.mark.execute_serially def test_cancellation_mid_command(self, vector): """Test that keyboard interrupt cancels multiline query strings"""
