[PATCH] ntdll: Don't reset rsp to context->Rsp until exception data is copied.

Paul Gofman pgofman at codeweavers.com
Thu Jul 2 05:05:02 CDT 2020

On 7/2/20 12:55, Alexandre Julliard wrote:
> Paul Gofman <pgofman at codeweavers.com> writes:
>> On 7/2/20 12:09, Alexandre Julliard wrote:
>>> Paul Gofman <pgofman at codeweavers.com> writes:
>>>> Context record may be stored on stack below context stack. This
>>>> happens, e. g., with RtlRaiseException().
>>> That doesn't seem right, there may be other things on the stack too. Is
>>> there a reason to switch stack to context->Rsp at all?
>> Exception unwinding does not work otherwise, and that matches stack
>> layout on Windows: the context and exception record on stack has a fixed
>> gap after context's Rsp. But it looks we don't need anything else from
>> the stack besides the context, or am I missing something?
> Potentially the exception record, if we allow things to be below
> context->Rsp. Maybe RtlRaiseException is not setting the right Rsp?
> This could use a few more tests.
We could change RtlRaiseException() to set up the stack in a way it is
usable for passing to KiUserExceptionDispatcher and thus avoid copying
context at all, but this way NtRaiseException() would rely on being
called from RtlRaiseException(), while it works other ways too.

What I see from additional tests on Windows is that in
KiUserExceptionDispatcher hook the rsp (that is, context pointer) has
offset 0x710 from context->Rsp, regardless of how NtRaiseException is
called: directly or through RtlRaiseException() with BeingDebugged set
to TRUE. The same offset is from fault. So I am not sure how changing
RtlRaiseException() can bring that all in line? Maybe I can just save
exception record on the current stack before copying context to avoid
potential problems?

I guess some part of trickiness here comes from the fact that unlike
Windows kernel part we have the same stack in unix part.

As a separate note, I noticed during testing that NtRaiseException() can
capture the context itself if the context flags don't have
CONTEXT_CONTROL flag (otherwise it uses the given context even if it is
completely bogus). But this doesn't seem related here.

More information about the wine-devel mailing list