mirror of
https://github.com/intel/llvm.git
synced 2026-01-16 13:35:38 +08:00
[lldb-dap] Correctly trigger 'entry' stop reasons. (#165901)
Noticed this while looking into test stability that the 'entry' stop reason is not triggering correctly. This should ensure we correctly trigger the 'entry' stop reason when launching a process with `"stopOnEntry": true`. I've also updated the tests to ensure we receive the 'entry' stop reason to catch this regression.
This commit is contained in:
@@ -223,6 +223,16 @@ class DAPTestCaseBase(TestBase):
|
||||
return True
|
||||
return False
|
||||
|
||||
def verify_stop_on_entry(self) -> None:
|
||||
"""Waits for the process to be stopped and then verifies at least one
|
||||
thread has the stop reason 'entry'."""
|
||||
self.dap_server.wait_for_stopped()
|
||||
self.assertIn(
|
||||
"entry",
|
||||
(t["reason"] for t in self.dap_server.thread_stop_reasons.values()),
|
||||
"Expected at least one thread to report stop reason 'entry' in {self.dap_server.thread_stop_reasons}",
|
||||
)
|
||||
|
||||
def verify_commands(self, flavor: str, output: str, commands: list[str]):
|
||||
self.assertTrue(output and len(output) > 0, "expect console output")
|
||||
lines = output.splitlines()
|
||||
|
||||
@@ -51,20 +51,8 @@ class TestDAP_restart(lldbdap_testcase.DAPTestCaseBase):
|
||||
self.build_and_launch(program, stopOnEntry=True)
|
||||
[bp_main] = self.set_function_breakpoints(["main"])
|
||||
|
||||
self.dap_server.request_configurationDone()
|
||||
self.dap_server.wait_for_stopped()
|
||||
# Once the "configuration done" event is sent, we should get a stopped
|
||||
# event immediately because of stopOnEntry.
|
||||
self.assertTrue(
|
||||
len(self.dap_server.thread_stop_reasons) > 0,
|
||||
"expected stopped event during launch",
|
||||
)
|
||||
for _, body in self.dap_server.thread_stop_reasons.items():
|
||||
if "reason" in body:
|
||||
reason = body["reason"]
|
||||
self.assertNotEqual(
|
||||
reason, "breakpoint", 'verify stop isn\'t "main" breakpoint'
|
||||
)
|
||||
self.continue_to_next_stop()
|
||||
self.verify_stop_on_entry()
|
||||
|
||||
# Then, if we continue, we should hit the breakpoint at main.
|
||||
self.continue_to_breakpoints([bp_main])
|
||||
@@ -73,17 +61,7 @@ class TestDAP_restart(lldbdap_testcase.DAPTestCaseBase):
|
||||
# main.
|
||||
resp = self.dap_server.request_restart()
|
||||
self.assertTrue(resp["success"])
|
||||
stopped_events = self.dap_server.wait_for_stopped()
|
||||
for stopped_event in stopped_events:
|
||||
if "body" in stopped_event:
|
||||
body = stopped_event["body"]
|
||||
if "reason" in body:
|
||||
reason = body["reason"]
|
||||
self.assertNotEqual(
|
||||
reason,
|
||||
"breakpoint",
|
||||
'verify stop after restart isn\'t "main" breakpoint',
|
||||
)
|
||||
self.verify_stop_on_entry()
|
||||
|
||||
@skipIfWindows
|
||||
def test_arguments(self):
|
||||
|
||||
@@ -11,27 +11,6 @@ from lldbsuite.test.lldbtest import line_number
|
||||
|
||||
@skipIfBuildType(["debug"])
|
||||
class TestDAP_restart_console(lldbdap_testcase.DAPTestCaseBase):
|
||||
def verify_stopped_on_entry(self, stopped_events: List[Dict[str, Any]]):
|
||||
seen_stopped_event = 0
|
||||
for stopped_event in stopped_events:
|
||||
body = stopped_event.get("body")
|
||||
if body is None:
|
||||
continue
|
||||
|
||||
reason = body.get("reason")
|
||||
if reason is None:
|
||||
continue
|
||||
|
||||
self.assertNotEqual(
|
||||
reason,
|
||||
"breakpoint",
|
||||
'verify stop after restart isn\'t "main" breakpoint',
|
||||
)
|
||||
if reason == "entry":
|
||||
seen_stopped_event += 1
|
||||
|
||||
self.assertEqual(seen_stopped_event, 1, "expect only one stopped entry event.")
|
||||
|
||||
@skipIfAsan
|
||||
@skipIfWindows
|
||||
@skipIf(oslist=["linux"], archs=["arm$"]) # Always times out on buildbot
|
||||
@@ -92,11 +71,8 @@ class TestDAP_restart_console(lldbdap_testcase.DAPTestCaseBase):
|
||||
self.build_and_launch(program, console="integratedTerminal", stopOnEntry=True)
|
||||
[bp_main] = self.set_function_breakpoints(["main"])
|
||||
|
||||
self.dap_server.request_continue() # sends configuration done
|
||||
stopped_events = self.dap_server.wait_for_stopped()
|
||||
# We should be stopped at the entry point.
|
||||
self.assertGreaterEqual(len(stopped_events), 0, "expect stopped events")
|
||||
self.verify_stopped_on_entry(stopped_events)
|
||||
self.dap_server.request_configurationDone()
|
||||
self.verify_stop_on_entry()
|
||||
|
||||
# Then, if we continue, we should hit the breakpoint at main.
|
||||
self.dap_server.request_continue()
|
||||
@@ -105,8 +81,7 @@ class TestDAP_restart_console(lldbdap_testcase.DAPTestCaseBase):
|
||||
# Restart and check that we still get a stopped event before reaching
|
||||
# main.
|
||||
self.dap_server.request_restart()
|
||||
stopped_events = self.dap_server.wait_for_stopped()
|
||||
self.verify_stopped_on_entry(stopped_events)
|
||||
self.verify_stop_on_entry()
|
||||
|
||||
# continue to main
|
||||
self.dap_server.request_continue()
|
||||
|
||||
@@ -176,7 +176,7 @@ llvm::Error SendThreadStoppedEvent(DAP &dap, bool on_entry) {
|
||||
|
||||
llvm::DenseSet<lldb::tid_t> old_thread_ids;
|
||||
old_thread_ids.swap(dap.thread_ids);
|
||||
uint32_t stop_id = process.GetStopID();
|
||||
uint32_t stop_id = on_entry ? 0 : process.GetStopID();
|
||||
const uint32_t num_threads = process.GetNumThreads();
|
||||
|
||||
// First make a pass through the threads to see if the focused thread
|
||||
|
||||
@@ -711,7 +711,7 @@ llvm::json::Value CreateThreadStopped(DAP &dap, lldb::SBThread &thread,
|
||||
break;
|
||||
}
|
||||
if (stop_id == 0)
|
||||
body.try_emplace("reason", "entry");
|
||||
body["reason"] = "entry";
|
||||
const lldb::tid_t tid = thread.GetThreadID();
|
||||
body.try_emplace("threadId", (int64_t)tid);
|
||||
// If no description has been set, then set it to the default thread stopped
|
||||
|
||||
Reference in New Issue
Block a user