[Lldb-commits] [lldb] [lldb-dap] Adding exception handling for dap server disconnect and terminations in lldbdap_testcase.py (PR #155335)
Piyush Jaiswal via lldb-commits
lldb-commits at lists.llvm.org
Fri Aug 29 11:56:04 PDT 2025
https://github.com/piyushjaiswal98 updated https://github.com/llvm/llvm-project/pull/155335
>From 443c2b4c983399fce0ac6805abfa7ca2fffd1322 Mon Sep 17 00:00:00 2001
From: Piyush Jaiswal <piyushjais at meta.com>
Date: Mon, 25 Aug 2025 17:31:45 -0700
Subject: [PATCH 1/5] Improving lldbdap server error diagnosability and adding
exception handling
---
.../test/tools/lldb-dap/lldbdap_testcase.py | 28 +++++++++++++++----
1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
index c23b2e73fb45e..8691a87b6fa87 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
@@ -466,8 +466,15 @@ def attach(
# if we throw an exception during the test case.
def cleanup():
if disconnectAutomatically:
- self.dap_server.request_disconnect(terminateDebuggee=True)
- self.dap_server.terminate()
+ try:
+ self.dap_server.request_disconnect(terminateDebuggee=True)
+ except (ValueError, TimeoutError, BrokenPipeError, ConnectionError, Exception) as e:
+ # DAP server might not be responsive, skip disconnect and terminate directly
+ print(f"Warning: disconnect failed ({e}), skipping and terminating directly")
+ try:
+ self.dap_server.terminate()
+ except Exception as e:
+ print(f"Warning: terminate failed ({e}), DAP server may have already died")
# Execute the cleanup function during test case tear down.
self.addTearDownHook(cleanup)
@@ -477,9 +484,20 @@ def cleanup():
if expectFailure:
return response
if not (response and response["success"]):
- self.assertTrue(
- response["success"], "attach failed (%s)" % (response["message"])
- )
+ error_msg = "attach failed"
+ if response:
+ if "message" in response:
+ error_msg += " (%s)" % response["message"]
+ elif "body" in response and "error" in response["body"]:
+ if "format" in response["body"]["error"]:
+ error_msg += " (%s)" % response["body"]["error"]["format"]
+ else:
+ error_msg += " (error in body)"
+ else:
+ error_msg += " (no error details available)"
+ else:
+ error_msg += " (no response)"
+ self.assertTrue(response and response["success"], error_msg)
def launch(
self,
>From 1c68d3f63f020eaea8aceefc015641fa1fa8e801 Mon Sep 17 00:00:00 2001
From: Piyush Jaiswal <piyushjais at meta.com>
Date: Mon, 25 Aug 2025 21:09:59 -0700
Subject: [PATCH 2/5] spliting into 2 PRs and consolidating exeptions
---
.../test/tools/lldb-dap/lldbdap_testcase.py | 19 ++++---------------
1 file changed, 4 insertions(+), 15 deletions(-)
diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
index 8691a87b6fa87..04de3cc6cec0d 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
@@ -468,7 +468,7 @@ def cleanup():
if disconnectAutomatically:
try:
self.dap_server.request_disconnect(terminateDebuggee=True)
- except (ValueError, TimeoutError, BrokenPipeError, ConnectionError, Exception) as e:
+ except Exception as e:
# DAP server might not be responsive, skip disconnect and terminate directly
print(f"Warning: disconnect failed ({e}), skipping and terminating directly")
try:
@@ -484,20 +484,9 @@ def cleanup():
if expectFailure:
return response
if not (response and response["success"]):
- error_msg = "attach failed"
- if response:
- if "message" in response:
- error_msg += " (%s)" % response["message"]
- elif "body" in response and "error" in response["body"]:
- if "format" in response["body"]["error"]:
- error_msg += " (%s)" % response["body"]["error"]["format"]
- else:
- error_msg += " (error in body)"
- else:
- error_msg += " (no error details available)"
- else:
- error_msg += " (no response)"
- self.assertTrue(response and response["success"], error_msg)
+ self.assertTrue(
+ response["success"], "attach failed (%s)" % (response["message"])
+ )
def launch(
self,
>From 6a2c9a79994856eacc1492e6630dc2595b0ff936 Mon Sep 17 00:00:00 2001
From: Piyush Jaiswal <piyushjais at meta.com>
Date: Tue, 26 Aug 2025 11:12:41 -0700
Subject: [PATCH 3/5] Using addTearDownHook and formatting
---
.../test/tools/lldb-dap/lldbdap_testcase.py | 36 ++++++++-----------
1 file changed, 14 insertions(+), 22 deletions(-)
diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
index 04de3cc6cec0d..aef11c42b2cae 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
@@ -450,6 +450,16 @@ def disassemble(self, threadId=None, frameIndex=None):
return disassembled_instructions, disassembled_instructions[memoryReference]
+ def _register_dap_teardown_hooks(self, disconnectAutomatically):
+ """Register teardown hooks to ensure DAP debug adapter is properly cleaned up.
+ Uses separate hooks to ensure terminate() is called even if disconnect() fails.
+ """
+ if disconnectAutomatically:
+ self.addTearDownHook(
+ lambda: self.dap_server.request_disconnect(terminateDebuggee=True)
+ )
+ self.addTearDownHook(lambda: self.dap_server.terminate())
+
def attach(
self,
*,
@@ -464,20 +474,8 @@ def attach(
# Make sure we disconnect and terminate the DAP debug adapter even
# if we throw an exception during the test case.
- def cleanup():
- if disconnectAutomatically:
- try:
- self.dap_server.request_disconnect(terminateDebuggee=True)
- except Exception as e:
- # DAP server might not be responsive, skip disconnect and terminate directly
- print(f"Warning: disconnect failed ({e}), skipping and terminating directly")
- try:
- self.dap_server.terminate()
- except Exception as e:
- print(f"Warning: terminate failed ({e}), DAP server may have already died")
-
- # Execute the cleanup function during test case tear down.
- self.addTearDownHook(cleanup)
+ self._register_dap_teardown_hooks(disconnectAutomatically)
+
# Initialize and launch the program
self.dap_server.request_initialize(sourceInitFile)
response = self.dap_server.request_attach(**kwargs)
@@ -500,14 +498,8 @@ def launch(
"""Sending launch request to dap"""
# Make sure we disconnect and terminate the DAP debug adapter,
- # if we throw an exception during the test case
- def cleanup():
- if disconnectAutomatically:
- self.dap_server.request_disconnect(terminateDebuggee=True)
- self.dap_server.terminate()
-
- # Execute the cleanup function during test case tear down.
- self.addTearDownHook(cleanup)
+ # if we throw an exception during the test case.
+ self._register_dap_teardown_hooks(disconnectAutomatically)
# Initialize and launch the program
self.dap_server.request_initialize(sourceInitFile)
>From e36edb7cc8d2d3fb606047439a0f6968ee4bd167 Mon Sep 17 00:00:00 2001
From: Piyush Jaiswal <piyushjais at meta.com>
Date: Thu, 28 Aug 2025 11:52:06 -0700
Subject: [PATCH 4/5] Reverting to original format
---
.../test/tools/lldb-dap/lldbdap_testcase.py | 24 ++++++++++++-------
1 file changed, 15 insertions(+), 9 deletions(-)
diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
index 68b797d488f7a..ec738789196a0 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
@@ -450,15 +450,21 @@ def disassemble(self, threadId=None, frameIndex=None):
return disassembled_instructions, disassembled_instructions[memoryReference]
- def _register_dap_teardown_hooks(self, disconnectAutomatically):
- """Register teardown hooks to ensure DAP debug adapter is properly cleaned up.
- Uses separate hooks to ensure terminate() is called even if disconnect() fails.
- """
+ def dapCleanup(self, disconnectAutomatically):
if disconnectAutomatically:
- self.addTearDownHook(
- lambda: self.dap_server.request_disconnect(terminateDebuggee=True)
+ try:
+ self.dap_server.request_disconnect(terminateDebuggee=True)
+ except Exception as e:
+ # DAP server might not be responsive, skip disconnect and terminate directly
+ print(
+ f"Warning: disconnect failed ({e}), skipping and terminating directly"
+ )
+ try:
+ self.dap_server.terminate()
+ except Exception as e:
+ print(
+ f"Warning: terminate failed ({e}), DAP server may have already died"
)
- self.addTearDownHook(lambda: self.dap_server.terminate())
def _build_error_message(self, base_message, response):
"""Build a detailed error message from a DAP response.
@@ -493,7 +499,7 @@ def attach(
# Make sure we disconnect and terminate the DAP debug adapter even
# if we throw an exception during the test case.
- self._register_dap_teardown_hooks(disconnectAutomatically)
+ self.addTearDownHook(lambda: self.dapCleanup(disconnectAutomatically))
# Initialize and launch the program
self.dap_server.request_initialize(sourceInitFile)
@@ -517,7 +523,7 @@ def launch(
# Make sure we disconnect and terminate the DAP debug adapter,
# if we throw an exception during the test case.
- self._register_dap_teardown_hooks(disconnectAutomatically)
+ self.addTearDownHook(lambda: self.dapCleanup(disconnectAutomatically))
# Initialize and launch the program
self.dap_server.request_initialize(sourceInitFile)
>From 68eddcb0628c6e8883746f29e87c9bc3d390da9a Mon Sep 17 00:00:00 2001
From: Piyush Jaiswal <piyushjais at meta.com>
Date: Thu, 28 Aug 2025 13:04:06 -0700
Subject: [PATCH 5/5] Format document
---
.../Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
index ec738789196a0..b926e43b962e7 100644
--- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
+++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py
@@ -462,9 +462,7 @@ def dapCleanup(self, disconnectAutomatically):
try:
self.dap_server.terminate()
except Exception as e:
- print(
- f"Warning: terminate failed ({e}), DAP server may have already died"
- )
+ print(f"Warning: terminate failed ({e}), DAP server may have already died")
def _build_error_message(self, base_message, response):
"""Build a detailed error message from a DAP response.
More information about the lldb-commits
mailing list