Reactos
at listview 211 lines 6.2 kB view raw
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 11static PVOID ReturnAddresses[4]; 12 13static 14VOID 15TestStackWalk3(VOID); 16 17DECLSPEC_NOINLINE 18static 19VOID 20TestStackWalk4(VOID) 21{ 22 PVOID Frames[5]; 23 ULONG Ret; 24 ULONG Hash; 25 ULONG ExpectedHash; 26 ULONG i; 27 const ULONG FunctionSizeGuess = 0x1000; 28 NTSTATUS ExceptionStatus = STATUS_SUCCESS; 29 30 ReturnAddresses[3] = _ReturnAddress(); 31 32 Ret = RtlWalkFrameChain(NULL, 5, 0); 33 ok_eq_ulong(Ret, 0); 34 35 RtlFillMemory(Frames, sizeof(Frames), 0x55); 36 Ret = RtlWalkFrameChain(Frames, 0, 0); 37 ok_eq_ulong(Ret, 0); 38 ok_eq_pointer(Frames[0], (PVOID)(ULONG_PTR)0x5555555555555555); 39 40 RtlFillMemory(Frames, sizeof(Frames), 0x55); 41 Ret = RtlWalkFrameChain(Frames, 5, 0); 42 ok_eq_ulong(Ret, 5); 43 ok((ULONG_PTR)Frames[0] > (ULONG_PTR)TestStackWalk4, "Frame is %p, function is %p\n", Frames[0], TestStackWalk4); 44 ok((ULONG_PTR)Frames[0] < (ULONG_PTR)TestStackWalk4 + FunctionSizeGuess, "Frame is %p, function is %p\n", Frames[0], TestStackWalk4); 45 ok_eq_pointer(Frames[1], ReturnAddresses[3]); 46 ok_eq_pointer(Frames[2], ReturnAddresses[2]); 47 ok_eq_pointer(Frames[3], ReturnAddresses[1]); 48 ok_eq_pointer(Frames[4], ReturnAddresses[0]); 49 50 RtlFillMemory(Frames, sizeof(Frames), 0x55); 51 Ret = RtlWalkFrameChain(Frames, 4, 0); 52 ok_eq_ulong(Ret, 4); 53 ok((ULONG_PTR)Frames[0] > (ULONG_PTR)TestStackWalk4, "Frame is %p, function is %p\n", Frames[0], TestStackWalk4); 54 ok((ULONG_PTR)Frames[0] < (ULONG_PTR)TestStackWalk4 + FunctionSizeGuess, "Frame is %p, function is %p\n", Frames[0], TestStackWalk4); 55 ok_eq_pointer(Frames[1], ReturnAddresses[3]); 56 ok_eq_pointer(Frames[2], ReturnAddresses[2]); 57 ok_eq_pointer(Frames[3], ReturnAddresses[1]); 58 ok_eq_pointer(Frames[4], (PVOID)(ULONG_PTR)0x5555555555555555); 59 60 _SEH2_TRY 61 { 62 RtlCaptureStackBackTrace(0, 5, NULL, NULL); 63 } 64 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 65 { 66 ExceptionStatus = _SEH2_GetExceptionCode(); 67 } 68 _SEH2_END; 69 if (GetNTVersion() == _WIN32_WINNT_WS03) 70 ok_eq_hex(ExceptionStatus, STATUS_ACCESS_VIOLATION); 71 else 72 ok_eq_hex(ExceptionStatus, STATUS_SUCCESS); 73 74 RtlFillMemory(Frames, sizeof(Frames), 0x55); 75 Hash = 0x55555555; 76 Ret = RtlCaptureStackBackTrace(0, 0, Frames, &Hash); 77 ok_eq_ulong(Ret, 0); 78 ok_eq_hex(Hash, 0x55555555); 79 ok_eq_pointer(Frames[0], (PVOID)(ULONG_PTR)0x5555555555555555); 80 81 RtlFillMemory(Frames, sizeof(Frames), 0x55); 82 Hash = 0x55555555; 83 Ret = RtlCaptureStackBackTrace(0, 1, Frames, NULL); 84 ok_eq_ulong(Ret, 1); 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], (PVOID)(ULONG_PTR)0x5555555555555555); 88 89 RtlFillMemory(Frames, sizeof(Frames), 0x55); 90 Ret = RtlCaptureStackBackTrace(0, 5, Frames, &Hash); 91 ok_eq_ulong(Ret, 5); 92 ExpectedHash = 0; 93 for (i = 0; i < 5; i++) 94 ExpectedHash += (ULONG)(ULONG_PTR)Frames[i]; 95 ok_eq_hex(Hash, ExpectedHash); 96 ok((ULONG_PTR)Frames[0] > (ULONG_PTR)TestStackWalk4, "Frame is %p, function is %p\n", Frames[0], TestStackWalk4); 97 ok((ULONG_PTR)Frames[0] < (ULONG_PTR)TestStackWalk4 + FunctionSizeGuess, "Frame is %p, function is %p\n", Frames[0], TestStackWalk4); 98 ok_eq_pointer(Frames[1], ReturnAddresses[3]); 99 ok_eq_pointer(Frames[2], ReturnAddresses[2]); 100 ok_eq_pointer(Frames[3], ReturnAddresses[1]); 101 ok_eq_pointer(Frames[4], ReturnAddresses[0]); 102 103 RtlFillMemory(Frames, sizeof(Frames), 0x55); 104 Ret = RtlCaptureStackBackTrace(1, 4, Frames, &Hash); 105 ok_eq_ulong(Ret, 4); 106 ExpectedHash = 0; 107 for (i = 0; i < 4; i++) 108 ExpectedHash += (ULONG)(ULONG_PTR)Frames[i]; 109 ok_eq_hex(Hash, ExpectedHash); 110 ok_eq_pointer(Frames[0], ReturnAddresses[3]); 111 ok_eq_pointer(Frames[1], ReturnAddresses[2]); 112 ok_eq_pointer(Frames[2], ReturnAddresses[1]); 113 ok_eq_pointer(Frames[3], ReturnAddresses[0]); 114 ok_eq_pointer(Frames[4], (PVOID)(ULONG_PTR)0x5555555555555555); 115} 116 117DECLSPEC_NOINLINE 118static 119VOID 120TestStackWalk3(VOID) 121{ 122 ReturnAddresses[2] = _ReturnAddress(); 123 TestStackWalk4(); 124} 125 126DECLSPEC_NOINLINE 127static 128VOID 129TestStackWalk2(VOID) 130{ 131 ReturnAddresses[1] = _ReturnAddress(); 132 TestStackWalk3(); 133} 134 135DECLSPEC_NOINLINE 136static 137VOID 138TestStackWalk1(VOID) 139{ 140 ReturnAddresses[0] = _ReturnAddress(); 141 TestStackWalk2(); 142} 143 144#ifdef _M_AMD64 145NTSYSAPI 146PVOID 147NTAPI 148RtlPcToFileHeader( 149 _In_ PVOID PcValue, 150 _Out_ PVOID *BaseOfImage); 151 152extern char __ImageBase; 153 154DECLSPEC_NOINLINE 155static 156VOID 157TestRtlPcToFileHeader(VOID) 158{ 159 PVOID ImageBase, Result; 160 PTEB Teb; 161 PPEB Peb; 162 163 /* First test a function from this image */ 164 Result = RtlPcToFileHeader(&TestRtlPcToFileHeader, &ImageBase); 165 ok_eq_pointer(Result, ImageBase); 166 ok_eq_pointer(ImageBase, &__ImageBase); 167 168#ifdef NTOS_MODE_USER 169 Teb = NtCurrentTeb(); 170#else 171 Teb = PsGetCurrentThreadTeb(); 172#endif 173 ok(Teb != NULL, "Teb is NULL!\n"); 174 if (Teb == NULL) 175 { 176 return; 177 } 178 179 _SEH2_TRY 180 { 181 Peb = Teb->ProcessEnvironmentBlock; 182 ok(Peb != NULL, "Peb is NULL!\n"); 183 if (Peb == NULL) 184 { 185 return; 186 } 187 188 /* Test an address somewhere within the main image of the current process */ 189 Result = RtlPcToFileHeader((PUCHAR)Peb->ImageBaseAddress + 0x1000, &ImageBase); 190 ok_eq_pointer(Result, ImageBase); 191#ifdef NTOS_MODE_USER 192 ok_eq_pointer(ImageBase, Peb->ImageBaseAddress); 193#else 194 ok_eq_pointer(ImageBase, NULL); 195#endif 196 } 197 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 198 { 199 ok(FALSE, "Got an exception!\n"); 200 } 201 _SEH2_END 202} 203#endif // _M_AMD64 204 205START_TEST(RtlStack) 206{ 207 TestStackWalk1(); 208#ifdef _M_AMD64 209 TestRtlPcToFileHeader(); 210#endif // _M_AMD64 211}