Closed filipnavara closed 5 years ago
The underlying error is that TLS access destroys the last error value before it is recorded on the return from P/Invoke call. The first place where it gets destroyed is
There are likely others on the code path. A broad fix attempted in #15465 worked but it was rejected. A more targeted fix attempted in #15534 did NOT work which likely means that there are more places where the TLS access screws things up.
MSVC builds are not affected because they use __declspec(thread)
TLS access instead of TlsGetValue
API.
There is more than one code path in the interpreter that can hit this error:
Fix for this problem should be in interpreter, it needs to preserve the last error just after the p/invoke, currently it runs MINT_MONO_LDPTR and an additional MINT_CALLI_NAT_FAST to read it before storing it using mono_marshal_set_last_error. This is done since it uses the wrapper generated by emit_native_wrapper_ilgen. In JIT that is fine since the lowering will be a call direct after p/invoke, but in interpreter it needs to run the above instructions through the interpreter loop and that will clobber last error value.
https://github.com/mono/mono/pull/15571 should take care of this issue.
Ran above tests on mingw 64-bit build mono runtime using interpreter and with the fix in #15571 I get:
False (expected false) 6 (expected 6)
So looks like it gets the expected behavior.
There is a test in tests/last-error.cs.
Yes, I have run it locally with JIT+ Interpreter as well on both msvc as well as mingw. CI only uses msvc build, where it doesn't reproduce.
Fixed by #15571.
Steps to Reproduce
MONO_ENV_OPTIONS=--interp
:Current Behavior
Prints
false
and0
.Expected Behavior
Prints
false
and6
.On which platforms did you notice this
[ ] macOS [ ] Linux [x] Windows
Version Used:
Mono 6.5 e301847