Description
It seems that opening a handle with a path that doesn't exist can cause crashes when (potentially unrelated) code later tries to access it:
local handle
handle = uv.fs_open("does-not-exist", "r", 438, function(err, fd)
print(err, fd)
print(type(handle))
print(handle)
error("this is never executed")
end)
print(type(handle))
print(handle)
uv.walk(function(_)
error("this is never executed either")
end)
The program is halted with an assertion failure, which is triggered by a somewhat unreliable sanity check in src/loop.c
:
userdata
uv_fs_t: 0x01f4064047a8
Assertion failed: data && data->ref < 0x1000000, file /tmp/luv/src/loop.c, line 98
Occasionally, this sanity check fails and the program simply SEGFAULTs when trying to invoke the callback:
userdata
uv_fs_t: 0x02ddabb3c7d8
[1] 9817 segmentation fault
The handle itself appears to be active, but its context (data->ctx
) is NULL
. There were some issues mentioning cleanup and callback interactions; this may be related. Attempting to use the handle inside the callback, without uv.walk
, also fails (uv.run()
is implied):
local handle
handle = uv.fs_open("does-not-exist", "r", 438, function(err, fd)
print(err, fd)
print(type(handle))
print(handle)
error("this is never executed")
end)
The resulting Lua error is technically preventable since the err
and fd
values indicate a failure, but it could still be slightly confusing:
ENOENT: no such file or directory: does-not-exist nil
userdata
Uncaught Error: bad argument #1 to '?' (Expected uv_req_t)
I encountered this issue while queuing FS requests with some observability code enabled, which required walking all handles. There's no obvious way of guarding against these crashes, so that even a simple typo in a file system path could bring down the entire application.
Tested on Windows and Linux (Ubuntu) using the latest LuaJIT build. This doesn't look like a platform-specific problem, though.