-
Notifications
You must be signed in to change notification settings - Fork 214
Closed
Labels
Description
Steps to reproduce:
- Log into some remote Linux machine with clangd installed (but this may be server-agnostic).
- Create a simple
foobar"project" with the snippet below:
mkdir -p foobar/foo foobar/bar
echo "int main(){}" > foobar/foo/foo.cc
echo "int main(){}" > foobar/bar/bar.cc
git init foobar- From within Emacs running on your local machine,
C-x C-ftofoo.ccvia TRAMP, e.g./ssh:my-remote-machine:foobar/foo/foo.cc. - Wait until
[eglot] Connected! Server `clangd' now managing `c++-mode' buffers in project `foobar'. C-x C-ftobar.cc.- Observe the error
Forbidden reentrant call of Tramp.
BTW, this doesn't happen when files foo.cc and bar.cc are in the same dir, e.g. foobar/foo.cc and foobar/bar.cc.
Details:
- Server used: clangd
- Emacs version:
27.1(with TRAMP2.5.2.2installed from ELPA viapackage.el) - Operating system: macOS (locally), Linux (remotely)
- Eglot version: current
master@8dc5180 - Eglot installation method: git
- Using Doom: No
LSP transcript - M-x eglot-events-buffer (mandatory unless Emacs inoperable)
[internal] Thu Mar 3 19:34:41 2022:
(:message "Running language server: (sh -c stty raw > /dev/null; clangd --clang-tidy\\=0)")
[stderr] I[18:34:41.402] Ubuntu clangd version 13.0.0-2
[stderr] I[18:34:41.403] Features: linux
[stderr] I[18:34:41.403] PID: 2073
[stderr] I[18:34:41.403] Working directory: /home/xor-xor/foobar
[stderr] I[18:34:41.403] argv[0]: clangd
[stderr] I[18:34:41.403] argv[1]: --clang-tidy=0
[stderr] I[18:34:41.403] Starting LSP over stdin/stdout
[client-request] (id:1) Thu Mar 3 19:34:41 2022:
(:jsonrpc "2.0" :id 1 :method "initialize" :params
(:processId nil :rootPath "/home/xor-xor/foobar/" :rootUri "file:///home/xor-xor/foobar" :initializationOptions #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data
())
:capabilities
(:workspace
(:applyEdit t :executeCommand
(:dynamicRegistration :json-false)
:workspaceEdit
(:documentChanges :json-false)
:didChangeWatchedFiles
(:dynamicRegistration t)
:symbol
(:dynamicRegistration :json-false)
:configuration t)
:textDocument
(:synchronization
(:dynamicRegistration :json-false :willSave t :willSaveWaitUntil t :didSave t)
:completion
(:dynamicRegistration :json-false :completionItem
(:snippetSupport :json-false :deprecatedSupport t :tagSupport
(:valueSet
[1]))
:contextSupport t)
:hover
(:dynamicRegistration :json-false :contentFormat
["markdown" "plaintext"])
:signatureHelp
(:dynamicRegistration :json-false :signatureInformation
(:parameterInformation
(:labelOffsetSupport t)
:activeParameterSupport t))
:references
(:dynamicRegistration :json-false)
:definition
(:dynamicRegistration :json-false :linkSupport t)
:declaration
(:dynamicRegistration :json-false :linkSupport t)
:implementation
(:dynamicRegistration :json-false :linkSupport t)
:typeDefinition
(:dynamicRegistration :json-false :linkSupport t)
:documentSymbol
(:dynamicRegistration :json-false :hierarchicalDocumentSymbolSupport t :symbolKind
(:valueSet
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26]))
:documentHighlight
(:dynamicRegistration :json-false)
:codeAction
(:dynamicRegistration :json-false :codeActionLiteralSupport
(:codeActionKind
(:valueSet
["quickfix" "refactor" "refactor.extract" "refactor.inline" "refactor.rewrite" "source" "source.organizeImports"]))
:isPreferredSupport t)
:formatting
(:dynamicRegistration :json-false)
:rangeFormatting
(:dynamicRegistration :json-false)
:rename
(:dynamicRegistration :json-false)
:publishDiagnostics
(:relatedInformation :json-false :codeDescriptionSupport :json-false :tagSupport
(:valueSet
[1 2])))
:experimental #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data
()))))
[stderr] I[18:34:41.448] <-- initialize(1)
[stderr] I[18:34:41.449] --> reply:initialize(1) 0 ms
[server-reply] (id:1) Thu Mar 3 19:34:41 2022:
(:id 1 :jsonrpc "2.0" :result
(:capabilities
(:astProvider t :callHierarchyProvider t :codeActionProvider
(:codeActionKinds
["quickfix" "refactor" "info"])
:compilationDatabase
(:automaticReload t)
:completionProvider
(:allCommitCharacters
[" " " " "(" ")" "[" "]" "{" "}" "<" ">" ":" ";" "," "+" "-" "/" "*" "%" "^" "&" "#" "?" "." "=" "\"" "'" "|"]
:resolveProvider :json-false :triggerCharacters
["." "<" ">" ":" "\"" "/"])
:declarationProvider t :definitionProvider t :documentFormattingProvider t :documentHighlightProvider t :documentLinkProvider
(:resolveProvider :json-false)
:documentOnTypeFormattingProvider
(:firstTriggerCharacter "\n" :moreTriggerCharacter
[])
:documentRangeFormattingProvider t :documentSymbolProvider t :executeCommandProvider
(:commands
["clangd.applyFix" "clangd.applyTweak"])
:hoverProvider t :implementationProvider t :memoryUsageProvider t :referencesProvider t :renameProvider t :selectionRangeProvider t :semanticTokensProvider
(:full
(:delta t)
:legend
(:tokenModifiers
["declaration" "deprecated" "deduced" "readonly" "static" "abstract" "dependentName" "defaultLibrary" "functionScope" "classScope" "fileScope" "globalScope"]
:tokenTypes
["variable" "variable" "parameter" "function" "method" "function" "property" "variable" "class" "interface" "enum" "enumMember" "type" "type" "unknown" "namespace" "typeParameter" "concept" "type" "macro" "comment"])
:range :json-false)
:signatureHelpProvider
(:triggerCharacters
["(" ","])
:textDocumentSync
(:change 2 :openClose t :save t)
:typeHierarchyProvider t :workspaceSymbolProvider t)
:serverInfo
(:name "clangd" :version "Ubuntu clangd version 13.0.0-2 linux x86_64-pc-linux-gnu")))
[client-notification] Thu Mar 3 19:34:41 2022:
(:jsonrpc "2.0" :method "initialized" :params #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data
()))
[client-notification] Thu Mar 3 19:34:41 2022:
(:jsonrpc "2.0" :method "textDocument/didOpen" :params
(:textDocument
(:uri "file:///home/xor-xor/foobar/foo/foo.cc" :version 0 :languageId "c++" :text "int main(){}\n")))
[client-notification] Thu Mar 3 19:34:41 2022:
(:jsonrpc "2.0" :method "workspace/didChangeConfiguration" :params
(:settings nil))
[stderr] I[18:34:41.466] <-- initialized
[stderr] I[18:34:41.658] <-- textDocument/didOpen
[stderr] I[18:34:41.659] Failed to find compilation database for /home/xor-xor/foobar/foo/foo.cc
[stderr] I[18:34:41.660] ASTWorker building file /home/xor-xor/foobar/foo/foo.cc version 0 with command clangd fallback
[stderr] [/home/xor-xor/foobar/foo]
[stderr] /usr/lib/llvm-13/bin/clang -resource-dir=/usr/lib/llvm-13/lib/clang/13.0.0 -- /home/xor-xor/foobar/foo/foo.cc
[stderr] I[18:34:41.661] <-- workspace/didChangeConfiguration
[stderr] I[18:34:41.674] --> textDocument/publishDiagnostics
[server-notification] Thu Mar 3 19:34:41 2022:
(:jsonrpc "2.0" :method "textDocument/publishDiagnostics" :params
(:diagnostics
[]
:uri "file:///home/xor-xor/foobar/foo/foo.cc" :version 0))
[client-notification] Thu Mar 3 19:34:56 2022:
(:jsonrpc "2.0" :method "textDocument/didOpen" :params
(:textDocument
(:uri "file:///home/xor-xor/foobar/bar/bar.cc" :version 0 :languageId "c++" :text "int main(){}\n")))
[stderr] I[18:34:56.902] <-- textDocument/didOpen
[stderr] I[18:34:56.902] Failed to find compilation database for /home/xor-xor/foobar/bar/bar.cc
[stderr] I[18:34:56.902] ASTWorker building file /home/xor-xor/foobar/bar/bar.cc version 0 with command clangd fallback
[stderr] [/home/xor-xor/foobar/bar]
[stderr] /usr/lib/llvm-13/bin/clang -resource-dir=/usr/lib/llvm-13/lib/clang/13.0.0 -- /home/xor-xor/foobar/bar/bar.cc
[stderr] I[18:34:56.915] --> textDocument/publishDiagnostics
[server-notification] Thu Mar 3 19:34:57 2022:
(:jsonrpc "2.0" :method "textDocument/publishDiagnostics" :params
(:diagnostics
[]
:uri "file:///home/xor-xor/foobar/bar/bar.cc" :version 0))Backtrace (mandatory, unless no error message seen or heard):
(hostname redacted out)
Debugger entered--Lisp error: (remote-file-error "Forbidden reentrant call of Tramp")
signal(remote-file-error ("Forbidden reentrant call of Tramp"))
tramp-error(#<process *tramp/ssh my-host.somewhere*> remote-file-error "Forbidden reentrant call of Tramp")
tramp-send-string((tramp-file-name "ssh" nil nil "my-host.somewhere..." nil "/home/xor-xor/foobar/bar/bar.cc" nil) "\\readlink --canonicalize-missing /home/xor-xor...")
tramp-send-command((tramp-file-name "ssh" nil nil "my-host.somewhere..." nil "/home/xor-xor/foobar/bar/bar.cc" nil) "\\readlink --canonicalize-missing /home/xor-xor...")
tramp-send-command-and-check((tramp-file-name "ssh" nil nil "my-host.somewhere..." nil "/home/xor-xor/foobar/bar/bar.cc" nil) "\\readlink --canonicalize-missing /home/xor-xor...")
tramp-sh-handle-file-truename("/ssh:my-host.somewhere...")
apply(tramp-sh-handle-file-truename "/ssh:my-host.somewhere...")
tramp-vc-file-name-handler(file-truename "/ssh:my-host.somewhere...")
file-truename("/ssh:my-host.somewhere...")
find-buffer-visiting("/ssh:my-host.somewhere...")
(and t (find-buffer-visiting (eglot--uri-to-path uri)))
(let* ((buffer (and t (find-buffer-visiting (eglot--uri-to-path uri))))) (if buffer (save-current-buffer (set-buffer buffer) (let* ((--cl-vec-- diagnostics) (--cl-idx-- -1) (diag-spec nil) (diags nil)) (while (< (setq --cl-idx-- (1+ --cl-idx--)) (length --cl-vec--)) (setq diag-spec (aref --cl-vec-- --cl-idx--)) (setq diags (nconc diags (list ...)))) (cond (eglot--current-flymake-report-fn (eglot--report-to-flymake diags)) (t (setq eglot--unreported-diagnostics (cons t diags)))) nil)) (let* ((path (expand-file-name (eglot--uri-to-path uri))) (--cl-vec-- diagnostics) (--cl-idx-- -1) (diag-spec nil) (diags nil)) (while (< (setq --cl-idx-- (1+ --cl-idx--)) (length --cl-vec--)) (setq diag-spec (aref --cl-vec-- --cl-idx--)) (setq diags (nconc diags (list (let ... ...))))) (setq flymake-list-only-diagnostics (assoc-delete-all path flymake-list-only-diagnostics #'string=)) (setq flymake-list-only-diagnostics (cons (cons path diags) flymake-list-only-diagnostics)) nil)))
(progn (let* ((buffer (and t (find-buffer-visiting (eglot--uri-to-path uri))))) (if buffer (save-current-buffer (set-buffer buffer) (let* ((--cl-vec-- diagnostics) (--cl-idx-- -1) (diag-spec nil) (diags nil)) (while (< (setq --cl-idx-- ...) (length --cl-vec--)) (setq diag-spec (aref --cl-vec-- --cl-idx--)) (setq diags (nconc diags ...))) (cond (eglot--current-flymake-report-fn (eglot--report-to-flymake diags)) (t (setq eglot--unreported-diagnostics ...))) nil)) (let* ((path (expand-file-name (eglot--uri-to-path uri))) (--cl-vec-- diagnostics) (--cl-idx-- -1) (diag-spec nil) (diags nil)) (while (< (setq --cl-idx-- (1+ --cl-idx--)) (length --cl-vec--)) (setq diag-spec (aref --cl-vec-- --cl-idx--)) (setq diags (nconc diags (list ...)))) (setq flymake-list-only-diagnostics (assoc-delete-all path flymake-list-only-diagnostics #'string=)) (setq flymake-list-only-diagnostics (cons (cons path diags) flymake-list-only-diagnostics)) nil))))
(let* ((--cl-eglot--diag-type-- #'(lambda (sev) (cond ((null sev) 'eglot-error) ((<= sev 1) 'eglot-error) ((= sev 2) 'eglot-warning) (t 'eglot-note))))) (progn (let* ((buffer (and t (find-buffer-visiting (eglot--uri-to-path uri))))) (if buffer (save-current-buffer (set-buffer buffer) (let* ((--cl-vec-- diagnostics) (--cl-idx-- -1) (diag-spec nil) (diags nil)) (while (< ... ...) (setq diag-spec ...) (setq diags ...)) (cond (eglot--current-flymake-report-fn ...) (t ...)) nil)) (let* ((path (expand-file-name ...)) (--cl-vec-- diagnostics) (--cl-idx-- -1) (diag-spec nil) (diags nil)) (while (< (setq --cl-idx-- ...) (length --cl-vec--)) (setq diag-spec (aref --cl-vec-- --cl-idx--)) (setq diags (nconc diags ...))) (setq flymake-list-only-diagnostics (assoc-delete-all path flymake-list-only-diagnostics #'string=)) (setq flymake-list-only-diagnostics (cons (cons path diags) flymake-list-only-diagnostics)) nil)))))
(let* ((uri (car (cdr (plist-member --cl-rest-- ':uri)))) (diagnostics (car (cdr (plist-member --cl-rest-- ':diagnostics))))) (let* ((--cl-eglot--diag-type-- #'(lambda (sev) (cond (... ...) (... ...) (... ...) (t ...))))) (progn (let* ((buffer (and t (find-buffer-visiting ...)))) (if buffer (save-current-buffer (set-buffer buffer) (let* (... ... ... ...) (while ... ... ...) (cond ... ...) nil)) (let* ((path ...) (--cl-vec-- diagnostics) (--cl-idx-- -1) (diag-spec nil) (diags nil)) (while (< ... ...) (setq diag-spec ...) (setq diags ...)) (setq flymake-list-only-diagnostics (assoc-delete-all path flymake-list-only-diagnostics ...)) (setq flymake-list-only-diagnostics (cons ... flymake-list-only-diagnostics)) nil))))))
(progn (let* ((uri (car (cdr (plist-member --cl-rest-- ':uri)))) (diagnostics (car (cdr (plist-member --cl-rest-- ':diagnostics))))) (let* ((--cl-eglot--diag-type-- #'(lambda (sev) (cond ... ... ... ...)))) (progn (let* ((buffer (and t ...))) (if buffer (save-current-buffer (set-buffer buffer) (let* ... ... ... nil)) (let* (... ... ... ... ...) (while ... ... ...) (setq flymake-list-only-diagnostics ...) (setq flymake-list-only-diagnostics ...) nil)))))))
(closure (revert-buffer-preserve-modes eglot--managed-mode eglot-lsp-context company-tooltip-align-annotations company-backends markdown-fontify-code-blocks-natively t) (_server _method &rest --cl-rest--) "Handle notification publishDiagnostics.\n\n(fn SERVE..." (progn (let* ((uri (car (cdr ...))) (diagnostics (car (cdr ...)))) (let* ((--cl-eglot--diag-type-- #'...)) (progn (let* (...) (if buffer ... ...)))))))(#<eglot-lsp-server eglot-lsp-server-1fe17809a9a8> textDocument/publishDiagnostics :diagnostics [] :uri "file:///home/xor-xor/foobar/bar/bar.cc" :version 0)
apply((closure (revert-buffer-preserve-modes eglot--managed-mode eglot-lsp-context company-tooltip-align-annotations company-backends markdown-fontify-code-blocks-natively t) (_server _method &rest --cl-rest--) "Handle notification publishDiagnostics.\n\n(fn SERVE..." (progn (let* ((uri (car (cdr ...))) (diagnostics (car (cdr ...)))) (let* ((--cl-eglot--diag-type-- #'...)) (progn (let* (...) (if buffer ... ...))))))) #<eglot-lsp-server eglot-lsp-server-1fe17809a9a8> textDocument/publishDiagnostics (:diagnostics [] :uri "file:///home/xor-xor/foobar/bar/bar.cc" :version 0))
eglot-handle-notification(#<eglot-lsp-server eglot-lsp-server-1fe17809a9a8> textDocument/publishDiagnostics :diagnostics [] :uri "file:///home/xor-xor/foobar/bar/bar.cc" :version 0)
apply(eglot-handle-notification #<eglot-lsp-server eglot-lsp-server-1fe17809a9a8> textDocument/publishDiagnostics (:diagnostics [] :uri "file:///home/xor-xor/foobar/bar/bar.cc" :version 0))
(let ((eglot--cached-server server)) (apply fn server method (append params nil)))
(closure ((fn . eglot-handle-notification) (initargs :process (closure ((contact "clangd" "--clang-tidy=0") (server-info "sh" "-c" "stty raw > /dev/null; clangd --clang-tidy\\=0") (autostart-inferior-process) (readable-name . "EGLOT (foobar/c++-mode)") (nickname . "foobar") (language-id . "c++") (contact "clangd" "--clang-tidy=0") (class . eglot-lsp-server) (project vc . "/ssh:my-host.somewhere...") (managed-major-mode . c++-mode) eglot--managed-mode eglot-lsp-context company-tooltip-align-annotations company-backends markdown-fontify-code-blocks-natively t) nil (let ((default-directory default-directory)) (make-process :name readable-name :command (setq server-info ...) :connection-type 'pipe :coding 'utf-8-emacs-unix :noquery t :stderr (get-buffer-create ...) :file-handler t)))) (contact "clangd" "--clang-tidy=0") (server-info "sh" "-c" "stty raw > /dev/null; clangd --clang-tidy\\=0") (autostart-inferior-process) (readable-name . "EGLOT (foobar/c++-mode)") (nickname . "foobar") (language-id . "c++") (contact "clangd" "--clang-tidy=0") (class . eglot-lsp-server) (project vc . "/ssh:my-host.somewhere...") (managed-major-mode . c++-mode) eglot--managed-mode eglot-lsp-context company-tooltip-align-annotations company-backends markdown-fontify-code-blocks-natively t) (server method params) (let ((eglot--cached-server server)) (apply fn server method (append params nil))))(#<eglot-lsp-server eglot-lsp-server-1fe17809a9a8> textDocument/publishDiagnostics (:diagnostics [] :uri "file:///home/xor-xor/foobar/bar/bar.cc" :version 0))
jsonrpc-connection-receive(#<eglot-lsp-server eglot-lsp-server-1fe17809a9a8> (:jsonrpc "2.0" :method "textDocument/publishDiagnostics" :params (:diagnostics [] :uri "file:///home/xor-xor/foobar/bar/bar.cc" :version 0)))
jsonrpc--process-filter(#<process EGLOT (foobar/c++-mode)> "Content-Length: 158\15\n\15\n{\"jsonrpc\":\"2.0\",\"method\":\"...")
process-send-string(#<process *tramp/ssh my-host.somewhere*> "tramp_vc_registered_read_file_names <<'cc634870bf3...")
tramp-send-string((tramp-file-name "ssh" nil nil "my-host.somewhere..." nil "/home/xor-xor/foobar/bar/bar.cc" nil) "tramp_vc_registered_read_file_names <<'cc634870bf3...")
tramp-send-command((tramp-file-name "ssh" nil nil "my-host.somewhere..." nil "/home/xor-xor/foobar/bar/bar.cc" nil) "tramp_vc_registered_read_file_names <<'cc634870bf3...")
tramp-sh-handle-vc-registered("/ssh:my-host.somewhere...")
apply(tramp-sh-handle-vc-registered "/ssh:my-host.somewhere...")
tramp-sh-file-name-handler(vc-registered "/ssh:my-host.somewhere...")
apply(tramp-sh-file-name-handler vc-registered "/ssh:my-host.somewhere...")
tramp-file-name-handler(vc-registered "/ssh:my-host.somewhere...")
vc-registered("/ssh:my-host.somewhere...")
vc-backend("/ssh:my-host.somewhere...")
vc-refresh-state()
run-hooks(find-file-hook)
after-find-file(nil t)
find-file-noselect-1(#<buffer bar.cc> "/ssh:my-host.somewhere..." nil nil "/ssh:my-host.somewhere..." (1299068 (-1 . 1)))
find-file-noselect("/ssh:my-host.somewhere..." nil nil t)
find-file("/ssh:my-host.somewhere..." t)
funcall-interactively(find-file "/ssh:my-host.somewhere..." t)
call-interactively(find-file nil nil)
command-execute(find-file)Minimal configuration (mandatory)
# Emacs started with:
$ emacs -Q -f package-initialize -L /path/to/git-cloned/eglot -l eglot.el ;;; config evaluated via *scratch*:
(setq debug-on-error t)
(with-eval-after-load 'cc-mode
(require 'eglot)
(add-to-list 'eglot-server-programs '((c++-mode) . ("clangd" "--clang-tidy=0")))
(add-hook 'c++-mode-hook 'eglot-ensure))Reactions are currently unavailable