GetLastError() (with and without debugger)
David Holmes
david.holmes at oracle.com
Mon Aug 15 21:54:17 UTC 2022
On 16/08/2022 1:10 am, Pedro Lamarão wrote:
> Em seg., 15 de ago. de 2022 às 05:05, David Holmes
> <david.holmes at oracle.com <mailto:david.holmes at oracle.com>> escreveu:
>
> On 13/08/2022 2:05 am, Maurizio Cimadamore wrote:
> > If this is a problem with the debugger accidentally overwriting
> > LastError on some platforms, I think it would be perhaps better
> to fix
> > it at that level (given that our JVM has some code to defend against
> > similar accidental overwrites, I'm assuming that it is possible
> for the
> > JVM code/debugger code to act in a "transparent" fashion).
>
> PreserveLastError is just a helper for logging, so that the I/O from
> the
> logging doesn't overwrite any error from the real native operation.
>
>
> I think this is the correct general solution.
Saving and restoring the last-error across a call to "foreign code" is
the general solution**. PreserveLastError is a specific implementation
of that in the low-level Windows code - it isn't something generally
available.
** If you can actually wrap all such "entry" points.
> Fixing this in general would require that we define the required
> thread-local state to be preserved, and then save that after each
> native
> method invocation and restore it before the next. But that in itself
> would limit the effectiveness as it can't distinguish between
> application level native methods and library level (including things
> triggered from the VM).
>
>
> Consider this code:
>
> write(...)
> call-into-some-library-function(...)
> log(last-error())
>
> This is not the generally correct way to observe the status of write.
> It is not, generally, a library's responsibility to preserve last-error.
Much of the code we are talking about is also considered "library" code.
> The generally correct way is to observe the last-error immediately.
It is the only correct way.
> What matters is that the code below observes the status of write.
>
> write(...)
> log(last-error())
>
> If there is some code running somewhere with the power of affecting
> last-error on this thread, that code must be very careful to preserve it.
Yet you say it is not a library's responsibility to do that? How is the
library less responsible than a call to class-loading, or running an
event handler, or entering the debugger?
> It has been supposed that the OP's debugger is doing I/O from inside the
> application's thread;
> if that is the case, then this debugger must do something like
> PreserveLastError.
Even if it did that would not be sufficient as you would need a general
solution for preserving it between the user function that sets it, and
the user function that wants to read it. The handler for a method exit
event could also overwrite last-error before the debugger gets a chance
to preserve anything. I don't know if the way the debugger operates even
allows for conceptually saving and restoring the last-error across
debugger "entry points".
Cheers,
David
-----
> --
> Pedro Lamarão
More information about the panama-dev
mailing list