Author: Stefan Gränitz Date: 2026-07-13T15:55:13+02:00 New Revision: 290601ed3e08a7e90b81b0b17cf45e1a435783a7
URL: https://github.com/llvm/llvm-project/commit/290601ed3e08a7e90b81b0b17cf45e1a435783a7 DIFF: https://github.com/llvm/llvm-project/commit/290601ed3e08a7e90b81b0b17cf45e1a435783a7.diff LOG: [lldb] Make timeout for HTTP send/receive in SymbolLocatorSymStore configurable (#192061) This patch adds the `plugin.symbol-locator.symstore.timeout` setting and keeps the previously hard-coded value of 60 sections as the default. It adds a test to check that the breakpoint doesn't resolve and we get the correct warning message if the timeout hits. --------- Co-authored-by: Nerixyz <[email protected]> Added: Modified: lldb/source/Plugins/SymbolLocator/SymStore/SymbolLocatorSymStore.cpp lldb/source/Plugins/SymbolLocator/SymStore/SymbolLocatorSymStoreProperties.td lldb/test/API/symstore/TestSymStore.py Removed: ################################################################################ diff --git a/lldb/source/Plugins/SymbolLocator/SymStore/SymbolLocatorSymStore.cpp b/lldb/source/Plugins/SymbolLocator/SymStore/SymbolLocatorSymStore.cpp index fac00c1a12db2..eab334e0b8e7a 100644 --- a/lldb/source/Plugins/SymbolLocator/SymStore/SymbolLocatorSymStore.cpp +++ b/lldb/source/Plugins/SymbolLocator/SymStore/SymbolLocatorSymStore.cpp @@ -68,6 +68,12 @@ class PluginProperties : public Properties { return SymbolLocatorSymStore::GetSystemDefaultCachePath(); } + uint64_t GetTimeout() const { + const uint32_t idx = ePropertyTimeout; + return GetPropertyAtIndexAs<uint64_t>( + idx, g_symbollocatorsymstore_properties[idx].default_uint_value); + } + std::optional<std::string> GetTLSCertFingerprint() const { OptionValueString *s = m_collection_sp->GetPropertyAtIndexAsOptionValueString( @@ -272,9 +278,8 @@ RequestFileFromSymStoreServerHTTP(llvm::StringRef base_url, llvm::StringRef key, } llvm::HTTPClient client; - // TODO: Since PDBs can be huge, we should distinguish between resolve, - // connect, send and receive. - client.setTimeout(std::chrono::seconds(60)); + client.setTimeout( + std::chrono::seconds(GetGlobalPluginProperties().GetTimeout())); llvm::StreamedHTTPResponseHandler Handler( [dest = tmp_file.str().str()]() diff --git a/lldb/source/Plugins/SymbolLocator/SymStore/SymbolLocatorSymStoreProperties.td b/lldb/source/Plugins/SymbolLocator/SymStore/SymbolLocatorSymStoreProperties.td index da24201c66b18..9ffd0cfab4fc0 100644 --- a/lldb/source/Plugins/SymbolLocator/SymStore/SymbolLocatorSymStoreProperties.td +++ b/lldb/source/Plugins/SymbolLocator/SymStore/SymbolLocatorSymStoreProperties.td @@ -2,12 +2,14 @@ include "../../../../include/lldb/Core/PropertiesBase.td" let Definition = "symbollocatorsymstore", Path = "plugin.symbol-locator.symstore" in { def SymStoreURLs : Property<"urls", "Array">, - ElementType<"String">, - Desc<"List of local symstore directories to query after " - "_NT_SYMBOL_PATH">; + ElementType<"String">, + Desc<"List of local symstore directories to query after _NT_SYMBOL_PATH">; def CachePath : Property<"cache", "String">, DefaultStringValue<"">, Desc<"Default cache directory for downloaded symbol files. Used when no cache is specified in _NT_SYMBOL_PATH.">; + def Timeout : Property<"timeout", "UInt64">, + DefaultUnsignedValue<60>, + Desc<"Timeout in seconds for send/receive in HTTP connections to symbol servers. A value of 0 indicates an infinite (no) timeout.">; def TLSCertFingerprint : Property<"tls-cert-fingerprint", "String">, DefaultStringValue<"">, Desc<"SHA-256 fingerprint (lowercase hex, no separators) of the symbol server's TLS certificate. When set, LLDB will accept an HTTPS server that presents this self-signed certificate even if it is not trusted by the system certificate store (Windows only).">; diff --git a/lldb/test/API/symstore/TestSymStore.py b/lldb/test/API/symstore/TestSymStore.py index 83a3b71b0adfb..4c668134447d1 100644 --- a/lldb/test/API/symstore/TestSymStore.py +++ b/lldb/test/API/symstore/TestSymStore.py @@ -7,6 +7,7 @@ import ssl import sys import threading +import time from functools import partial import lldb @@ -233,6 +234,23 @@ def do_GET(self): super().do_GET() +class SlowHTTPHandler(http.server.BaseHTTPRequestHandler): + """HTTP request handler that delays responses to simulate a slow server.""" + + delay = 2 # seconds to sleep before responding; set per test + + def do_GET(self): + try: + time.sleep(self.delay) + self.send_response(200) + self.end_headers() + except (BrokenPipeError, ConnectionResetError): + pass # client disconnected after timeout, as expected + + def log_message(self, *args): + pass # suppress server-side output + + class SymStoreTests(TestBase): TEST_WITH_PDB_DEBUG_INFO = True @@ -426,6 +444,26 @@ def test_lookup_order(self): self.try_breakpoint(exe, should_have_loc=True) self.assertEqual(RequestCounter.requests, 0) + def test_http_timeout(self): + """ + Check that a warning is emitted and no symbol is found when the server + takes longer to respond than the configured timeout. + """ + exe, sym = self.build_inferior() + with MockedSymStore(self, exe, sym) as dir: + SlowHTTPHandler.delay = 5 # seconds; exceeds the 1s timeout below + self.runCmd("settings set plugin.symbol-locator.symstore.timeout 1") + with HTTPServer(dir, SlowHTTPHandler) as url: + self.runCmd(f"settings set plugin.symbol-locator.symstore.urls {url}") + warnings = "" + with open(self.getBuildArtifact("stderr.txt"), "w+b") as err_file: + self.dbg.SetErrorFileHandle(err_file, False) + self.try_breakpoint(exe, should_have_loc=False) + self.dbg.SetErrorFileHandle(sys.stderr, False) + err_file.seek(0) + warnings = err_file.read().decode() + self.assertIn("failed to download", warnings) + @skipUnlessPackageAvailable("cryptography") def test_https(self): """ _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
