[PATCH 3/3] ntdll: fix up instruction pointer in context insideraise_exception

Peter Oberndorfer kumbayo84 at arcor.de
Mon Feb 19 13:14:39 CST 2007


On Monday 19 February 2007 09:37, Dmitry Timoshkov wrote:
> "Peter Oberndorfer" <kumbayo84 at arcor.de> wrote:
> 
> > I'm not fully sure if the fixup also happens for other architectures
> > (i guess not)
> > so this patch is more a RFC
> 
> > @@ -336,6 +336,10 @@ static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL f
> >          if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED)
> >              return STATUS_SUCCESS;
> >  
> > +        /* fix up instruction pointer in context for EXCEPTION_BREAKPOINT */
> > +        if (rec->ExceptionCode == EXCEPTION_BREAKPOINT)
> > +            GET_IP(context) = (DWORD_PTR)GET_IP(context) - 1;
> 
> Gary Nebbett's book "Windows Nt/2000 Native API Reference" in the section C
> "Exceptions and Debugging" provides a pseudocode for KiDispatchException
> (page 439, Example C.1), and it does exactly the same thing as the patch
> above. *But* it does it as a very first thing after getting the context and
> before sending the debugger event.
> 
The strange thing is my testcase [patch 2/3] shows/(should show) that the debugger gets a unmodified eip for a first chance exception
+                    if (de.u.Exception.dwFirstChance)
+                    {
+                        /* debugger gets first chance exception with unmodified ctx.Eip */
+                        ok((DWORD)ctx.Eip == (DWORD)code_mem_address + 0xb, "Eip at %x instead of 0x%x\n",
+                            ctx.Eip, (DWORD)code_mem_address + 0xb);

and the modified one when the application did not handle the exception

+                    else
+                    {
+                        /* debugger gets context after exception handler has played with it */
+                        /* ctx.Eip is the same value the exception handler got */
+                        if (de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT)
+                        {
+                            todo_wine{
+                            ok((DWORD)ctx.Eip == (DWORD)code_mem_address + 0xa, "Eip at %x instead of 0x%x\n",
+                                ctx.Eip, (DWORD)code_mem_address + 0xa);
+                            }

i tested this testcase on XP and 2K

Unfortunetely i don't own that book :-(
Could you please verify in the pseudocode that the modified context gets sent to the debugger,
and not some unmodified copy?
Or maybe they unfix the context again in the send_to_debugger function ;-)
Or the pseudo code is not fully correct.

Thanks,
Greetings Peter



More information about the wine-devel mailing list