1 /* 2 * PROJECT: ReactOS kernel-mode tests 3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory 4 * PURPOSE: Kernel-Mode Test Suite Runtime library stack trace test 5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org> 6 */ 7 8 #define KMT_EMULATE_KERNEL 9 #include <kmt_test.h> 10 11 static PVOID ReturnAddresses[4]; 12 13 static 14 VOID 15 TestStackWalk3(VOID); 16 17 DECLSPEC_NOINLINE 18 static 19 VOID 20 TestStackWalk4(VOID) 21 { 22 PVOID Frames[5]; 23 ULONG Ret; 24 ULONG Hash; 25 ULONG ExpectedHash; 26 ULONG i; 27 const ULONG FunctionSizeGuess = 0x1000; 28 29 ReturnAddresses[3] = _ReturnAddress(); 30 31 Ret = RtlWalkFrameChain(NULL, 5, 0); 32 ok_eq_ulong(Ret, 0); 33 34 RtlFillMemory(Frames, sizeof(Frames), 0x55); 35 Ret = RtlWalkFrameChain(Frames, 0, 0); 36 ok_eq_ulong(Ret, 0); 37 ok_eq_pointer(Frames[0], (PVOID)(ULONG_PTR)0x5555555555555555); 38 39 RtlFillMemory(Frames, sizeof(Frames), 0x55); 40 Ret = RtlWalkFrameChain(Frames, 5, 0); 41 ok_eq_ulong(Ret, 5); 42 ok((ULONG_PTR)Frames[0] > (ULONG_PTR)TestStackWalk4, "Frame is %p, function is %p\n", Frames[0], TestStackWalk4); 43 ok((ULONG_PTR)Frames[0] < (ULONG_PTR)TestStackWalk4 + FunctionSizeGuess, "Frame is %p, function is %p\n", Frames[0], TestStackWalk4); 44 ok_eq_pointer(Frames[1], ReturnAddresses[3]); 45 ok_eq_pointer(Frames[2], ReturnAddresses[2]); 46 ok_eq_pointer(Frames[3], ReturnAddresses[1]); 47 ok_eq_pointer(Frames[4], ReturnAddresses[0]); 48 49 RtlFillMemory(Frames, sizeof(Frames), 0x55); 50 Ret = RtlWalkFrameChain(Frames, 4, 0); 51 ok_eq_ulong(Ret, 4); 52 ok((ULONG_PTR)Frames[0] > (ULONG_PTR)TestStackWalk4, "Frame is %p, function is %p\n", Frames[0], TestStackWalk4); 53 ok((ULONG_PTR)Frames[0] < (ULONG_PTR)TestStackWalk4 + FunctionSizeGuess, "Frame is %p, function is %p\n", Frames[0], TestStackWalk4); 54 ok_eq_pointer(Frames[1], ReturnAddresses[3]); 55 ok_eq_pointer(Frames[2], ReturnAddresses[2]); 56 ok_eq_pointer(Frames[3], ReturnAddresses[1]); 57 ok_eq_pointer(Frames[4], (PVOID)(ULONG_PTR)0x5555555555555555); 58 59 KmtStartSeh() 60 RtlCaptureStackBackTrace(0, 5, NULL, NULL); 61 KmtEndSeh(STATUS_ACCESS_VIOLATION); 62 63 RtlFillMemory(Frames, sizeof(Frames), 0x55); 64 Hash = 0x55555555; 65 Ret = RtlCaptureStackBackTrace(0, 0, Frames, &Hash); 66 ok_eq_ulong(Ret, 0); 67 ok_eq_hex(Hash, 0x55555555); 68 ok_eq_pointer(Frames[0], (PVOID)(ULONG_PTR)0x5555555555555555); 69 70 RtlFillMemory(Frames, sizeof(Frames), 0x55); 71 Hash = 0x55555555; 72 Ret = RtlCaptureStackBackTrace(0, 1, Frames, NULL); 73 ok_eq_ulong(Ret, 1); 74 ok((ULONG_PTR)Frames[0] > (ULONG_PTR)TestStackWalk4, "Frame is %p, function is %p\n", Frames[0], TestStackWalk4); 75 ok((ULONG_PTR)Frames[0] < (ULONG_PTR)TestStackWalk4 + FunctionSizeGuess, "Frame is %p, function is %p\n", Frames[0], TestStackWalk4); 76 ok_eq_pointer(Frames[1], (PVOID)(ULONG_PTR)0x5555555555555555); 77 78 RtlFillMemory(Frames, sizeof(Frames), 0x55); 79 Ret = RtlCaptureStackBackTrace(0, 5, Frames, &Hash); 80 ok_eq_ulong(Ret, 5); 81 ExpectedHash = 0; 82 for (i = 0; i < 5; i++) 83 ExpectedHash += (ULONG)(ULONG_PTR)Frames[i]; 84 ok_eq_hex(Hash, ExpectedHash); 85 ok((ULONG_PTR)Frames[0] > (ULONG_PTR)TestStackWalk4, "Frame is %p, function is %p\n", Frames[0], TestStackWalk4); 86 ok((ULONG_PTR)Frames[0] < (ULONG_PTR)TestStackWalk4 + FunctionSizeGuess, "Frame is %p, function is %p\n", Frames[0], TestStackWalk4); 87 ok_eq_pointer(Frames[1], ReturnAddresses[3]); 88 ok_eq_pointer(Frames[2], ReturnAddresses[2]); 89 ok_eq_pointer(Frames[3], ReturnAddresses[1]); 90 ok_eq_pointer(Frames[4], ReturnAddresses[0]); 91 92 RtlFillMemory(Frames, sizeof(Frames), 0x55); 93 Ret = RtlCaptureStackBackTrace(1, 4, Frames, &Hash); 94 ok_eq_ulong(Ret, 4); 95 ExpectedHash = 0; 96 for (i = 0; i < 4; i++) 97 ExpectedHash += (ULONG)(ULONG_PTR)Frames[i]; 98 ok_eq_hex(Hash, ExpectedHash); 99 ok_eq_pointer(Frames[0], ReturnAddresses[3]); 100 ok_eq_pointer(Frames[1], ReturnAddresses[2]); 101 ok_eq_pointer(Frames[2], ReturnAddresses[1]); 102 ok_eq_pointer(Frames[3], ReturnAddresses[0]); 103 ok_eq_pointer(Frames[4], (PVOID)(ULONG_PTR)0x5555555555555555); 104 } 105 106 DECLSPEC_NOINLINE 107 static 108 VOID 109 TestStackWalk3(VOID) 110 { 111 ReturnAddresses[2] = _ReturnAddress(); 112 TestStackWalk4(); 113 } 114 115 DECLSPEC_NOINLINE 116 static 117 VOID 118 TestStackWalk2(VOID) 119 { 120 ReturnAddresses[1] = _ReturnAddress(); 121 TestStackWalk3(); 122 } 123 124 DECLSPEC_NOINLINE 125 static 126 VOID 127 TestStackWalk1(VOID) 128 { 129 ReturnAddresses[0] = _ReturnAddress(); 130 TestStackWalk2(); 131 } 132 133 START_TEST(RtlStack) 134 { 135 TestStackWalk1(); 136 } 137