Author: ion
Date: Wed Aug 30 10:52:10 2006
New Revision: 23795
URL:
http://svn.reactos.org/svn/reactos?rev=23795&view=rev
Log:
- Implement RtlCaptureStackBackTrace and RtlWalkFrameChain and add definitions to ntifs.h
- Get rid of KeRosGetStackFrames and replace usage by RtlWalkFrameChain or
RtlCaptureStackBackTrace, depending.
- Remove this entry from Kernel Fun.
Modified:
trunk/reactos/dll/ntdll/rtl/libsupp.c
trunk/reactos/include/ddk/ntifs.h
trunk/reactos/lib/rtl/exception.c
trunk/reactos/lib/rtl/rtlp.h
trunk/reactos/ntoskrnl/KrnlFun.c
trunk/reactos/ntoskrnl/ke/bug.c
trunk/reactos/ntoskrnl/mm/ppool.c
trunk/reactos/ntoskrnl/ntoskrnl.def
trunk/reactos/ntoskrnl/rtl/libsupp.c
Modified: trunk/reactos/dll/ntdll/rtl/libsupp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/ntdll/rtl/libsupp.c?re…
==============================================================================
--- trunk/reactos/dll/ntdll/rtl/libsupp.c (original)
+++ trunk/reactos/dll/ntdll/rtl/libsupp.c Wed Aug 30 10:52:10 2006
@@ -171,6 +171,18 @@
IN ULONG Size)
{
/* Exception logging is not done in user-mode */
+}
+
+BOOLEAN
+NTAPI
+RtlpCaptureStackLimits(IN ULONG_PTR Ebp,
+ IN ULONG_PTR *StackBegin,
+ IN ULONG_PTR *StackEnd)
+{
+ /* FIXME: Verify */
+ *StackBegin = (ULONG_PTR)NtCurrentTeb()->Tib.StackLimit;
+ *StackEnd = (ULONG_PTR)NtCurrentTeb()->Tib.StackBase;
+ return TRUE;
}
/* RTL Atom Tables ************************************************************/
Modified: trunk/reactos/include/ddk/ntifs.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ddk/ntifs.h?rev=23…
==============================================================================
--- trunk/reactos/include/ddk/ntifs.h (original)
+++ trunk/reactos/include/ddk/ntifs.h Wed Aug 30 10:52:10 2006
@@ -3676,6 +3676,16 @@
);
NTSYSAPI
+USHORT
+NTAPI
+RtlCaptureStackBackTrace (
+ IN ULONG FramesToSkip,
+ IN ULONG FramesToCapture,
+ OUT PVOID *BackTrace,
+ OUT PULONG BackTraceHash OPTIONAL
+);
+
+NTSYSAPI
NTSTATUS
NTAPI
RtlCompressBuffer (
Modified: trunk/reactos/lib/rtl/exception.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/exception.c?rev=23…
==============================================================================
--- trunk/reactos/lib/rtl/exception.c (original)
+++ trunk/reactos/lib/rtl/exception.c Wed Aug 30 10:52:10 2006
@@ -110,8 +110,92 @@
}
/*
-* @unimplemented
-*/
+ * @implemented
+ */
+ULONG
+NTAPI
+RtlWalkFrameChain(OUT PVOID *Callers,
+ IN ULONG Count,
+ IN ULONG Flags)
+{
+ PULONG Stack, NewStack;
+ ULONG Eip;
+ ULONG_PTR StackBegin, StackEnd;
+ BOOLEAN Result, StopSearch = FALSE;
+ ULONG i = 0;
+
+ /* Get current EBP */
+#if defined __GNUC__
+ __asm__("mov %%ebp, %0" : "=r" (Stack) : );
+#elif defined(_MSC_VER)
+ __asm mov Stack, ebp
+#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;
+ }
+
+ /* Loop the frames */
+ for (i = 0; i < Count; i++)
+ {
+ /* Check if we're past the stack */
+ if ((ULONG_PTR)Stack >= StackEnd) break;
+
+ /* Check if this is the first entry */
+#if 0
+ if (!i)
+ {
+ if ((ULONG_PTR)Stack != StackBegin) break;
+ }
+ else
+ {
+ if ((ULONG_PTR)Stack == StackBegin) break;
+ }
+#endif
+
+ /* Make sure there's enough frames */
+ if ((StackEnd - (ULONG_PTR)Stack) < (2 * sizeof(ULONG_PTR))) break;
+
+ /* Get new stack and EIP */
+ NewStack = (PULONG)Stack[0];
+ Eip = Stack[1];
+
+ /* Check if the new pointer is above the oldone and past the end */
+ if (!((Stack < NewStack) && ((ULONG_PTR)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;
+
+ /* Save this frame */
+ Callers[i] = (PVOID)Eip;
+
+ /* Check if we should continue */
+ if (StopSearch) break;
+
+ /* Move to the next stack */
+ Stack = NewStack;
+ }
+
+ /* Return frames parsed */
+ return i;
+}
+
+/*
+ * @implemented
+ */
USHORT
NTAPI
RtlCaptureStackBackTrace(IN ULONG FramesToSkip,
@@ -119,21 +203,39 @@
OUT PVOID *BackTrace,
OUT PULONG BackTraceHash OPTIONAL)
{
- UNIMPLEMENTED;
- return 0;
-}
-
-/*
-* @unimplemented
-*/
-ULONG
-NTAPI
-RtlWalkFrameChain(OUT PVOID *Callers,
- IN ULONG Count,
- IN ULONG Flags)
-{
- UNIMPLEMENTED;
- return 0;
+ 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, 0);
+
+ /* 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;
}
/*
Modified: trunk/reactos/lib/rtl/rtlp.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/rtlp.h?rev=23795&a…
==============================================================================
--- trunk/reactos/lib/rtl/rtlp.h (original)
+++ trunk/reactos/lib/rtl/rtlp.h Wed Aug 30 10:52:10 2006
@@ -32,6 +32,14 @@
KPROCESSOR_MODE
NTAPI
RtlpGetMode(VOID);
+
+BOOLEAN
+NTAPI
+RtlpCaptureStackLimits(
+ IN ULONG_PTR Ebp,
+ IN ULONG_PTR *StackBegin,
+ IN ULONG_PTR *StackEnd
+);
NTSTATUS
NTAPI
Modified: trunk/reactos/ntoskrnl/KrnlFun.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/KrnlFun.c?rev=237…
==============================================================================
--- trunk/reactos/ntoskrnl/KrnlFun.c (original)
+++ trunk/reactos/ntoskrnl/KrnlFun.c Wed Aug 30 10:52:10 2006
@@ -25,7 +25,6 @@
// - Use Object Type Mutex/Lock.
//
// Ke:
-// - Clean up exp.c (remove all stack functions and use
RtlWalkFrameChain/RtlCaptureStackBacktrace)
// - Sanitize some context fields during conversions
// - Add PSEH handler when an exception occurs in an exception (KiCopyExceptionRecord).
// - Forward exceptions to user-mode debugger.
Modified: trunk/reactos/ntoskrnl/ke/bug.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/bug.c?rev=2379…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/bug.c (original)
+++ trunk/reactos/ntoskrnl/ke/bug.c Wed Aug 30 10:52:10 2006
@@ -83,83 +83,22 @@
return(FALSE);
}
-ULONG
-NTAPI
-KeRosGetStackFrames(PULONG Frames,
- ULONG FrameCount)
-{
- ULONG Count = 0;
- PULONG StackBase, StackEnd, Frame;
- MEMORY_BASIC_INFORMATION mbi;
- ULONG ResultLength = sizeof(mbi);
- NTSTATUS Status;
-
- _SEH_TRY
- {
-#if defined __GNUC__
- __asm__("mov %%ebp, %0" : "=r" (Frame) : );
-#elif defined(_MSC_VER)
- __asm mov [Frame], ebp
-#endif
-
- Status = MiQueryVirtualMemory (
- (HANDLE)-1,
- Frame,
- MemoryBasicInformation,
- &mbi,
- sizeof(mbi),
- &ResultLength );
- if ( !NT_SUCCESS(Status) )
- {
- DPRINT1("Can't get stack frames: MiQueryVirtualMemory() failed:
%x\n", Status );
- return 0;
- }
-
- StackBase = Frame;
- StackEnd = (PULONG)((ULONG_PTR)mbi.BaseAddress + mbi.RegionSize);
-
- while ( Count < FrameCount && Frame >= StackBase && Frame
< StackEnd )
- {
- Frames[Count++] = Frame[1];
- StackBase = Frame;
- Frame = (PULONG)Frame[0];
- }
- }
- _SEH_HANDLE
- {
- }
- _SEH_END;
- return Count;
-}
-
-VOID
-NTAPI
-KeDumpStackFrames(PULONG Frame)
-{
- /* Just call the extended version */
- KeRosDumpStackFrames(Frame, 0);
-}
-
VOID
NTAPI
KeRosDumpStackFrames(IN PULONG Frame OPTIONAL,
IN ULONG FrameCount OPTIONAL)
{
ULONG Frames[32];
- ULONG Count, i, Addr;
-
- /* Don't let anyone ask more then 32 frames */
- if (FrameCount > 32) return;
+ ULONG i, Addr;
/* If the caller didn't ask, assume 32 frames */
if (!FrameCount) FrameCount = 32;
- /* Get the current frames, and make sure caller didn't ask too many */
- Count = KeRosGetStackFrames(Frames, FrameCount); // <= should be replaced with
Rtl
- if (FrameCount > Count) FrameCount = Count;
+ /* Get the current frames */
+ FrameCount = RtlCaptureStackBackTrace(2, FrameCount, (PVOID*)Frames, NULL);
/* Now loop them (skip the two. One for the dumper, one for the caller) */
- for (i = 2; i < FrameCount; i++)
+ for (i = 0; i < FrameCount; i++)
{
/* Get the EIP */
Addr = Frames[i];
@@ -177,9 +116,6 @@
/* Print it out */
if (!KeRosPrintAddress((PVOID)Addr)) DbgPrint("<%X>", Addr);
-
- /* Break out of invalid addresses */
- if (Addr == 0 || Addr == 0xDEADBEEF) break;
/* Go to the next frame */
DbgPrint("\n");
Modified: trunk/reactos/ntoskrnl/mm/ppool.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ppool.c?rev=23…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ppool.c (original)
+++ trunk/reactos/ntoskrnl/mm/ppool.c Wed Aug 30 10:52:10 2006
@@ -34,7 +34,7 @@
#define R_PRINT_ADDRESS(addr) KeRosPrintAddress(addr)
#define R_PANIC() KeBugCheck(0)
#define R_DEBUG DbgPrint
-#define R_GET_STACK_FRAMES(ptr,cnt) KeRosGetStackFrames(ptr,cnt)
+#define R_GET_STACK_FRAMES(ptr,cnt) RtlWalkFrameChain((PVOID*)ptr,cnt, 0)
#include "rpoolmgr.h"
Modified: trunk/reactos/ntoskrnl/ntoskrnl.def
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ntoskrnl.def?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/ntoskrnl.def (original)
+++ trunk/reactos/ntoskrnl/ntoskrnl.def Wed Aug 30 10:52:10 2006
@@ -977,7 +977,6 @@
READ_REGISTER_BUFFER_USHORT@12
KiRosPrintAddress@4
KeRosDumpStackFrames@8
-KeRosGetStackFrames@8
RtlAbsoluteToSelfRelativeSD@12
RtlAddAccessAllowedAce@16
RtlAddAce@20
Modified: trunk/reactos/ntoskrnl/rtl/libsupp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/rtl/libsupp.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/rtl/libsupp.c (original)
+++ trunk/reactos/ntoskrnl/rtl/libsupp.c Wed Aug 30 10:52:10 2006
@@ -186,6 +186,34 @@
/* Not in DPC stack */
return FALSE;
+}
+
+BOOLEAN
+NTAPI
+RtlpCaptureStackLimits(IN ULONG_PTR Ebp,
+ IN ULONG_PTR *StackBegin,
+ IN ULONG_PTR *StackEnd)
+{
+ PKTHREAD Thread = KeGetCurrentThread();
+
+ /* FIXME: Super native implementation */
+
+ /* FIXME: ROS HACK */
+ if (!Thread) return FALSE;
+
+ /* Start with defaults */
+ *StackBegin = Thread->StackLimit;
+ *StackEnd = (ULONG_PTR)Thread->StackBase;
+
+ /* Check if we seem to be on the DPC stack */
+ if ((*StackBegin > Ebp) || (Ebp > *StackEnd))
+ {
+ /* FIXME: TODO */
+ ASSERT(FALSE);
+ }
+
+ /* Return success */
+ return TRUE;
}
/* RTL Atom Tables ************************************************************/