You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@impala.apache.org by mi...@apache.org on 2024/08/02 18:14:05 UTC
(impala) 04/04: IMPALA-13230: Dump stacktrace for impala-shell when it receives SIGUSR1
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 <jo...@cloudera.com>
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 <wy...@gmail.com>
Tested-by: Impala Public Jenkins <im...@cloudera.com>
Reviewed-by: Michael Smith <mi...@cloudera.com>
---
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"""