Repository: neovim
Issue: crash on self-attach via nvim_ui_attach RPC
Labels: channels-rpc,has:backtrace,bug-crash,ui-extensibility

### Problem

After **nvim_ui_attach()** call via RPC Neovim crashes on *unpacker_advance* function (./src/nvim/msgpack_rpc/unpacker.c), after **abort()** call. This only happens when I'm calling **nvim_ui_attach()** from Lua code, when I'm using Python and pynvim everything works fine. I mentioned this problem in [this](https://github.com/neovim/neovim/discussions/31682) discussion among other problems I faced.

Stack trace:

```shell
       Message: Process 30221 (nvim) of user 1000 dumped core.

                Stack trace of thread 30221:
                #0  0x000071ffc47763f4 n/a (libc.so.6 + 0x963f4)
                #1  0x000071ffc471d120 raise (libc.so.6 + 0x3d120)
                #2  0x000071ffc47044c3 abort (libc.so.6 + 0x244c3)
                #3  0x0000607571579803 unpacker_advance (nvim + 0x4c803)
                #4  0x00006075717e93ba internal_read_event (nvim + 0x2bc3ba)
                #5  0x00006075718e52e8 state_handle_k_event (nvim + 0x3b82e8)
                #6  0x0000607571802b71 nv_event (nvim + 0x2d5b71)
                #7  0x00006075717f1eb2 normal_execute (nvim + 0x2c4eb2)
                #8  0x00006075718ed211 state_enter (nvim + 0x3c0211)
                #9  0x00006075717eebca normal_enter (nvim + 0x2c1bca)
                #10 0x000060757157b0e7 main (nvim + 0x4e0e7)
                #11 0x000071ffc4705e08 n/a (libc.so.6 + 0x25e08)
                #12 0x000071ffc4705ecc __libc_start_main (libc.so.6 + 0x25ecc)
                #13 0x000060757157d285 _start (nvim + 0x50285)
                ELF object binary architecture: AMD x86-64
```

Lua code to reproduce this issue (also fail with `--clean` argument):

```lua
local I = function(v)
  print(vim.inspect(v))
end

if CHECK_EXTS_NVIM_CHANNEL then
  assert(vim.fn.chanclose(CHECK_EXTS_NVIM_CHANNEL) == 1)
  vim.notify("Previous channel was closed")
end
CHECK_EXTS_NVIM_CHANNEL = assert(vim.fn.sockconnect("pipe", vim.v.servername, {
  rpc = true,
}))

vim.fn.rpcrequest(
  CHECK_EXTS_NVIM_CHANNEL,
  "nvim_set_client_info",
  "it's me dude",
  vim.version(),
  "remote",
  vim.empty_dict(),
  vim.empty_dict()
)

vim.fn.rpcrequest(CHECK_EXTS_NVIM_CHANNEL, "nvim_eval", [['echo' . ' 12']])
vim.fn.rpcrequest(CHECK_EXTS_NVIM_CHANNEL, "nvim_exec2", "echomsg 12", {})

I(vim.fn.rpcrequest(CHECK_EXTS_NVIM_CHANNEL, "nvim_get_vvar", "servername"))
-- I(vim.fn.rpcrequest(CHECK_EXTS_NVIM_CHANNEL, "nvim_get_api_info"))

I({
  "nvim_ui_attach result",
  vim.fn.rpcrequest(
    CHECK_EXTS_NVIM_CHANNEL,
    "nvim_ui_attach",
    vim.o.columns,
    vim.o.lines,
    {
      ext_messages = false,
      ext_linegrid = true,
      ext_multigrid = false,
    }
  )
})
-- This print works
I("I'm here")
```

Working Python code:

```python
import functools
import os
from typing import List

import pynvim


def nvim_cb(prefix: str, event_name: str, events: List[str]) -> None:
    sep = "  "
    print(prefix, event_name)
    print(sep, end="")
    print(*events, sep="\n" + sep)


def main() -> None:
    # PID here
    nvim_pid = 1
    xdg_runtime_dir = os.getenv("XDG_RUNTIME_DIR")
    assert xdg_runtime_dir and os.path.isdir(xdg_runtime_dir)

    nvim = pynvim.attach(
        "socket",
        path=os.path.join(
            xdg_runtime_dir,
            f"nvim.{nvim_pid}.0",
        ),
    )
    nvim.ui_attach(1_000, 1_000, ext_linegrid=True, ext_multigrid=True)
    nvim.run_loop(
        functools.partial(nvim_cb, "request_cb"),
        functools.partial(nvim_cb, "notification_cb"),
    )


if __name__ == "__main__":
    main()
```

Used nightly (b51110f4a1), master (7567f7d322) and v0.10.3 (9b5ee7df3e) commits, all versions fail. I'm on Arch Linux, `Linux arch 6.12.3-arch1-1 #1 SMP PREEMPT_DYNAMIC Fri, 06 Dec 2024 11:15:43 +0000 x86_64 GNU/Linux`.

### Steps to reproduce

1. Run Lua script above (e.g., with `--clean`), you can see all the prints and then crash (SIGABRT after abort call()). Core dump should be the same as mine in the example above.
2. Open some Nvim, get its PID (`vim.fn.getpid()`). Run Python code (paste process ID in **nvim_pid** variable), see prints of UI events

### Expected behavior

Work w/o crash :)

### Nvim version (nvim -v)

NVIM v0.11.0-dev-1414+gb51110f4a1

### Vim (not Nvim) behaves the same?

vim doesn't have this API

### Operating system/version

Linux arch 6.12.3-arch1-1 #1 SMP PREEMPT_DYNAMIC Fri, 06 Dec 2024 11:15:43 +0000 x86_64 GNU/Linux

### Terminal name/version

alacritty 0.14.0-dev (d4f2f857)

### $TERM environment variable

alacritty

### Installation

Tried both AUR and self compiled versions