From 06918331a401ea1f8bca1365b549a5f5db472c84 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 30 Mar 2018 23:53:24 -0700 Subject: [PATCH] Port wiki pages which I created in the cquery repo --- Debugging.md | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 Debugging.md diff --git a/Debugging.md b/Debugging.md new file mode 100644 index 0000000..8a4c6cd --- /dev/null +++ b/Debugging.md @@ -0,0 +1,63 @@ +First of all, use a `--variant=debug` [[Build]]. It is compiled with `-O0 -g` while the default `--variant=release` is `-O3 -g`. + +### Logs + +`--log-file=/tmp/cq.log` + +### Dump LSP requests/responses + +`--record=/tmp/ccls`: You can find stdin/stdout (LSP requests/responses) in `/tmp/cquery.{in,out}` + +Alternatively, enable logs and pass the `--log-all-to-stderr` option to the ccls executable (`bin/cquery --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: +```zsh +sudo sysdig -As999 --unbuffered -p '%evt.type %proc.name %evt.buffer' "proc.exe contains ccls and fd.type=pipe" | egrep -v '^Content|^$' +``` + +### Stopping at the start to debug early issues + +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|Neovim]] for debugging (even if you use Emacs or VSCode) because it can be started with simple shell command. + +```vim +# vimrc +nn ,al :LanguageClientStart +``` + +```zsh +rm -r /tmp/ccls && CQUERY_TRACEME=1 nvim a.cc +'normal ,al' +``` + +The Neovim buffer will hang there because `CCLS_TRACEME=1` causes the bin/cquery process to SIGTSTP itself. In another shell, `gdb -p $(pgrep -fn bin/cquery)` + +### Poor man's breakpoint + +Insert an infinite loop `volatile static int z=0;while(!z);` somewhere and ccls will stop there. Attach to the cquery process with `gdb -p $(pgrep -fn cquery)`. 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`. + +### Using a debugger + +Cache files are deleted to avoid possible issues related to stale cache. `CCLS_TRACEME=1` causes the cquery process to stop at the start of `main()`. You may attach to the process with: + +* `gdb -p $(pgrep -fn ccls)`. Invoke `signal SIGCONT` if you want cquery to continue running after detaching of gdb. +* `lldb -p $(pgrep -fn ccls)`. Invoke `pro sig SIGCONT` when the process resumes (with a `c` command) if you want cquery to continue running after detaching. + +### libclang or indexer callback issues + +`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. + + +## Developing + +### Diagnose whether requests are handled correctly + +Set breakpoints in `src/messages/*` files. They are inbound message handlers.