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"""

Reply via email to