[USP10_WINETEST] Sync with Wine Staging 2.9. CORE-13362
[reactos.git] / rostests / kmtests / rtl / RtlStack.c
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 }