mirror of
https://github.com/neovim/neovim.git
synced 2026-08-27 09:31:47 +00:00
fix(channel): crash on failed sockconnect() (#37811)
Problem: Crash on failed sockconnect() if a new connection is accepted
while polling for uv events.
Solution: Don't use channel_destroy_early().
Also test "tcp" mode failure properly.
This commit is contained in:
@@ -474,7 +474,9 @@ uint64_t channel_connect(bool tcp, const char *address, bool rpc, CallbackReader
|
|||||||
channel = channel_alloc(kChannelStreamSocket);
|
channel = channel_alloc(kChannelStreamSocket);
|
||||||
if (!socket_connect(&main_loop, &channel->stream.socket,
|
if (!socket_connect(&main_loop, &channel->stream.socket,
|
||||||
tcp, address, timeout, error)) {
|
tcp, address, timeout, error)) {
|
||||||
channel_destroy_early(channel);
|
// Don't use channel_destroy_early() as new channels may have been allocated
|
||||||
|
// by channel_from_connection() while polling for uv events.
|
||||||
|
channel_decref(channel);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -478,9 +478,31 @@ describe('channels', function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
it('in "tcp" mode', function()
|
it('in "tcp" mode', function()
|
||||||
|
skip(not is_os('linux'), 'FIXME: hangs on non-Linux')
|
||||||
eq(
|
eq(
|
||||||
'Vim:connection failed: connection refused',
|
'Vim:connection failed: connection refused',
|
||||||
pcall_err(fn.sockconnect, 'pipe', '127.0.0.1:0')
|
pcall_err(fn.sockconnect, 'tcp', '127.0.0.1:0')
|
||||||
|
)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('with another connection accepted while polling #37807', function()
|
||||||
|
local server = api.nvim_get_vvar('servername')
|
||||||
|
local invalid_pipe = n.new_pipename()
|
||||||
|
exec_lua(function()
|
||||||
|
vim.defer_fn(function()
|
||||||
|
vim.uv.sleep(50) -- Block the uv event loop.
|
||||||
|
vim.fn.sockconnect('pipe', invalid_pipe)
|
||||||
|
end, 10)
|
||||||
|
end)
|
||||||
|
vim.uv.sleep(20)
|
||||||
|
-- The server uv event loop is currently blocked, so the connection will
|
||||||
|
-- be accepted when sockconnect() polls.
|
||||||
|
local other_session = n.connect(server)
|
||||||
|
eq({ true, { 1000 } }, { other_session:request('nvim_list_wins') })
|
||||||
|
other_session:close()
|
||||||
|
matches(
|
||||||
|
'^vim.schedule callback: Vim:connection failed: connection refused\n',
|
||||||
|
api.nvim_get_vvar('errmsg')
|
||||||
)
|
)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|||||||
Reference in New Issue
Block a user