This is more straight forward refactor of the startup sequence that reverts parts ofba29e60f9a. 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 in087a5d2ec7I 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()
|