Notice (2018-05-24): bugzilla.xamarin.com is now in
Please join us on
Visual Studio Developer Community and in the
Mono organizations on
GitHub to continue tracking issues. Bugzilla will remain
available for reference in read-only mode. We will continue to work
on open Bugzilla bugs, copy them to the new locations
as needed for follow-up, and add the new items under Related
Our sincere thanks to everyone who has contributed on this bug
tracker over the years. Thanks also for your understanding as we
make these adjustments and improvements for the future.
Please create a new report on
GitHub or Developer Community with
your current version information, steps to reproduce, and relevant error
messages or log files if you are hitting an issue that looks similar to
this resolved bug and you do not yet see a matching new report.
The following fails on platforms that do _not_ have "large file support":
using (var f = File.Create (Path.Combine (
f.Lock (0, long.MaxValue);
It dies with:
> System.IO.IOException: Lock violation on path /data/data/Scratch.FileLocking/files/foo.dat
> at System.IO.FileStream.Lock (Int64 position, Int64 length) [0x00000] in <filename unknown>:0
The reason why: signed/unsigned mismatch.
LockFile() takes "logical" 64-bit offset and length values which are split into "high" and "low" values, and uses these values to call _wapi_lock_file_region(). The problem is the !HAVE_LARGE_FILE_SUPPORT block:
offset = offset_low;
length = length_low;
offset and length are `off_t`, and on non-large-file-support platforms `off_t` is a 32-bit int. Due to the value masking performed in ves_icall_System_IO_MonoIO_Lock(), length_low will be 0xFFFFFFFF (which is correct!), and thus the value of `length` will be -1 (which is the bug).
A plausible fix would be to change the offset & length assignment to instead be:
offset = offset_low > INT_MAX ? INT_MAX : offset_low;
length = length_low > INT_MAX ? INT_MAX : length_low;
ALTERNATIVELY: LockFile() should error out when we're on a 32-bit only platform and a 64-bit offset/region has been specified.
Alas, LockFile() doesn't specify an error to return when a "bad" offset is specified, so I'm not sure what's "correct". Erroring out seems to be the saner thing to do, though, as silently altering (truncating!) file offset + region lock length seems like a Bad Idea™.
> The following fails on platforms that do _not_ have "large file support":
It should fail; this is correct behavior.
The "problem" is that the error doesn't tell you what the error is:
> System.IO.IOException: Lock violation on path ...
Why is there a lock violation? There isn't one; the problem is that a parameter is invalid.
Fixed in master/6c5d76dd by checking for the overflows and setting ERROR_INVALID_PARAMETER instead of ERROR_LOCK_VIOLATION when LockFIle() is given unsupportable parameters.