[ros-diffs] [fireball] 29332: - KeRosCaptureUserStackBackTrace is now created, which calls RtlWalkFrameChain with the user-mode flag, meaning that bugchecks finally show the user-mode stack again! - KeRosDumpStackFrames is fixed so that if the EIP can't be found in a module list, it's still displayed (just without the module name). Previously the EIP would not be shown, resulting in code running on the heap/stack/somewhere else not being shown as part of the trace.

fireball at svn.reactos.org fireball at svn.reactos.org
Mon Oct 1 19:58:50 CEST 2007


Author: fireball
Date: Mon Oct  1 21:58:49 2007
New Revision: 29332

URL: http://svn.reactos.org/svn/reactos?rev=29332&view=rev
Log:
- KeRosCaptureUserStackBackTrace is now created, which calls RtlWalkFrameChain with the user-mode flag, meaning that bugchecks finally show the user-mode stack again!
- KeRosDumpStackFrames is fixed so that if the EIP can't be found in a module list, it's still displayed (just without the module name). Previously the EIP would not be shown, resulting in code running on the heap/stack/somewhere else not being shown as part of the trace.

Modified:
    trunk/reactos/dll/ntdll/rtl/libsupp.c   (contents, props changed)
    trunk/reactos/include/ndk/rtlfuncs.h
    trunk/reactos/lib/rtl/exception.c
    trunk/reactos/ntoskrnl/ke/bug.c
    trunk/reactos/ntoskrnl/rtl/libsupp.c
    trunk/reactos/subsystems/win32/win32k/ntuser/misc.c

Modified: trunk/reactos/dll/ntdll/rtl/libsupp.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/ntdll/rtl/libsupp.c?rev=29332&r1=29331&r2=29332&view=diff
==============================================================================
--- trunk/reactos/dll/ntdll/rtl/libsupp.c (original)
+++ trunk/reactos/dll/ntdll/rtl/libsupp.c Mon Oct  1 21:58:49 2007
@@ -14,6 +14,19 @@
 #include <debug.h>
 
 /* FUNCTIONS ***************************************************************/
+
+/*
+ * @implemented
+ */
+ULONG
+NTAPI
+RtlWalkFrameChain(OUT PVOID *Callers,
+                  IN ULONG Count,
+                  IN ULONG Flags)
+{
+    /* Not implemented for user-mode */
+    return 0;
+}
 
 BOOLEAN
 NTAPI

Propchange: trunk/reactos/dll/ntdll/rtl/libsupp.c
------------------------------------------------------------------------------
--- svn:needs-lock (original)
+++ svn:needs-lock (removed)
@@ -1,1 +1,0 @@
-*

Modified: trunk/reactos/include/ndk/rtlfuncs.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/rtlfuncs.h?rev=29332&r1=29331&r2=29332&view=diff
==============================================================================
--- trunk/reactos/include/ndk/rtlfuncs.h (original)
+++ trunk/reactos/include/ndk/rtlfuncs.h Mon Oct  1 21:58:49 2007
@@ -449,6 +449,15 @@
 // Tracing Functions
 //
 NTSYSAPI
