[Lldb-commits] [lldb] Reland "[lldb] Initial plugin and test for SymbolLocatorSymStore" (PR #185658)

David Spickett via lldb-commits lldb-commits at lists.llvm.org
Tue Mar 10 10:20:55 PDT 2026


Stefan =?utf-8?q?Gränitz?= <stefan.graenitz at gmail.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/185658 at github.com>


================
@@ -0,0 +1,121 @@
+import os
+import shutil
+import tempfile
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+
+
+"""
+Test debug symbol acquisition from a local SymStore repository. This can work
+cross-platform and for arbitrary debug info formats. We only support PDB
+currently.
+"""
+
+
+class MockedSymStore:
+    """
+    Context Manager to populate a file structure equivalent to SymStore.exe in a
+    temporary directory.
+    """
+
+    def __init__(self, test, exe, pdb):
+        self._test = test
+        self._exe = exe
+        self._pdb = pdb
+        self._tmp = None
+
+    def get_key_pdb(self, exe):
+        """
+        Module UUID: 12345678-1234-5678-9ABC-DEF012345678-00000001
+        To SymStore key: 12345678123456789ABCDEF0123456781
+        """
+        spec = lldb.SBModuleSpec()
+        spec.SetFileSpec(lldb.SBFileSpec(self._test.getBuildArtifact(exe)))
+        module = lldb.SBModule(spec)
+        raw = module.GetUUIDString().replace("-", "").upper()
+        if len(raw) != 40:
+            raise RuntimeError("Unexpected number of bytes in embedded UUID")
+        guid_hex = raw[:32]
+        age = int(raw[32:], 16)
+        return guid_hex + str(age)
+
+    def __enter__(self):
+        """
+        Mock local symstore directory tree, move PDB there and report path.
+        """
+        key = None
+        if self._test.getDebugInfo() == "pdb":
+            key = self.get_key_pdb(self._exe)
+        self._test.assertIsNotNone(key)
+        self._tmp = self._test.getBuildArtifact("tmp")
+        pdb_dir = os.path.join(self._tmp, self._pdb, key)
+        os.makedirs(pdb_dir)
+        shutil.move(
+            self._test.getBuildArtifact(self._pdb),
+            os.path.join(pdb_dir, self._pdb),
+        )
+        return self._tmp
+
+    def __exit__(self, *exc_info):
+        """
+        Clean up and delete original exe so next make won't skip link command.
+        """
+        shutil.rmtree(self._tmp)
----------------
DavidSpickett wrote:

Thanks, that link explains it well.

Also I shouldn't have been lazy, I could've checked myself:
```
class Foo(object):
  def __enter__(self):
    raise RuntimeError("!")
  def __exit__(self):
    print("Here!")

with Foo() as f:
  pass
```
```
Traceback (most recent call last):
  File "/tmp/test.py", line 7, in <module>
    with Foo() as f:
  File "/tmp/test.py", line 3, in __enter__
    raise RuntimeError("!")
RuntimeError: !
```

But one more question. If enter throws after making your temp dir and therefore it doesn't get removed, is the test still fine?

I think it would be, given that the only place it can throw is the move into the folder. So if that failed, it's just an empty folder as far as the next run is concerned. Even if it got further, the only thing in there is the PDB and enter will overwrite that on the next run.

So I think I just answered my own question :)

If you agree with that then consider this thread resolved.

https://github.com/llvm/llvm-project/pull/185658


More information about the lldb-commits mailing list