-
Notifications
You must be signed in to change notification settings - Fork 263
Debugging
First of all, use a --variant=debug
Build. It is compiled with -O0 -g
while the default --variant=release
is -O3 -g
.
--log-file=/tmp/cq.log
Alternatively, enable logs and pass the --log-all-to-stderr
option to the ccls executable (bin/ccls --log-file=/tmp/cq.log --log-all-to-stderr
). You can find stderr output in:
- LanguageClient-neovim:
/tmp/LanguageServer.log
(default) - Emacs lsp-mode:
*lsp-ccls stderr*
buffer. They will also go to*message*
buffer if(setq lsp-print-io t)
- VSCode: TODO
You can also use sysdig on Linux:
sudo sysdig -As999 --unbuffered -p '%evt.type %proc.name %evt.buffer' "proc.exe contains ccls and fd.type=pipe" | egrep -v '^Content|^$'
To debug individual LSP requests, you can attach your debugger after ccls has done indexing. However,
for many other issues, such as project file loading (project.cc
) and C/C++ parsing and indexing clang_indexer.cc
, you need to set an early breakpoint to be able to trace the code.
It is recommended to use LanguageClient-neovim for debugging (even if you use Emacs or VSCode) because it can be started with simple shell command.
# vimrc
nn ,al :LanguageClientStart<cr>
rm -r /tmp/ccls && CQUERY_TRACEME=1 nvim a.cc +'normal ,al'
The Neovim buffer will hang there because CCLS_TRACEME=1
causes the ccls
process to SIGTSTP itself. In another shell, gdb -p $(pgrep -fn debug/ccls)
Insert an infinite loop volatile static int z=0;while(!z);
somewhere and ccls will stop there. Attach to the ccls process with gdb -p $(pgrep -fn ccls)
. Set some breakpoints, use print
commands, and execute p z=1
for continuing.
When setting breakpoints, if several threads may stop on the same breakpoint (e.g. concurrent indexer threads),
execute set scheduler-locking on
.
Cache files are deleted to avoid possible issues related to stale cache. CCLS_TRACEME=1
causes the ccls process to stop at the start of main()
. You may attach to the process with:
-
gdb -p $(pgrep -fn ccls)
. Invokesignal SIGCONT
if you want ccls to continue running after detaching of gdb. -
lldb -p $(pgrep -fn ccls)
. Invokepro sig SIGCONT
when the process resumes (with ac
command) if you want ccls to continue running after detaching.
export LIBCLANG_DISABLE_CRASH_RECOVERY=1
disables libclang crash recovery. In case of libclang or indexer callback issues, you will not see libclang: crash detected
in the log file but get a process crash. And if you attach a debugger before it crashes, you can get the stack trace.
Set breakpoints in src/messages/*
files. They are inbound message handlers.