From ffce5f4f66ae25ec29a68fae6b76f5e73c27af6e Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sat, 30 Jun 2007 18:58:09 +0000 Subject: [PATCH] - Commit a fix for KDBG's attach to process problem. See issue #1263 for more details. svn path=/trunk/; revision=27348 --- reactos/ntoskrnl/kdbg/kdb.c | 46 +++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/reactos/ntoskrnl/kdbg/kdb.c b/reactos/ntoskrnl/kdbg/kdb.c index a2bab606a96..4bbd0cfbfd8 100644 --- a/reactos/ntoskrnl/kdbg/kdb.c +++ b/reactos/ntoskrnl/kdbg/kdb.c @@ -168,6 +168,29 @@ KdbpKdbTrapFrameToTrapFrame(PKDB_KTRAP_FRAME KdbTrapFrame, PKTRAP_FRAME TrapFram /* FIXME: copy v86 registers if TrapFrame is a V86 trapframe */ } +STATIC VOID +KdbpKdbTrapFrameFromKernelStack(PVOID KernelStack, + PKDB_KTRAP_FRAME KdbTrapFrame) +{ + ULONG_PTR *StackPtr; + + RtlZeroMemory(KdbTrapFrame, sizeof(KDB_KTRAP_FRAME)); + StackPtr = (ULONG_PTR *) KernelStack; + KdbTrapFrame->Tf.Ebp = StackPtr[3]; + KdbTrapFrame->Tf.Edi = StackPtr[4]; + KdbTrapFrame->Tf.Esi = StackPtr[5]; + KdbTrapFrame->Tf.Ebx = StackPtr[6]; + KdbTrapFrame->Tf.Eip = StackPtr[7]; + KdbTrapFrame->Tf.HardwareEsp = (ULONG) (StackPtr + 8); + KdbTrapFrame->Tf.HardwareSegSs = KGDT_R0_DATA; + KdbTrapFrame->Tf.SegCs = KGDT_R0_CODE; + KdbTrapFrame->Tf.SegDs = KGDT_R0_DATA; + KdbTrapFrame->Tf.SegEs = KGDT_R0_DATA; + KdbTrapFrame->Tf.SegGs = KGDT_R0_DATA; + + /* FIXME: what about the other registers??? */ +} + /*!\brief Overwrites the instruction at \a Address with \a NewInst and stores * the old instruction in *OldInst. * @@ -1040,7 +1063,8 @@ KdbpAttachToThread( if (KdbCurrentThread != KdbOriginalThread) { ASSERT(KdbCurrentTrapFrame == &KdbThreadTrapFrame); - KdbpKdbTrapFrameToTrapFrame(KdbCurrentTrapFrame, KdbCurrentThread->Tcb.TrapFrame); + /* Actually, we can't save the context, there's no guarantee that there + * was a trap frame */ } else { @@ -1050,12 +1074,13 @@ KdbpAttachToThread( /* Switch to the thread's context */ if (Thread != KdbOriginalThread) { - if (Thread->Tcb.TrapFrame == NULL) - { - KdbpPrint("Threads TrapFrame is NULL! Cannot attach.\n"); - return FALSE; - } - KdbpTrapFrameToKdbTrapFrame(Thread->Tcb.TrapFrame, &KdbThreadTrapFrame); + /* The thread we're attaching to isn't the thread on which we entered + * kdb and so the thread we're attaching to is not running. There + * is no guarantee that it actually has a trap frame. So we have to + * peek directly at the registers which were saved on the stack when the + * thread was preempted in the scheduler */ + KdbpKdbTrapFrameFromKernelStack(Thread->Tcb.KernelStack, + &KdbThreadTrapFrame); KdbCurrentTrapFrame = &KdbThreadTrapFrame; } else /* Switching back to original thread */ @@ -1529,11 +1554,8 @@ KdbEnterDebuggerException( } } - /* Save the current thread's trapframe */ - if (KdbCurrentTrapFrame == &KdbThreadTrapFrame) - { - KdbpKdbTrapFrameToTrapFrame(KdbCurrentTrapFrame, KdbCurrentThread->Tcb.TrapFrame); - } + /* We can't update the current thread's trapframe 'cause it might not + have one */ /* Detach from attached process */ if (KdbCurrentProcess != KdbOriginalProcess)