Quick links: help overview · quick reference · user manual toc · reference manual toc
Go to keyword (shortcut: k)
Site search (shortcut: s)
dev_tools.txt          Nvim


                            NVIM REFERENCE MANUAL


Tools and techniques for developing Nvim                        dev-tools

The following advice is helpful when working on or debugging issues with Nvim
itself. See also debug.txt for advice that applies to Vim.

                                  Type gO to see the table of contents.

==============================================================================
Backtraces                                            dev-tools-backtrace

LINUX 

Core dumps are disabled by default on Ubuntu
https://stackoverflow.com/a/18368068, CentOS and others. To enable core dumps:
>bash
    ulimit -c unlimited
<
On systemd-based systems getting a backtrace is as easy as:
>bash
    coredumpctl -1 gdb
<
It's an optional tool, so you may need to install it:
>bash
    sudo apt install systemd-coredump
<

The full backtrace is most useful, send us the bt.txt file:
>bash
    2>&1 coredumpctl -1 gdb | tee -a bt.txt
    thread apply all bt full
<
On older systems a core file will appear in the current directory. To get
a backtrace from the core file:
>bash
    gdb build/bin/nvim core 2>&1 | tee backtrace.txt
    thread apply all bt full
<

MACOS

If nvim crashes, you can see the backtrace in Console.app (under "Crash
Reports" or "User Diagnostic Reports" for older macOS versions).
>bash
    open -a Console
<
You may also want to enable core dumps on macOS. To do this, first make sure
the /cores/ directory exists and is writable:
>bash
    sudo mkdir /cores
    sudo chown root:admin /cores
    sudo chmod 1775 /cores
<
Then set the core size limit to unlimited:
>bash
    ulimit -c unlimited
<
Note that this is done per shell process. If you want to make this the default
for all shells, add the above line to your shell's init file (e.g. ~/.bashrc
or similar).

You can then open the core file in lldb:
>bash
    lldb -c /cores/core.12345
<
Apple's documentation archive has some other useful information
https://developer.apple.com/library/archive/technotes/tn2124/_index.html#//apple_ref/doc/uid/DTS10003391-CH1-SECCOREDUMPS,
but note that some of the things on this page are out of date (such as enabling
core dumps with /etc/launchd.conf).

==============================================================================
Gdb                                                          dev-tools-gdb

USING GDB TO STEP THROUGH FUNCTIONAL TESTS 

Use TEST_TAG to run tests matching busted tags (of the form #foo e.g.
`it("test #foo ...", ...)`):
>bash
    GDB=1 TEST_TAG=foo make functionaltest
<
Then, in another terminal:
>bash
    gdb build/bin/nvim
    target remote localhost:7777

-- See nvim_argv in https://github.com/neovim/neovim/blob/master/test/functional/testnvim.lua.

USING LLDB TO STEP THROUGH UNIT TESTS 

>bash
    lldb .deps/usr/bin/luajit -- .deps/usr/bin/busted --lpath="./build/?.lua" test/unit/
<

USING GDB 

To attach to a running nvim process with a pid of 1234:
>bash
    gdb -tui -p 1234 build/bin/nvim
<
The gdb interactive prompt will appear. At any time you can:

- `break foo` to set a breakpoint on the foo() function
- n to step over the next statement
    - <Enter> to repeat the last command
- s to step into the next statement
- c to continue
- finish to step out of the current function
- `p zub` to print the value of zub
- bt to see a backtrace (callstack) from the current location
- `CTRL-x CTRL-a` or `tui enable` to show a TUI view of the source file in the
  current debugging context. This can be extremely useful as it avoids the
  need for a gdb "frontend".
- <up> and <down> to scroll the source file view


GDB "REVERSE DEBUGGING" 

- `set record full insn-number-max unlimited`
- continue for a bit (at least until main() is executed
- record
- provoke the bug, then use revert-next, reverse-step, etc. to rewind the
  debugger


USING GDBSERVER 

You may want to connect multiple gdb clients to the same running nvim
process, or you may want to connect to a remote nvim process with a local
gdb. Using gdbserver, you can attach to a single process and control it
from multiple gdb clients.

Open a terminal and start gdbserver attached to nvim like this:
>bash
    gdbserver :6666 build/bin/nvim 2> gdbserver.log
<
gdbserver is now listening on port 6666. You then need to attach to this
debugging session in another terminal:
>bash
    gdb build/bin/nvim
<
Once you've entered gdb, you need to attach to the remote session:

    target remote localhost:6666

In case gdbserver puts the TUI as a background process, the TUI can become
unable to read input from pty (and receives SIGTTIN signal) and/or output data
(SIGTTOU signal). To force the TUI as the foreground process, you can add

    signal (SIGTTOU, SIG_IGN);
    if (!tcsetpgrp(data->input.in_fd, getpid())) {
        perror("tcsetpgrp failed");
    }

to tui.c:terminfo_start.


USING GDBSERVER IN TMUX 

Consider using a custom makefile
https://github.com/neovim/neovim/blob/master/BUILD.md#custom-makefile to
quickly start debugging sessions using the gdbserver method mentioned above.
This example local.mk will create the debugging session when you type `make
debug`.
>make
    .PHONY: dbg-start dbg-attach debug build

    build:
        @$(MAKE) nvim

    dbg-start: build
        @tmux new-window -n 'dbg-neovim' 'gdbserver :6666 ./build/bin/nvim -D'

    dbg-attach:
        @tmux new-window -n 'dbg-cgdb' 'cgdb -x gdb_start.sh ./build/bin/nvim'

    debug: dbg-start dbg-attach
<
Here gdb_start.sh includes gdb commands to be called when the debugger
starts. It needs to attach to the server started by the dbg-start rule. For
example:

    target remote localhost:6666
    br main


vim:tw=78:ts=8:et:ft=help:norl:


Quick links: help overview · quick reference · user manual toc · reference manual toc