[runtime] Add write barriers for FindFirstFile/FindNextFile icalls (#4114)
authorAlexander Köplinger <alex.koeplinger@outlook.com>
Fri, 9 Dec 2016 13:01:06 +0000 (14:01 +0100)
committerGitHub <noreply@github.com>
Fri, 9 Dec 2016 13:01:06 +0000 (14:01 +0100)
commitdc8231a9d16189aa47c0eb6303cedc18799cee8d
tree1b03b689ff1fc5d6f30a593b81fc5c167b88bb5b
parentcf3f3aa8d1b9528cd6f2778d5ecfd250d3e6d040
[runtime] Add write barriers for FindFirstFile/FindNextFile icalls (#4114)

We were seeing crashes like [1] or [2] after https://github.com/mono/mono/pull/4042 was merged.
While debugging the issue I found out that when instead of using `out data.cFileName` for passing
the string through the the icall I use a temporary field and assign the result to `data` later on
the crash went away. It also worked if I made the `WIN32_FIND_DATA` class a struct instead.

I talked to @ludovic-henry and he was able to figure out what was going on (many thanks!):

> It seems to be a missing wbarrier
> and that would also explains why it would work with a struct, but not with a class
> so it would work with a struct, because `out data.filename` would be a `MonoString**` to the thread stack,
> and that would work because we would always scan the thread stack
> and it wouldn’t work with a class, because `out data.filename` would be a `MonoString**` to the heap
>
> and because we have a generational GC, if `data` is in the “old” heap (and because we are missing this write barrier),
> we would never scan `data`, thus freeing the `data.filename` string object, and as soon as you are trying to access it,
> well you access garbage
>
> with the write barrier, we will make sure to scan the `data` object, and not loose the reference to `data.filename`

[1] https://jenkins.mono-project.com/job/test-mono-mainline/label=osx-amd64/5422/parsed_console/log_content.html#WARNING1
[2] https://jenkins.mono-project.com/job/test-mono-mainline/label=osx-amd64/5419/parsed_console/log_content.html#WARNING1
[3] https://github.com/mono/mono/blob/dd88ff52e2f130ee188661a34794aa7c7b564fa8/mcs/class/referencesource/mscorlib/system/io/filesystemenumerable.cs#L280
mono/metadata/file-io.c