dev_tools.txt 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. *dev_tools.txt* Nvim
  2. NVIM REFERENCE MANUAL
  3. Tools and techniques for developing Nvim *dev-tools*
  4. The following advice is helpful when working on or debugging issues with Nvim
  5. itself.
  6. TODO: merge |debug.txt| into here.
  7. Type |gO| to see the table of contents.
  8. ==============================================================================
  9. Backtraces *dev-tools-backtrace*
  10. LINUX
  11. Core dumps are disabled by default on Ubuntu, CentOS and others.
  12. To enable core dumps:
  13. >bash
  14. ulimit -c unlimited
  15. <
  16. On systemd-based systems getting a backtrace is as easy as:
  17. >bash
  18. coredumpctl -1 gdb
  19. <
  20. `coredumpctl` is an optional tool, so you may need to install it:
  21. >bash
  22. sudo apt install systemd-coredump
  23. <
  24. The full backtrace is most useful; please send us the `backtrace.txt` file
  25. when reporting a bug related to a crash:
  26. >bash
  27. 2>&1 coredumpctl -1 gdb | tee -a backtrace.txt
  28. (gdb) thread apply all bt full
  29. <
  30. On systems without `coredumpctl`, you may find a `core` dump file appearing
  31. in the current directory or in other locations. On Linux systems where
  32. `apport` is installed (such as Ubuntu), the directory where core dump files
  33. are saved can be `/var/lib/apport/coredump` or elsewhere, depending on the
  34. system configuration (see `/proc/sys/kernel/core_pattern`). See also:
  35. https://stackoverflow.com/a/18368068
  36. To get a backtrace from the `./core` dump file:
  37. >bash
  38. gdb build/bin/nvim ./core 2>&1 | tee backtrace.txt
  39. (gdb) thread apply all bt full
  40. <
  41. MACOS
  42. If `nvim` crashes, you can see the backtrace in `Console.app` (under "Crash
  43. Reports" or "User Diagnostic Reports" for older macOS versions).
  44. >bash
  45. open -a Console
  46. <
  47. You may also want to enable core dumps on macOS. To do this, first make sure
  48. the `/cores/` directory exists and is writable:
  49. >bash
  50. sudo mkdir /cores
  51. sudo chown root:admin /cores
  52. sudo chmod 1775 /cores
  53. <
  54. Then set the core size limit to `unlimited`:
  55. >bash
  56. ulimit -c unlimited
  57. <
  58. Note that this is done per shell process. If you want to make this the default
  59. for all shells, add the above line to your shell's init file (e.g. `~/.bashrc`
  60. or similar).
  61. You can then open the core file in `lldb`:
  62. >bash
  63. lldb -c /cores/core.12345
  64. <
  65. Apple's documentation archive has some other useful information
  66. https://developer.apple.com/library/archive/technotes/tn2124/_index.html#//apple_ref/doc/uid/DTS10003391-CH1-SECCOREDUMPS,
  67. but note that some of the things on this page are out of date (such as enabling
  68. core dumps with `/etc/launchd.conf`).
  69. ==============================================================================
  70. Gdb *dev-tools-gdb*
  71. USING GDB TO STEP THROUGH FUNCTIONAL TESTS
  72. Use `TEST_TAG` to run tests matching busted tags (of the form `#foo` e.g.
  73. `it("test #foo ...", ...)`):
  74. >bash
  75. GDB=1 TEST_TAG=foo make functionaltest
  76. <
  77. Then, in another terminal:
  78. >bash
  79. gdb build/bin/nvim
  80. (gdb) target remote localhost:7777
  81. -- See `nvim_argv` in https://github.com/neovim/neovim/blob/master/test/functional/testnvim.lua.
  82. USING LLDB TO STEP THROUGH UNIT TESTS
  83. >
  84. lldb .deps/usr/bin/luajit -- .deps/usr/bin/busted --lpath="./build/?.lua" test/unit/
  85. <
  86. USING GDB
  87. To attach to a running `nvim` process with a pid of 1234 (Tip: the pid of a
  88. running Nvim instance can be obtained by calling |getpid()|), for instance:
  89. >bash
  90. gdb -tui -p 1234 build/bin/nvim
  91. <
  92. The `gdb` interactive prompt will appear. At any time you can:
  93. - `break foo` to set a breakpoint on the `foo()` function
  94. - `n` to step over the next statement
  95. - `<Enter>` to repeat the last command
  96. - `s` to step into the next statement
  97. - `c` to continue
  98. - `finish` to step out of the current function
  99. - `p zub` to print the value of `zub`
  100. - `bt` to see a backtrace (callstack) from the current location
  101. - `CTRL-x CTRL-a` or `tui enable` to show a TUI view of the source file in the
  102. current debugging context. This can be extremely useful as it avoids the
  103. need for a gdb "frontend".
  104. - `<up>` and `<down>` to scroll the source file view
  105. GDB REVERSE DEBUGGING
  106. - `set record full insn-number-max unlimited`
  107. - `continue` for a bit (at least until `main()` is executed
  108. - `record`
  109. - provoke the bug, then use `revert-next`, `reverse-step`, etc. to rewind the
  110. debugger
  111. USING GDBSERVER
  112. You may want to connect multiple `gdb` clients to the same running `nvim`
  113. process, or you may want to connect to a remote `nvim` process with a local
  114. `gdb`. Using `gdbserver`, you can attach to a single process and control it
  115. from multiple `gdb` clients.
  116. Open a terminal and start `gdbserver` attached to `nvim` like this:
  117. >bash
  118. gdbserver :6666 build/bin/nvim 2> gdbserver.log
  119. <
  120. `gdbserver` is now listening on port 6666. You then need to attach to this
  121. debugging session in another terminal:
  122. >bash
  123. gdb build/bin/nvim
  124. <
  125. Once you've entered `gdb`, you need to attach to the remote session:
  126. >
  127. (gdb) target remote localhost:6666
  128. <
  129. In case gdbserver puts the TUI as a background process, the TUI can become
  130. unable to read input from pty (and receives SIGTTIN signal) and/or output data
  131. (SIGTTOU signal). To force the TUI as the foreground process, you can add
  132. >c
  133. signal (SIGTTOU, SIG_IGN);
  134. if (!tcsetpgrp(data->input.in_fd, getpid())) {
  135. perror("tcsetpgrp failed");
  136. }
  137. <
  138. to `tui.c:terminfo_start`.
  139. USING GDBSERVER IN TMUX
  140. Consider using a custom makefile
  141. https://github.com/neovim/neovim/blob/master/BUILD.md#custom-makefile to
  142. quickly start debugging sessions using the `gdbserver` method mentioned above.
  143. This example `local.mk` will create the debugging session when you type `make
  144. debug`.
  145. >make
  146. .PHONY: dbg-start dbg-attach debug build
  147. build:
  148. @$(MAKE) nvim
  149. dbg-start: build
  150. @tmux new-window -n 'dbg-neovim' 'gdbserver :6666 ./build/bin/nvim -D'
  151. dbg-attach:
  152. @tmux new-window -n 'dbg-cgdb' 'cgdb -x gdb_start.sh ./build/bin/nvim'
  153. debug: dbg-start dbg-attach
  154. <
  155. Here `gdb_start.sh` includes `gdb` commands to be called when the debugger
  156. starts. It needs to attach to the server started by the `dbg-start` rule. For
  157. example:
  158. >
  159. (gdb) target remote localhost:6666
  160. (gdb) br main
  161. <
  162. vim:tw=78:ts=8:et:ft=help:norl: