[KMTESTS:RTL]
authorThomas Faber <thomas.faber@reactos.org>
Sat, 6 May 2017 15:29:56 +0000 (15:29 +0000)
committerThomas Faber <thomas.faber@reactos.org>
Sat, 6 May 2017 15:29:56 +0000 (15:29 +0000)
- Add a test for RtlWalkFrameChain and RtlCaptureStackBackTrace

svn path=/trunk/; revision=74489

rostests/kmtests/CMakeLists.txt
rostests/kmtests/kmtest/testlist.c
rostests/kmtests/kmtest_drv/testlist.c
rostests/kmtests/rtl/RtlStack.c [new file with mode: 0644]

index 8fe2101..6291fcd 100644 (file)
@@ -20,6 +20,7 @@ list(APPEND COMMON_SOURCE
     rtl/RtlMemory.c
     rtl/RtlRegistry.c
     rtl/RtlSplayTree.c
+    rtl/RtlStack.c
     rtl/RtlUnicodeString.c)
 
 #
index 3778a09..74e525c 100644 (file)
@@ -21,6 +21,7 @@ KMT_TESTFUNC Test_RtlIntSafe;
 KMT_TESTFUNC Test_RtlMemory;
 KMT_TESTFUNC Test_RtlRegistry;
 KMT_TESTFUNC Test_RtlSplayTree;
+KMT_TESTFUNC Test_RtlStack;
 KMT_TESTFUNC Test_RtlUnicodeString;
 KMT_TESTFUNC Test_TcpIpIoctl;
 KMT_TESTFUNC Test_TcpIpTdi;
@@ -43,6 +44,7 @@ const KMT_TEST TestList[] =
     { "RtlMemory",          Test_RtlMemory },
     { "RtlRegistry",        Test_RtlRegistry },
     { "RtlSplayTree",       Test_RtlSplayTree },
+    { "RtlStack",           Test_RtlStack },
     { "RtlUnicodeString",   Test_RtlUnicodeString },
     { "TcpIpTdi",           Test_TcpIpTdi },
     { "TcpIpConnect",       Test_TcpIpConnect },
index 74cb68f..5f2417f 100644 (file)
@@ -70,6 +70,7 @@ KMT_TESTFUNC Test_RtlIsValidOemCharacter;
 KMT_TESTFUNC Test_RtlMemory;
 KMT_TESTFUNC Test_RtlRegistry;
 KMT_TESTFUNC Test_RtlSplayTree;
+KMT_TESTFUNC Test_RtlStack;
 KMT_TESTFUNC Test_RtlUnicodeString;
 KMT_TESTFUNC Test_ZwAllocateVirtualMemory;
 KMT_TESTFUNC Test_ZwCreateSection;
@@ -139,6 +140,7 @@ const KMT_TEST TestList[] =
     { "RtlMemoryKM",                        Test_RtlMemory },
     { "RtlRegistryKM",                      Test_RtlRegistry },
     { "RtlSplayTreeKM",                     Test_RtlSplayTree },
+    { "RtlStackKM",                         Test_RtlStack },
     { "RtlUnicodeStringKM",                 Test_RtlUnicodeString },
     { "SeInheritance",                      Test_SeInheritance },
     { "SeQueryInfoToken",                   Test_SeQueryInfoToken },
