3 ms·
Hmm, you immediately knew that async IO was the culprit... but it wasn't, according to the article. The function that called the async IO (which was a Windows A
by quietbritishjim 5y ago
Hmm, you immediately knew that async IO was the culprit... but it wasn't, according to the article. The function that called the async IO (which was a Windows API function, not in Unity) was correctly waiting until the IO completed before releasing the struct (by returning).
The actual problem was that the rug was being whipped from under it by an exception being injected into a place where it ought to have been impossible. Your suggestion of using heap allocation instead wouldn't have fixed anything; it would've turned the crash into a memory leak, which would've just masked the the problem.
The solution they went for in the end addressed this real issue, and the async IO (happening under the hood of that Windows API function) remains unchanged.
- vardump 5y agoWell, overlapped (=async) IO was what ultimately overwrote stack memory. The hazard pattern I recognized from previous experience. Of course exception in the queued APC was the reason why select's WFSO was prematurely interrupted and stack rewound, so the bug was of course there. It's pretty dangerous to execute code in the context of a waiting thread. While the solution to fix it by using heap allocation is a bit ugly in some sense, if your choices are to abort execution completely or to infrequently leak some bytes of memory, I know I'd choose to leak and perhaps log what just happened. There are rare cases when the I/O never completes and CancelIo doesn't complete either. Probably hardware faults or kernel driver bugs. Stuff that should absolutely never happen, but can still be defensively programmed around.