[llvm-branch-commits] [lldb] [lldb] Resolve dispatch qSymbol requests by exact linkage name (PR #232696)

Karim Alweheshy via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Oct 16 04:43:05 PDT 2026


https://github.com/karim-alweheshy created https://github.com/llvm/llvm-project/pull/232696

debugserver requests dispatch_queue_offsets as a C ABI data symbol. Resolve that request through exact linkage-name matching so a C++ function basename cannot satisfy it. Other qSymbol requests keep their existing matching behavior.

Depends on #232694. This PR contains only the qSymbol consumer and mock-server regressions. History checked: retain the non-Mach-O symbol-type and raw-value handling added by #200134 and #200411.

Validation: All three mock-server qSymbol tests pass with current-main LLDB built with this change over its prerequisite. On the prerequisite alone, both new cases fail by returning the C++ function address while the original case passes. Present/absent dispatch data and the unchanged generic request path are covered. Both YAML fixture variants assemble successfully.

Assisted-by: OpenAI Codex


<!-- av pr metadata
This information is embedded by the av CLI when creating PRs to track the status of stacks when using Aviator. Please do not delete or edit this section of the PR.
```
{"parent":"users/karim-alweheshy/lldb-exact-c-symbol-lookup","parentHead":"2888d6d184552bee1b635bbc575968b12360e79a","parentPull":232694,"trunk":"main"}
```
-->


>From aba3e072c601c59b09d5d4a8d1033df82ced7d4a Mon Sep 17 00:00:00 2001
From: Karim Alweheshy <karim.alweheshy at reddit.com>
Date: Fri, 16 Oct 2026 12:59:52 +0200
Subject: [PATCH] [lldb] Resolve dispatch qSymbol requests by exact linkage
 name

Use the opt-in linkage-name lookup for dispatch_queue_offsets while preserving generic matching for other remote requests and existing address and symbol-type handling. Cover C++ basename decoys and an absent dispatch data symbol with the mock server.

Assisted-by: OpenAI Codex
---
 .../GDBRemoteCommunicationClient.cpp          |  8 ++-
 .../gdb_remote_client/TestQSymbol.py          | 61 ++++++++++++++++---
 .../gdb_remote_client/test_qsymbol.yaml       | 25 +++++++-
 3 files changed, 84 insertions(+), 10 deletions(-)

diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 19b642ed3f65c5..c674641e5bcbac 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -4336,8 +4336,14 @@ void GDBRemoteCommunicationClient::ServeSymbolLookups(
 
               addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
               lldb_private::SymbolContextList sc_list;
+              // debugserver uses this C ABI data symbol to decode dispatch
+              // queues. C++ basename aliases are not that runtime definition.
+              // Other remote requests retain their usual name matching.
+              const bool match_linkage_names =
+                  symbol_name == "dispatch_queue_offsets";
               process->GetTarget().GetImages().FindSymbolsWithNameAndType(
-                  ConstString(symbol_name), eSymbolTypeAny, sc_list);
+                  ConstString(symbol_name), eSymbolTypeAny, sc_list,
+                  match_linkage_names);
               for (const SymbolContext &sc : sc_list) {
                 if (symbol_load_addr != LLDB_INVALID_ADDRESS)
                   break;
diff --git a/lldb/test/API/functionalities/gdb_remote_client/TestQSymbol.py b/lldb/test/API/functionalities/gdb_remote_client/TestQSymbol.py
index 96d6d83c203304..394c2a80d2b8c7 100644
--- a/lldb/test/API/functionalities/gdb_remote_client/TestQSymbol.py
+++ b/lldb/test/API/functionalities/gdb_remote_client/TestQSymbol.py
@@ -2,6 +2,7 @@
 Test LLDB's handling of qSymbol sequences.
 """
 
+from pathlib import Path
 from textwrap import dedent
 import lldb
 from lldbsuite.test.lldbtest import *
@@ -12,15 +13,19 @@
 
 
 class MyResponder(MockGDBServerResponder):
-    def __init__(self, test_obj):
+    def __init__(self, test_obj, wanted_symbols=None):
         super().__init__()
-        self.wanted_symbols = [
-            "main",
-            "local_address",
-            "global_value",
-            "local_value",
-            "not_a_symbol",
-        ]
+        self.wanted_symbols = (
+            wanted_symbols
+            if wanted_symbols is not None
+            else [
+                "main",
+                "local_address",
+                "global_value",
+                "local_value",
+                "not_a_symbol",
+            ]
+        )
         self.last_symbol_request = None
         self.symbol_results = {}
         self.test_obj = test_obj
@@ -80,3 +85,43 @@ def test_qsymbol(self):
             ]
         )
         self.assertEqual(expected_results, self.server.responder.symbol_results)
+
+    @skipIfRemote
+    @skipIfLLVMTargetMissing("AArch64")
+    def test_dispatch_symbol_uses_linkage_name(self):
+        self.check_dispatch_symbol(has_dispatch_data=True)
+
+    @skipIfRemote
+    @skipIfLLVMTargetMissing("AArch64")
+    def test_missing_dispatch_symbol_rejects_cpp_basename(self):
+        self.check_dispatch_symbol(has_dispatch_data=False)
+
+    def check_dispatch_symbol(self, has_dispatch_data):
+        self.runCmd("settings set target.preload-symbols false")
+        fixture = Path(self.getSourceDir()) / "test_qsymbol.yaml"
+        if not has_dispatch_data:
+            missing = Path(self.getBuildArtifact("qsymbol-missing.yaml"))
+            missing.write_text(
+                fixture.read_text().replace(
+                    "Name: dispatch_queue_offsets", "Name: unrelated_dispatch_data"
+                )
+            )
+            fixture = missing
+        target = self.createTarget(str(fixture))
+        self.server.responder = MyResponder(
+            self, ["dispatch_queue_offsets", "other_wire_request"]
+        )
+        process = self.connect(target)
+        lldbutil.expect_state_changes(
+            self, self.dbg.GetListener(), process, [lldb.eStateStopped]
+        )
+        self.assertFalse(self.server.responder.wanted_symbols)
+        # The known dispatch ABI must not resolve to the C++ function basename
+        # at 0x1008. Other requests keep their C++ basename lookup behavior.
+        self.assertEqual(
+            self.server.responder.symbol_results,
+            {
+                "dispatch_queue_offsets": 0x2000 if has_dispatch_data else None,
+                "other_wire_request": 0x1009,
+            },
+        )
diff --git a/lldb/test/API/functionalities/gdb_remote_client/test_qsymbol.yaml b/lldb/test/API/functionalities/gdb_remote_client/test_qsymbol.yaml
index 10a2cb99ea27f8..67b02a3d63e802 100644
--- a/lldb/test/API/functionalities/gdb_remote_client/test_qsymbol.yaml
+++ b/lldb/test/API/functionalities/gdb_remote_client/test_qsymbol.yaml
@@ -9,7 +9,12 @@ Sections:
     Type:  SHT_PROGBITS
     Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
     Address: 0x1000
-    Content: C0035FD6 # ret
+    Content: C0035FD6C0035FD6C0035FD6 # ret; ret; ret
+  - Name: .data
+    Type: SHT_PROGBITS
+    Flags: [ SHF_ALLOC, SHF_WRITE ]
+    Address: 0x2000
+    Content: '0000000000000000'
 Symbols:
   - Name: main
     Type: STT_FUNC
@@ -30,4 +35,22 @@ Symbols:
     Index: SHN_ABS
     Value: 0x1234
     Binding: STB_GLOBAL
+  - Name: _Z22dispatch_queue_offsetsv
+    Type: STT_FUNC
+    Section: .text
+    Value: 0x1008
+    Size: 1
+    Binding: STB_GLOBAL
+  - Name: _Z18other_wire_requestv
+    Type: STT_FUNC
+    Section: .text
+    Value: 0x1009
+    Size: 1
+    Binding: STB_GLOBAL
+  - Name: dispatch_queue_offsets
+    Type: STT_OBJECT
+    Section: .data
+    Value: 0x2000
+    Size: 8
+    Binding: STB_GLOBAL
 ...



More information about the llvm-branch-commits mailing list