diff --git a/rostests/kmtests/rtl/RtlStack.c b/rostests/kmtests/rtl/RtlStack.c
new file mode 100644 (file)
index 0000000..45db416
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * PROJECT:         ReactOS kernel-mode tests
+ * LICENSE:         LGPLv2.1+ - See COPYING.LIB in the top level directory
+ * PURPOSE:         Kernel-Mode Test Suite Runtime library stack trace test
+ * PROGRAMMER:      Thomas Faber <thomas.faber@reactos.org>
+ */
+
+#define KMT_EMULATE_KERNEL
+#include <kmt_test.h>
+
+static PVOID ReturnAddresses[4];
+
+static
+VOID
+TestStackWalk3(VOID);
+
+DECLSPEC_NOINLINE
+static
+VOID
+TestStackWalk4(VOID)
+{
+    PVOID Frames[5];
+    ULONG Ret;
+    ULONG Hash;
+    ULONG ExpectedHash;
+    ULONG i;
+    const ULONG FunctionSizeGuess = 0x1000;
+
+    ReturnAddresses[3] = _ReturnAddress();
+
+    Ret = RtlWalkFrameChain(NULL, 5, 0);
+    ok_eq_ulong(Ret, 0);
+
+    RtlFillMemory(Frames, sizeof(Frames), 0x55);
+    Ret = RtlWalkFrameChain(Frames, 0, 0);
+    ok_eq_ulong(Ret, 0);
+    ok_eq_pointer(Frames[0], (PVOID)(ULONG_PTR)0x5555555555555555);
+
+    RtlFillMemory(Frames, sizeof(Frames), 0x55);
+    Ret = RtlWalkFrameChain(Frames, 5, 0);
+    ok_eq_ulong(Ret, 5);
+    ok((ULONG_PTR)Frames[0] > (ULONG_PTR)TestStackWalk4, "Frame is %p, function is %p\n", Frames[0], TestStackWalk4);
+    ok((ULONG_PTR)Frames[0] < (ULONG_PTR)TestStackWalk4 + FunctionSizeGuess, "Frame is %p, function is %p\n", Frames[0], TestStackWalk4);
+    ok_eq_pointer(Frames[1], ReturnAddresses[3]);
+    ok_eq_pointer(Frames[2], ReturnAddresses[2]);
+    ok_eq_pointer(Frames[3], ReturnAddresses[1]);
+    ok_eq_pointer(Frames[4], ReturnAddresses[0]);
+
+    RtlFillMemory(Frames, sizeof(Frames), 0x55);
+    Ret = RtlWalkFrameChain(Frames, 4, 0);
+    ok_eq_ulong(Ret, 4);
+    ok((ULONG_PTR)Frames[0] > (ULONG_PTR)TestStackWalk4, "Frame is %p, function is %p\n", Frames[0], TestStackWalk4);
+    ok((ULONG_PTR)Frames[0] < (ULONG_PTR)TestStackWalk4 + FunctionSizeGuess, "Frame is %p, function is %p\n", Frames[0], TestStackWalk4);
+    ok_eq_pointer(Frames[1], ReturnAddresses[3]);
+    ok_eq_pointer(Frames[2], ReturnAddresses[2]);
+    ok_eq_pointer(Frames[3], ReturnAddresses[1]);
+    ok_eq_pointer(Frames[4], (PVOID)(ULONG_PTR)0x5555555555555555);
+
+    KmtStartSeh()
+        RtlCaptureStackBackTrace(0, 5, NULL, NULL);
+    KmtEndSeh(STATUS_ACCESS_VIOLATION);
+
+    RtlFillMemory(Frames, sizeof(Frames), 0x55);
+    Hash = 0x55555555;
+    Ret = RtlCaptureStackBackTrace(0, 0, Frames, &Hash);
+    ok_eq_ulong(Ret, 0);
+    ok_eq_hex(Hash, 0x55555555);
+    ok_eq_pointer(Frames[0], (PVOID)(ULONG_PTR)0x5555555555555555);
+
+    RtlFillMemory(Frames, sizeof(Frames), 0x55);
+    Hash = 0x55555555;
+    Ret = RtlCaptureStackBackTrace(0, 1, Frames, NULL);
+    ok_eq_ulong(Ret, 1);
+    ok((ULONG_PTR)Frames[0] > (ULONG_PTR)TestStackWalk4, "Frame is %p, function is %p\n", Frames[0], TestStackWalk4);
+    ok((ULONG_PTR)Frames[0] < (ULONG_PTR)TestStackWalk4 + FunctionSizeGuess, "Frame is %p, function is %p\n", Frames[0], TestStackWalk4);
+    ok_eq_pointer(Frames[1], (PVOID)(ULONG_PTR)0x5555555555555555);
+
+    RtlFillMemory(Frames, sizeof(Frames), 0x55);
+    Ret = RtlCaptureStackBackTrace(0, 5, Frames, &Hash);
+    ok_eq_ulong(Ret, 5);
+    ExpectedHash = 0;
+    for (i = 0; i < 5; i++)
+        ExpectedHash += (ULONG)(ULONG_PTR)Frames[i];
+    ok_eq_hex(Hash, ExpectedHash);
+    ok((ULONG_PTR)Frames[0] > (ULONG_PTR)TestStackWalk4, "Frame is %p, function is %p\n", Frames[0], TestStackWalk4);
+    ok((ULONG_PTR)Frames[0] < (ULONG_PTR)TestStackWalk4 + FunctionSizeGuess, "Frame is %p, function is %p\n", Frames[0], TestStackWalk4);
+    ok_eq_pointer(Frames[1], ReturnAddresses[3]);
+    ok_eq_pointer(Frames[2], ReturnAddresses[2]);
+    ok_eq_pointer(Frames[3], ReturnAddresses[1]);
+    ok_eq_pointer(Frames[4], ReturnAddresses[0]);
+
+    RtlFillMemory(Frames, sizeof(Frames), 0x55);
+    Ret = RtlCaptureStackBackTrace(1, 4, Frames, &Hash);
+    ok_eq_ulong(Ret, 4);
+    ExpectedHash = 0;
+    for (i = 0; i < 4; i++)
+        ExpectedHash += (ULONG)(ULONG_PTR)Frames[i];
+    ok_eq_hex(Hash, ExpectedHash);
+    ok_eq_pointer(Frames[0], ReturnAddresses[3]);
+    ok_eq_pointer(Frames[1], ReturnAddresses[2]);
+    ok_eq_pointer(Frames[2], ReturnAddresses[1]);
+    ok_eq_pointer(Frames[3], ReturnAddresses[0]);
+    ok_eq_pointer(Frames[4], (PVOID)(ULONG_PTR)0x5555555555555555);
+}
+
+DECLSPEC_NOINLINE
+static
+VOID
+TestStackWalk3(VOID)
+{
+    ReturnAddresses[2] = _ReturnAddress();
+    TestStackWalk4();
+}
+
+DECLSPEC_NOINLINE
+static
+VOID
+TestStackWalk2(VOID)
+{
+    ReturnAddresses[1] = _ReturnAddress();
+    TestStackWalk3();
+}
+
+DECLSPEC_NOINLINE
+static
+VOID
+TestStackWalk1(VOID)
+{
+    ReturnAddresses[0] = _ReturnAddress();
+    TestStackWalk2();
+}
+
+START_TEST(RtlStack)
+{
+    TestStackWalk1();
+}