sammccall added a comment. In D92155#2419346 <https://reviews.llvm.org/D92155#2419346>, @psionic12 wrote:
>> clangd (and other clang tools) get deployed in environments where all access >> to the filesystem goes through a llvm::vfs::Filesystem, and all filenames >> referred to in the compile command are within that virtual filesystem rather >> than the real one. >> (Again, this isn't an issue if we require these paths to be specified on the >> *clangd* startup command line, as opposed to the clang flags that form the >> compile command) > > Yes I know how clang manager files through vfs, it just that loading > libraries does not involve vfs at all, the path of a lib is passed directly > to the system level API (eg, dlopen on Linux, System::Load on Windows), so I > still can't understand what you are concerning, This is exactly the problem, filenames specified in *clang* flags are *supposed* to be read from the VFS. (In practice this probably just means we'd need to disable this feature in environments where VFS is used) > Or, could you help to point out what's the difference between passing a > plugin path through *clangd* startup command line and through clang flags? Sure. TL;DR is: clangd flags are configured by the user, user can be fully responsible for security/stability. clang flags are configured by the project. If they're bad, we can e.g. give bad diagnostics, but can't crash or compromise security. More detail: In the simplest possible case, clangd is configured as follows: 1. user downloads clangd binary 2. user installs an LSP plugin for their editor, and configures the plugin to use /usr/bin/clangd for C++ files. clangd starts when the editor does 3. the build system for $PROJECT generates $PROJECT/compile_commands.json 4. when the user opens $PROJECT/src/foo.cpp in the editor, it notifies clangd. clangd searches for $PROJECT/compile_commands.json, finds the clang arguments, and uses them to parse foo.cpp *clangd* command-line flags would be added explicitly by the user at step 2. We can reasonably ask the user to be aware/responsible for security/stability implications of doing this, including with their particular clangd version. We can also ask them to run `clangd --check` without the plugin flag to test whether the plugin is causing a stability problem. *clang* command-line flags are added implicitly in step 3. Or they could simply be checked into the repository - nothing ensures they were generated locally by the build system. The point is in typical usage they are not controlled by the user directly, and from a security perspective are not trusted (as safely opening files from untrusted repos is a reasonable expectation). So if we're loading plugins based on instructions in clang command-line flags, clangd bears most of the responsibility for making sure that's safe and correct (and I don't see a way to do that). ================ Comment at: clang/lib/Frontend/CompilerInvocation.cpp:3905 + std::string Error; + if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(Path.c_str(), &Error)) + Diags.Report(diag::err_fe_unable_to_load_plugin) << Path << Error; ---------------- psionic12 wrote: > sammccall wrote: > > psionic12 wrote: > > > sammccall wrote: > > > > is this threadsafe on all platforms? > > > While I can't tell, clang driver use this for a while and seems no > > > problem, could you help to point out what's the worst case your concerned > > > about? > > clang-driver isn't multithreaded, so wouldn't show up problems here. > > > > I'm concerned that if thread A loads plugin X, thread B loads plugin X, and > > thread C loads plugin Y, all concurrently and using this code path, whether > > they will all load correctly. > > > > In clangd these threads could correspond to two open files and a > > background-index worker. > > > > (I don't know much about dynamic loading, this may be totally fine) > In this case I can make sure multiple thread works just fine with > `LoadLibraryPermanently`, I checked all the dynamic loading API on most > platforms and all of the are thread-safe(it's rare to see system APIs which > are not thread safe, to me). That sounds good! I do see mutexes in the posix implementation so I guess the LLVM wrapper is intended to be threadsafe. ================ Comment at: clang/lib/Frontend/CompilerInvocation.cpp:3914 + if (P->getActionType() == PluginASTAction::ReplaceAction) { + Res.getFrontendOpts().ProgramAction = clang::frontend::PluginAction; + Res.getFrontendOpts().ActionName = Plugin.getName().str(); ---------------- psionic12 wrote: > sammccall wrote: > > psionic12 wrote: > > > sammccall wrote: > > > > we can't support replacement of the main action in clangd. What's the > > > > plan there - ignore the plugin? > > > Could you help to explain why action replacements are not supported? > > > > > > As far as I know, replacement of actions is related with Actions, which > > > does not have directly relationship with clangd, > > Clangd uses some custom FrontendActions (different ones for different ways > > we're parsing the file) to implement its features (e.g. track which parts > > of the AST are part of the main-file without deserializing the preamble, > > and to do indexing). > > If you replace these actions, normal features will not work. > > > > e.g.: > > - > > https://github.com/llvm/llvm-project/blob/4df8efce80e373dd1e05bd4910c796a0c91383e7/clang-tools-extra/clangd/ParsedAST.cpp#L97 > > - > > https://github.com/llvm/llvm-project/blob/master/clang-tools-extra/clangd/index/IndexAction.cpp#L206 > > > > If we replace these with the plugin's action, clangd won't work > I think this is the part I didn't expected, seems a standalone action loading > logic needs to exist. > > I'll try to come up a patch which has standalone plugin loading and guard it > with experimental checking. It seems plugins can run before/after/replace the main action. I wonder if it'd break things to silently "promote" a replace plugin to e.g. an after one, which I guess would solve this. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D92155/new/ https://reviews.llvm.org/D92155 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits