Crash in cmFileMonitor.cxx on directory change on Windows
on_directory_change
is the callback passed to uv_fs_event_start
, and on_directory_change
will unconditionally construct a std::string
from the filename
arguments passed on from libuv. The documentation from libuv says that the filename
argument may be NULL
. Constructing a std::string
from NULL
is illegal. In debug mode, this results in a crash.
libuv doesn't seem to document why filename
would be null, but I investigated further.
The reason libuv passes NULL
is because the OVERLAPPED
structure does not receive filesystem information in InternalHigh
which should say information about why libuv was notified about the filesystem change. InternalHigh
is only NULL
in the case of some error, where the error code is stored in the Internal
field of the OVERLAPPED
structure. In my test case, the Internal
value of OVERLAPPED
is 268
, which corresponds with the status STATUS_NOTIFY_ENUM_DIR
. The appearance of this status message is not documented and seems to actually be a bug in Windows and it seems to correspond to ERROR_NOTIFY_ENUM_DIR
, as discussed here. This happens when the buffer allocated to store the notification information is too small.
In this case, the notification is regarding the CMakeFiles
subdirectory of the build directory. My best guess is that there was a notification on too many files in the directory simultaneously to be stored properly. In this case, the directory watcher is not notified regarding a single file but is notified that the directory, in general, has multiple files changing within.
I'm not sure what the correct behavior might be. Perhaps drop the notification? Perhaps forward a notification for each file in the directory?