Port wiki pages which I created in the cquery repo

Fangrui Song 2018-03-30 23:53:24 -07:00
parent cd6e534ac6
commit 06918331a4

63
Debugging.md Normal file

@ -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<cr>
```
```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.