This is a follow-up patch for D148088. The dynamic symbol index (FileIndex::updatePreamble) may run in a separate thread, and the DiagnosticConsumer that is set up in buildPreamble might go out of scope before it is used. This could result in a SIGSEGV when attempting to call any method of the DiagnosticConsumer class.
The function buildPreamble sets up the DiagnosticConsumer as follows:
... buildPreamble(...) { ... StoreDiags PreambleDiagnostics; ... llvm::IntrusiveRefCntPtr<DiagnosticsEngine> PreambleDiagsEngine = CompilerInstance::createDiagnostics(&CI.getDiagnosticOpts(), &PreambleDiagnostics, /*ShouldOwnClient=*/false); ... // The call might use the diagnostic consumer in a separate thread PreambleCallback(...) ... }
PreambleDiagnostics might be out of scope for buildPreamble function when we call it inside PreambleCallback in a separate thread.
The Fix
The fix involves replacing the client (DiagnosticConsumer) with an IgnoringDiagConsumer instance, which will print messages to the clangd log.
Alternatively, we can replace PreambleDiagnostics with an object that is owned by DiagnosticsEngine.
Note
There is no corresponding LIT/GTest for this issue, since there is a specific race condition that is difficult to reproduce within a test framework.
Test Plan:
ninja check-clangd
Alternative fix