Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212/* * 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];
staticVOIDTestStackWalk3(VOID);
DECLSPEC_NOINLINEstaticVOIDTestStackWalk4(VOID){ PVOID Frames[5]; ULONG Ret; ULONG Hash; ULONG ExpectedHash; ULONG i; const ULONG FunctionSizeGuess = 0x1000; NTSTATUS ExceptionStatus = STATUS_SUCCESS;
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);
_SEH2_TRY { RtlCaptureStackBackTrace(0, 5, NULL, NULL); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ExceptionStatus = _SEH2_GetExceptionCode(); } _SEH2_END; if (GetNTVersion() == _WIN32_WINNT_WS03) ok_eq_hex(ExceptionStatus, STATUS_ACCESS_VIOLATION); else ok_eq_hex(ExceptionStatus, STATUS_SUCCESS);
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_NOINLINEstaticVOIDTestStackWalk3(VOID){ ReturnAddresses[2] = _ReturnAddress(); TestStackWalk4();}
DECLSPEC_NOINLINEstaticVOIDTestStackWalk2(VOID){ ReturnAddresses[1] = _ReturnAddress(); TestStackWalk3();}
DECLSPEC_NOINLINEstaticVOIDTestStackWalk1(VOID){ ReturnAddresses[0] = _ReturnAddress(); TestStackWalk2();}
#ifdef _M_AMD64NTSYSAPIPVOIDNTAPIRtlPcToFileHeader( _In_ PVOID PcValue, _Out_ PVOID *BaseOfImage);
extern char __ImageBase;
DECLSPEC_NOINLINEstaticVOIDTestRtlPcToFileHeader(VOID){ PVOID ImageBase, Result; PTEB Teb; PPEB Peb;
/* First test a function from this image */ Result = RtlPcToFileHeader(&TestRtlPcToFileHeader, &ImageBase); ok_eq_pointer(Result, ImageBase); ok_eq_pointer(ImageBase, &__ImageBase);
#ifdef NTOS_MODE_USER Teb = NtCurrentTeb();#else Teb = PsGetCurrentThreadTeb();#endif ok(Teb != NULL, "Teb is NULL!\n"); if (Teb == NULL) { return; }
_SEH2_TRY { Peb = Teb->ProcessEnvironmentBlock; ok(Peb != NULL, "Peb is NULL!\n"); if (Peb == NULL) { return; }
/* Test an address somewhere within the main image of the current process */ Result = RtlPcToFileHeader((PUCHAR)Peb->ImageBaseAddress + 0x1000, &ImageBase); ok_eq_pointer(Result, ImageBase);#ifdef NTOS_MODE_USER ok_eq_pointer(ImageBase, Peb->ImageBaseAddress);#else ok_eq_pointer(ImageBase, NULL);#endif } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ok(FALSE, "Got an exception!\n"); } _SEH2_END}#endif // _M_AMD64
START_TEST(RtlStack){ TestStackWalk1();#ifdef _M_AMD64 TestRtlPcToFileHeader();#endif // _M_AMD64}