ITADN

Segfault in OutboundPort::notify during evalExprWithProgress (Signal 11, libLLVM)

#832Openlightx 创建于 2026-05-24
bug
L
lightxcommented
**Describe the bug** `nixd` segfaults (Signal 11/SEGV) during expression evaluation while sending a `WorkDoneProgressEnd` LSP notification. The crash occurs in `llvm::json::isUTF8(llvm::StringRef)` called from `lspserver::OutboundPort::notify()` — the `StringRef` appears to reference invalid memory (address `0x59d44836c755` is clearly not a valid pointer), causing a null-pointer-adjacent dereference inside `libLLVM.so.21.1`. **Stack trace (crashing thread 1671726)** ``` #0 0x000078e2986463d9 llvm::json::isUTF8(llvm::StringRef, unsigned long*) (libLLVM.so.21.1 + 0xc463d9) #1 0x000078e2a1c833c0 lspserver::OutboundPort::notify(llvm::StringRef, llvm::json::Value) (libnixd-lspserver.so + 0x213c0) #2 0x000078e2a1de21c8 llvm::detail::UniqueFunctionBase<...>::CallImpl<lspserver::LSPServer::mkOutNotifiction<WorkDoneProgressEnd>...> (libnixd.so + 0x1141c8) #3 0x000078e2a1db20f2 llvm::detail::UniqueFunctionBase<...>::CallImpl<nixd::Controller::evalExprWithProgress(...)...> (libnixd.so + 0xe40f2) #4 0x000078e2a1de6dcf llvm::detail::UniqueFunctionBase<...>::CallImpl<lspserver::LSPServer::mkOutMethod<...>...> (libnixd.so + 0x118dcf) #5 0x000078e2a1c8c19d lspserver::LSPServer::onReply(llvm::json::Value, llvm::Expected<llvm::json::Value>) (libnixd-lspserver.so + 0x2a19d) #6 0x000078e2a1c8320b lspserver::InboundPort::dispatch(llvm::json::Value, lspserver::MessageHandler&) (libnixd-lspserver.so + 0x2120b) #7 0x000078e2a1c851a9 lspserver::InboundPort::loop(lspserver::MessageHandler&) (libnixd-lspserver.so + 0x231a9) ``` The main thread (1671677) was in `Controller::~Controller()` → `_M_erase` (destroying `AttrSetClientProc` map entries), waiting on thread join — indicating nixd was shutting down while the eval thread was still trying to send progress notifications through a dying/dead channel. **Kernel log** ``` May 24 17:39:41 hornet kernel: nixd[1671726]: segfault at 59d44836c755 ip 000078e2986463d9 sp 000078e2799ce340 error 4 in libLLVM.so.21.1[c463d9,78e2983b0000+5bd0000] likely on CPU 10 (core 2, socket 0) May 24 17:39:41 hornet kernel: Code: 25 28 00 00 00 48 89 45 f8 31 c0 48 39 fe 74 41 48 89 f9 48 89 f8 eb 12 66 0f 1f 84 00 00 00 00 00 48 83 c0 01 48 39 c6 74 27 <80> 38 00 79 f2 48 8d 7d f0 48 89 55 e0 48 89 4d f0 48 89 4d e8 e8 ``` The `<80> 38 00` instruction is `cmp byte [rax], 0` — classic strlen-style scan hitting an invalid pointer. **Configuration** ```json { "nixd": { "formatting": { "command": ["nixfmt"] } } } ``` Running inside Neovim via nvim-lspconfig. **To Reproduce** Not reliably reproducible — this is an intermittent crash that occurs during heavy flake evaluation. The flake in question (`nix flake check`) passes cleanly. This appears to be a race condition where the progress notification callback runs after or during controller teardown. Steps that may trigger it: 1. Open a large NixOS flake in an editor with nixd LSP 2. Wait for nixd to begin evaluating (progress notifications fire) 3. Crash occurs when the LSP channel disconnects or the controller starts shutting down while eval callbacks are still pending **Expected behavior** nixd should not segfault. Progress notifications should be safely dropped if the outbound channel is no longer valid. **Additional context** - nixd version: 2.9.1 - NixOS 25.05 (Warbler), Linux 6.18.26 - x86_64 - Nix store path: `/nix/store/nq6rgzv6kxs01jncg3b19fdygfnxkjwh-nixd-2.9.1` - No custom nixd config beyond formatting command - Flakes evaluation with home-manager integration (7 hosts)
5 条评论