This is more straight forward refactor of the startup sequence that reverts parts of ba29e60f9a2222bd5e883579bb78db13fc5a7588. Unlike my previous attempt, I ended up removing the pending request queue and not including an `AsyncReqeustHandler` because I don't think we actually need that at the moment. The key is that during the startup flow there are 2 parallel operations happening in the DAP that have different triggers. * The `initialize` request is sent and once the response is received the `launch` or `attach` is sent. * When the `initialized` event is recieved the `setBreakpionts` and other config requests are made followed by the `configurationDone` event. I moved the `initialized` event back to happen in the `PostRun` of the `launch` or `attach` request handlers. This ensures that we have a valid target by the time the configuration calls are made. I added also added a few extra validations that to the `configurationeDone` handler to ensure we're in an expected state. I've also fixed up the tests to match the new flow. With the other additional test fixes in 087a5d2ec7897cd99d3787820711fec76a8e1792 I think we've narrowed down the main source of test instability that motivated the startup sequence change.
56 lines
2.2 KiB
Python
56 lines
2.2 KiB
Python
import dap_server
|
|
from lldbsuite.test.decorators import *
|
|
from lldbsuite.test.lldbtest import *
|
|
from lldbsuite.test import lldbutil
|
|
import lldbdap_testcase
|
|
import re
|
|
|
|
|
|
class TestDAP_module_event(lldbdap_testcase.DAPTestCaseBase):
|
|
@skipIfWindows
|
|
def test_module_event(self):
|
|
program = self.getBuildArtifact("a.out")
|
|
self.build_and_launch(program)
|
|
|
|
source = "main.cpp"
|
|
breakpoint1_line = line_number(source, "// breakpoint 1")
|
|
breakpoint2_line = line_number(source, "// breakpoint 2")
|
|
breakpoint3_line = line_number(source, "// breakpoint 3")
|
|
|
|
breakpoint_ids = self.set_source_breakpoints(
|
|
source, [breakpoint1_line, breakpoint2_line, breakpoint3_line]
|
|
)
|
|
self.continue_to_breakpoints(breakpoint_ids)
|
|
|
|
# We're now stopped at breakpoint 1 before the dlopen. Flush all the module events.
|
|
event = self.dap_server.wait_for_event("module", 0.25)
|
|
while event is not None:
|
|
event = self.dap_server.wait_for_event("module", 0.25)
|
|
|
|
# Continue to the second breakpoint, before the dlclose.
|
|
self.continue_to_breakpoints(breakpoint_ids)
|
|
|
|
# Make sure we got a module event for libother.
|
|
event = self.dap_server.wait_for_event("module", 5)
|
|
self.assertTrue(event, "didn't get a module event")
|
|
module_name = event["body"]["module"]["name"]
|
|
module_id = event["body"]["module"]["id"]
|
|
self.assertEqual(event["body"]["reason"], "new")
|
|
self.assertIn("libother", module_name)
|
|
|
|
# Continue to the third breakpoint, after the dlclose.
|
|
self.continue_to_breakpoints(breakpoint_ids)
|
|
|
|
# Make sure we got a module event for libother.
|
|
event = self.dap_server.wait_for_event("module", 5)
|
|
self.assertTrue(event, "didn't get a module event")
|
|
reason = event["body"]["reason"]
|
|
self.assertEqual(event["body"]["reason"], "removed")
|
|
self.assertEqual(event["body"]["module"]["id"], module_id)
|
|
|
|
# The removed module event should omit everything but the module id.
|
|
# Check that there's no module name in the event.
|
|
self.assertNotIn("name", event["body"]["module"])
|
|
|
|
self.continue_to_exit()
|