[pypy-dev] errno and GetLastError in RPython

Armin Rigo arigo at tunes.org
Fri Jan 23 10:28:50 CET 2015


Hi all,

I recently merged the "errno-again" branch.  This branch moves the
reading/saving of errno (and on Windows Get/SetLastError) closer to
the actual function call.  It should avoid bugs about rarely getting
the wrong value for errno, in case "something special" happened: for
example, it was not impossible that a call to malloc would invoke the
GC at precisely the wrong spot, which might need to ask the OS for
more memory, which would overwrite the current value of errno.  The
bug actually showed up on the Windows buildbots for GetLastError(),
which would in some cases incorrectly return 0 just if the code
happened to be JIT-traced (not before and not after).  This is now
fixed.

It means any RPython project needs to be updated when it upgrades to
the trunk version of the RPython translation toolchain.  The fix is
rather mechanical.

Replace rposix.get_errno() with rposix.get_saved_errno().
Importantly, review each place that you change.  You need to make sure
which external function call is done before (usually in the few lines
before).  Once you're sure which function's errno is being checked, go
to the declaration of that function, which should be using
rffi.llexternal().  Add the keyword argument
"save_err=rffi.RFFI_SAVE_ERRNO".  This forces errno to be saved
immediately after the function call, into the so-called "saved errno".
This "saved errno" is another thread-local variable, which
rposix.get_saved_errno() returns.

Similarly with rwin32.GetLastValue() -> rwin32.GetLastValue_saved() +
rffi.RFFI_SAVE_LASTERROR.

If there are cases with rposix.set_errno(0), they can be killed and
the following function given the flag "RFFI_ZERO_ERRNO_BEFORE".

See the new docstrings of the rposix.get/set_saved_errno() and
rwin32.Get/SetLastValue_saved() for more details.


A bientôt,

Armin.


More information about the pypy-dev mailing list