New submission from Steve Dower <[email protected]>:
Most Win32 API calls are made within Py_BEGIN_ALLOW_THREADS blocks, as they do
not access Python objects and so we can release the GIL.
However, in general, error handling occurs after the Py_END_ALLOW_THREADS line.
Due to the design of the Win32 API, the pattern looks like this:
Py_BEGIN_ALLOW_THREADS
ret = ApiCall(...);
Py_END_ALLOW_THREADS
if (FAILED(ret)) {
error_code = GetLastError();
}
However, Py_END_ALLOW_THREADS also makes Win32 API calls (to acquire the GIL),
and if any of these fail then the error code may be overwritten.
Failures in Py_END_ALLOW_THREADS are either fatal (in which case we don't care
about the preceding error any more) or signal a retry (in which case we *do*
care about the preceding error), but in the latter case we may have lost the
error code.
Further, while Win32 APIs are not _supposed_ to set the last error to
ERROR_SUCCESS (0) when they succeed, some occasionally do.
We should update Py_END_ALLOW_THREADS to preserve the last error code when
necessary. Ideally, if we don't have to do any work to reacquire the GIL, we
shouldn't do any work to preserve the error code either.
----------
components: Windows
messages: 313447
nosy: paul.moore, steve.dower, tim.golden, zach.ware
priority: normal
severity: normal
stage: test needed
status: open
title: GetLastError() may be overwritten by Py_END_ALLOW_THREADS
type: behavior
versions: Python 3.6, Python 3.7, Python 3.8
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue33030>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com