| """ |
| Test LLDB's handling of qSymbol sequences. |
| """ |
| |
| from textwrap import dedent |
| import lldb |
| from lldbsuite.test.lldbtest import * |
| from lldbsuite.test.decorators import * |
| from lldbsuite.test.gdbclientutils import * |
| from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase |
| from lldbsuite.support.seven import hexlify, unhexlify |
| |
| |
| class MyResponder(MockGDBServerResponder): |
| def __init__(self, test_obj): |
| super().__init__() |
| self.wanted_symbols = [ |
| "main", |
| "local_address", |
| "global_value", |
| "local_value", |
| "not_a_symbol", |
| ] |
| self.last_symbol_request = None |
| self.symbol_results = {} |
| self.test_obj = test_obj |
| |
| def qSymbol(self, args): |
| # args will be <name hex encoded>:<hex value>. |
| # In the initial packet both fields are empty. |
| if args == ":": |
| self.test_obj.assertIsNone(self.last_symbol_request) |
| else: |
| # Anything else should be a response to our previous request. |
| value, name = args.split(":") |
| name = unhexlify(name) |
| self.test_obj.assertEqual(name, self.last_symbol_request) |
| |
| if value: |
| self.symbol_results[name] = int(value, 16) |
| |
| if self.wanted_symbols: |
| want = self.wanted_symbols.pop(0) |
| self.last_symbol_request = want |
| self.symbol_results[want] = None |
| |
| return "qSymbol:" + hexlify(want) |
| |
| # "OK" ends the qSymbol sequence. |
| return "OK" |
| |
| |
| class TestQSymbol(GDBRemoteTestBase): |
| @skipIfRemote |
| @skipIfLLVMTargetMissing("AArch64") |
| def test_qsymbol(self): |
| target = self.createTarget("test_qsymbol.yaml") |
| self.server.responder = MyResponder(self) |
| |
| if self.TraceOn(): |
| self.runCmd("log enable gdb-remote packets") |
| self.addTearDownHook(lambda: self.runCmd("log disable gdb-remote packets")) |
| |
| # LLDB will send a qSymbol shortly after connecting, which starts the sequence. |
| process = self.connect(target) |
| lldbutil.expect_state_changes( |
| self, self.dbg.GetListener(), process, [lldb.eStateStopped] |
| ) |
| |
| # LLDB should have responded in some way to all the qSymbol requests. |
| self.assertFalse(self.server.responder.wanted_symbols) |
| |
| expected_results = dict( |
| [ |
| ("main", 0x1000), |
| ("local_address", 0x1004), |
| ("global_value", 0x1234), |
| ("local_value", 0xABCD), |
| ("not_a_symbol", None), |
| ] |
| ) |
| self.assertEqual(expected_results, self.server.responder.symbol_results) |