+ULONG
+NTAPI
+RtlWalkFrameChain(
+    OUT PVOID *Callers,
+    IN ULONG Count,
+    IN ULONG Flags
+);
+
+NTSYSAPI
 USHORT
 NTAPI
 RtlLogStackBackTrace(

Modified: trunk/reactos/lib/rtl/exception.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/exception.c?rev=29332&r1=29331&r2=29332&view=diff
==============================================================================
--- trunk/reactos/lib/rtl/exception.c (original)
+++ trunk/reactos/lib/rtl/exception.c Mon Oct  1 21:58:49 2007
@@ -116,110 +116,6 @@
 /*
  * @implemented
  */
-ULONG
-NTAPI
-RtlWalkFrameChain(OUT PVOID *Callers,
-                  IN ULONG Count,
-                  IN ULONG Flags)
-{
-    ULONG_PTR Stack, NewStack, StackBegin, StackEnd;
-    ULONG Eip;
-    BOOLEAN Result, StopSearch = FALSE;
-    ULONG i = 0;
-    
-    /* Get current EBP */
-#if defined(_M_IX86)
-#if defined __GNUC__
-    __asm__("mov %%ebp, %0" : "=r" (Stack) : );
-#elif defined(_MSC_VER)
-    __asm mov Stack, ebp
-#endif
-#elif defined(_M_MIPS)
-        __asm__("move $sp, %0" : "=r" (Stack) : );
-#elif defined(_M_PPC)
-    __asm__("mr %0,1" : "=r" (Stack) : );
-#else
-#error Unknown architecture
-#endif
-    
-    /* Set it as the stack begin limit as well */
-    StackBegin = (ULONG_PTR)Stack;
-    
-    /* Check if we're called for non-logging mode */
-    if (!Flags)
-    {
-        /* Get the actual safe limits */
-        Result = RtlpCaptureStackLimits((ULONG_PTR)Stack,
-                                        &StackBegin,
-                                        &StackEnd);
-        if (!Result) return 0;
-    }
-    
-    /* Use a SEH block for maximum protection */
-    _SEH_TRY
-    {
-        /* Loop the frames */
-        for (i = 0; i < Count; i++)
-        {
-            /*
-             * Leave if we're past the stack,
-             * if we're before the stack,
-             * or if we've reached ourselves.
-             */
-            if ((Stack >= StackEnd) ||
-                (!i ? (Stack < StackBegin) : (Stack <= StackBegin)) ||
-                ((StackEnd - Stack) < (2 * sizeof(ULONG_PTR))))
-            {
-                /* We're done or hit a bad address */
-                break;
-            }
-            
-            /* Get new stack and EIP */
-            NewStack = *(PULONG_PTR)Stack;
-            Eip = *(PULONG_PTR)(Stack + sizeof(ULONG_PTR));
-            
-            /* Check if the new pointer is above the oldone and past the end */
-            if (!((Stack < NewStack) && (NewStack < StackEnd)))
-            {
-                /* Stop searching after this entry */
-                StopSearch = TRUE;
-            }
-            
-            /* Also make sure that the EIP isn't a stack address */
-            if ((StackBegin < Eip) && (Eip < StackEnd)) break;
-            
-            /* Check if we reached a user-mode address */
-            if (!(Flags) && !(Eip & 0x80000000)) break;
-            
-            /* Save this frame */
-            Callers[i] = (PVOID)Eip;
-            
-            /* Check if we should continue */
-            if (StopSearch)
-            {
-                /* Return the next index */
-                i++;
-                break;
-            }
-            
-            /* Move to the next stack */
-            Stack = NewStack;
-        }
-    }
-    _SEH_HANDLE
-    {
-        /* No index */
-        i = 0;
-    }
-    _SEH_END;
-        
-    /* Return frames parsed */
-    return i;
-}
-
-/*
- * @implemented
- */
 USHORT
 NTAPI
 RtlCaptureStackBackTrace(IN ULONG FramesToSkip,

Modified: trunk/reactos/ntoskrnl/ke/bug.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/bug.c?rev=29332&r1=29331&r2=29332&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/bug.c (original)
+++ trunk/reactos/ntoskrnl/ke/bug.c Mon Oct  1 21:58:49 2007
@@ -136,6 +136,97 @@
     return(FALSE);
 }
 
+PVOID
+NTAPI
+KiRosPcToUserFileHeader(IN PVOID Eip,
+                        OUT PLDR_DATA_TABLE_ENTRY *LdrEntry)
+{
+    PVOID ImageBase, EipBase = NULL;
+    PLDR_DATA_TABLE_ENTRY Entry;
+    PLIST_ENTRY ListHead, NextEntry;
+    
+    /*
+     * We know this is valid because we should only be called after a
+     * succesfull address from RtlWalkFrameChain for UserMode, which
+     * validates everything for us.
+     */
+    ListHead = &KeGetCurrentThread()->
+               Teb->ProcessEnvironmentBlock->Ldr->InLoadOrderModuleList;
+    
+    /* Set list pointers and make sure it's valid */
+    NextEntry = ListHead->Flink;
+    if (NextEntry)
+    {
+        /* Start loop */
+        while (NextEntry != ListHead)
+        {
+            /* Get the loader entry */
+            Entry = CONTAINING_RECORD(NextEntry,
+                                      LDR_DATA_TABLE_ENTRY,
+                                      InLoadOrderLinks);
+            
+            /* Move to the next entry */
+            NextEntry = NextEntry->Flink;
+            ImageBase = Entry->DllBase;
+            
+            /* Check if this is the right one */
+            if (((ULONG_PTR)Eip >= (ULONG_PTR)Entry->DllBase) &&
+                ((ULONG_PTR)Eip < ((ULONG_PTR)Entry->DllBase + Entry->SizeOfImage)))
+            {
+                /* Return this entry */
+                *LdrEntry = Entry;
+                EipBase = ImageBase;
+                break;
+            }
+        }
+    }
+    
+    /* Return the base address */
+    return EipBase;
+}
+
+USHORT
+NTAPI
+KeRosCaptureUserStackBackTrace(IN ULONG FramesToSkip,
+                               IN ULONG FramesToCapture,
+                               OUT PVOID *BackTrace,
+                               OUT PULONG BackTraceHash OPTIONAL)
+{
+    PVOID Frames[2 * 64];
+    ULONG FrameCount;
+    ULONG Hash = 0, i;
+    
+    /* Skip a frame for the caller */
+    FramesToSkip++;
+    
+    /* Don't go past the limit */
+    if ((FramesToCapture + FramesToSkip) >= 128) return 0;
+    
+    /* Do the back trace */
+    FrameCount = RtlWalkFrameChain(Frames, FramesToCapture + FramesToSkip, 1);
+    
+    /* Make sure we're not skipping all of them */
+    if (FrameCount <= FramesToSkip) return 0;
+    
+    /* Loop all the frames */
+    for (i = 0; i < FramesToCapture; i++)
+    {
+        /* Don't go past the limit */
+        if ((FramesToSkip + i) >= FrameCount) break;
+        
+        /* Save this entry and hash it */
+        BackTrace[i] = Frames[FramesToSkip + i];
+        Hash += PtrToUlong(BackTrace[i]);
+    }
+    
+    /* Write the hash */
+    if (BackTraceHash) *BackTraceHash = Hash;
+    
+    /* Clear the other entries and return count */
+    RtlFillMemoryUlong(Frames, 128, 0);
+    return (USHORT)i;
+}
+
 VOID
 NTAPI
 KeRosDumpStackFrames(IN PULONG Frame OPTIONAL,
@@ -176,7 +267,38 @@
             Addr -= (ULONG_PTR)LdrEntry->DllBase;
             DbgPrint("<%wZ: %x>", &LdrEntry->FullDllName, Addr);
         }
-
+        else if (Addr)
+        {
+            /* Print only the address */
+            DbgPrint("<%x>", Addr);
+        }
+
+        /* Go to the next frame */
+        DbgPrint("\n");
+    }
+    
+    /* Get the current frames */
+    FrameCount = KeRosCaptureUserStackBackTrace(-1, 32, (PVOID*)Frames, NULL);
+    
+    /* Now loop them */
+    for (i = 0; i < FrameCount; i++)
+    {
+        /* Get the EIP */
+        Addr = Frames[i];
+        
+        /* Get the base for this file */
+        if (KiRosPcToUserFileHeader((PVOID)Addr, &LdrEntry))
+        {
+            /* Print out the module name */
+            Addr -= (ULONG_PTR)LdrEntry->DllBase;
+            DbgPrint("<%wZ: %x>", &LdrEntry->FullDllName, Addr);
+        }
+        else if (Addr)
+        {
+            /* Print only the address */
+            DbgPrint("<%x>", Addr);
+        }
+        
         /* Go to the next frame */
         DbgPrint("\n");
     }

