sammccall added inline comments.

================
Comment at: clang-tools-extra/clangd/ClangdServer.cpp:1008-1010
+  // TUScheduler is the only thing that starts background indexing work.
+  if (IndexTasks && !IndexTasks->wait(timeoutSeconds(TimeoutSeconds)))
+    return false;
----------------
bnbarham wrote:
> @sammccall shouldn't we also be waiting for this to finish when 
> `ClangdServer` is destroyed? IIUC right now the both `FileIndex` itself 
> (stored in `ClangdServer`) and the actual `UpdateIndexCallbacks` (stored in 
> `TUScheduler`) can be freed while `indexStdlib` is running asynchronously, 
> resulting in a use-after-free on eg. `FIndex->updatePreamble(std::move(IF))`. 
> I was confused as to why this wasn't happening in the tests, but these lines 
> would explain it 😅 
> 
> Adding a `IndexTasks->wait()` to `~ClangdServer` fixes the crash I'm seeing 
> in the sourcekit-lsp tests (see 
> https://github.com/apple/llvm-project/pull/5837), though ideally we 
> (sourcekit-lsp) wouldn't be running any indexing at all. As far as I can tell 
> there's no way to turn off dynamic indexing now though, except for 
> `StandardLibrary` indexing through the config file (but not from clangd args)?
Thanks for flagging this!

We *almost* have the sequencing we need in ~ClangdServer:
 - when we fall off the end of ~ClangdServer it destroys all its members
 - `ClangdServer::IndexTasks` is declared after `FIndex`, so is destroyed first
 - ~AsyncTaskRunner calls `wait()`

But the task we schedule on `IndexTasks` captures a ref to 
`UpdateIndexCallbacks`, which is owned by the `TUScheduler`, which we 
explicitly destroy at the beginning of `~ClangdServer`.

However I think your patch is *also* not quite correct: we can wait for the 
tasks to be empty, but then the TUScheduler could fill it up again before we 
destroy TUScheduler.

Options include adding an explicit stop() to TUScheduler, changing TUScheduler 
to not (exclusively) own UpdateIndexCallbacks, or have the task not capture the 
callbacks by reference.
I'll try the latter first, which seems least invasive.

---

> ideally we (sourcekit-lsp) wouldn't be running any indexing at all. As far as 
> I can tell there's no way to turn off dynamic indexing now though, except for 
> StandardLibrary indexing through the config file (but not from clangd args)?

Clangd won't provide any top-level/namespace-level completions at all without 
dynamic index (index of preambles), and various other features won't work (docs 
on hover, include-fixer, type/call-hierarchy). We dropped support for disabling 
this at some point, as it didn't really seem usable and made features more 
complex if we tried to accommodate it. At a technical level it would be 
possible to disable I think, but I'd be really surprised if completion worked 
well, or if a language server without completion was useful.

> `StandardLibrary` indexing through the config file (but not from clangd args)

We've tried to move away from flags for options that are interesting to users, 
as config files are more flexible, more forgiving on errors, and allow 
different settings per-project in a consistent way. (We don't own the editors, 
so cross-editor consistency is important to being able to support users at 
all...)

I can see how requiring config to be materialized on disk could be inconvenient 
for IDEs though. I think we could add a general-purpose 
`--config-inline=<YAML/JSON goes here>` flag, and/or the ability to set config 
over LSP (this can be dynamic, accordingly bigger design space that might be 
hard to get right).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D115232/new/

https://reviews.llvm.org/D115232

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to