Modified: trunk/reactos/ntoskrnl/rtl/libsupp.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/rtl/libsupp.c?rev=29332&r1=29331&r2=29332&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/rtl/libsupp.c (original)
+++ trunk/reactos/ntoskrnl/rtl/libsupp.c Mon Oct  1 21:58:49 2007
@@ -255,6 +255,144 @@
     return TRUE;
 }
 
+/*
+ * @implemented
+ */
+ULONG
+NTAPI
+RtlWalkFrameChain(OUT PVOID *Callers,
+                  IN ULONG Count,
+                  IN ULONG Flags)
+{
+    ULONG_PTR Stack, NewStack, StackBegin, StackEnd;
+    ULONG Eip;
+    BOOLEAN Result, StopSearch = FALSE;
+    ULONG i = 0;
+    PKTHREAD Thread = KeGetCurrentThread();
+    PTEB Teb;
+    PKTRAP_FRAME TrapFrame;
+    
+    /* Get current EBP */
+#if defined(_M_IX86)
+#if defined __GNUC__
+    __asm__("mov %%ebp, %0" : "=r" (Stack) : );
+#elif defined(_MSC_VER)
+    __asm mov Stack, ebp
+#endif
+#elif defined(_M_MIPS)
+        __asm__("move $sp, %0" : "=r" (Stack) : );
+#elif defined(_M_PPC)
+    __asm__("mr %0,1" : "=r" (Stack) : );
+#else
+#error Unknown architecture
+#endif
+    
+    /* Set it as the stack begin limit as well */
+    StackBegin = (ULONG_PTR)Stack;
+    
+    /* Check if we're called for non-logging mode */
+    if (!Flags)
+    {
+        /* Get the actual safe limits */
+        Result = RtlpCaptureStackLimits((ULONG_PTR)Stack,
+                                        &StackBegin,
+                                        &StackEnd);
+        if (!Result) return 0;
+    }
+    
+    /* Use a SEH block for maximum protection */
+    _SEH_TRY
+    {
+        /* Check if we want the user-mode stack frame */
+        if (Flags == 1)
+        {
+            /* Get the trap frame and TEB */          
+            TrapFrame = Thread->TrapFrame;
+            Teb = Thread->Teb;
+            
+            /* Make sure we can trust the TEB and trap frame */
+            if (!(Teb) || 
+                !((PVOID)((ULONG_PTR)TrapFrame & 0x80000000)) || 
+                ((PVOID)TrapFrame <= (PVOID)Thread->StackLimit) ||
+                ((PVOID)TrapFrame >= (PVOID)Thread->StackBase) ||
+                (KeIsAttachedProcess()) || 
+                (KeGetCurrentIrql() >= DISPATCH_LEVEL))
+            {
+                /* Invalid or unsafe attempt to get the stack */
+                return 0;
+            }
+
+            /* Get the stack limits */
+            StackBegin = (ULONG_PTR)Teb->Tib.StackLimit;
+            StackEnd = (ULONG_PTR)Teb->Tib.StackBase;
+            Stack = TrapFrame->Ebp;
+
+            /* Validate them */
+            if (StackEnd <= StackBegin) return 0;
+            ProbeForRead((PVOID)StackBegin,
+                         StackEnd - StackBegin,
+                         sizeof(CHAR));
+        }
+        
+        /* Loop the frames */
+        for (i = 0; i < Count; i++)
+        {
+            /*
+             * Leave if we're past the stack,
+             * if we're before the stack,
+             * or if we've reached ourselves.
+             */
+            if ((Stack >= StackEnd) ||
+                (!i ? (Stack < StackBegin) : (Stack <= StackBegin)) ||
+                ((StackEnd - Stack) < (2 * sizeof(ULONG_PTR))))
+            {
+                /* We're done or hit a bad address */
+                break;
+            }
+            
+            /* Get new stack and EIP */
+            NewStack = *(PULONG_PTR)Stack;
+            Eip = *(PULONG_PTR)(Stack + sizeof(ULONG_PTR));
+            
+            /* Check if the new pointer is above the oldone and past the end */
+            if (!((Stack < NewStack) && (NewStack < StackEnd)))
+            {
+                /* Stop searching after this entry */
+                StopSearch = TRUE;
+            }
+            
+            /* Also make sure that the EIP isn't a stack address */
+            if ((StackBegin < Eip) && (Eip < StackEnd)) break;
+            
+            /* Check if we reached a user-mode address */
+            if (!(Flags) && !(Eip & 0x80000000)) break;
+            
+            /* Save this frame */
+            Callers[i] = (PVOID)Eip;
+            
+            /* Check if we should continue */
+            if (StopSearch)
+            {
+                /* Return the next index */
+                i++;
+                break;
+            }
+            
+            /* Move to the next stack */
+            Stack = NewStack;
+        }
+    }
+    _SEH_HANDLE
+    {
+        /* No index */
+        i = 0;
+    }
+    _SEH_END;
+    
+    /* Return frames parsed */
+    return i;    
+}
+
 /* RTL Atom Tables ************************************************************/
 
 NTSTATUS

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/misc.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/misc.c?rev=29332&r1=29331&r2=29332&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/misc.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/misc.c Mon Oct  1 21:58:49 2007
@@ -1543,8 +1543,7 @@
 {
     NTSTATUS Status = STATUS_SUCCESS;
 
-    /* remove this when all spi are implement */
-    DPRINT1("UserSystemParametersInfo_StructGet SPI Action 0x%x (uiParam: 0x%x, fWinIni: 0x%x)\n",uiAction,  uiParam, fWinIni);
+    DPRINT("UserSystemParametersInfo_StructGet SPI Action 0x%x (uiParam: 0x%x, fWinIni: 0x%x)\n",uiAction,  uiParam, fWinIni);
 
     _SEH_TRY
     {




More information about the Ros-diffs mailing list