ReactOS 0.4.16-dev-1946-g52006dd
setjmp.c File Reference
#include <apitest.h>
#include <pseh/pseh2.h>
#include <setjmp.h>
#include <assert.h>
#include <rtlfuncs.h>
Include dependency graph for setjmp.c:

Go to the source code of this file.

Macros

#define todo_pseh
 
#define CHECK_POINT(number)
 
#define check_buffer_registers(Buf, Sp, Pc)    check_buffer_registers_(__LINE__, Buf, Sp, Pc)
 
#define DO_COME(number)    ok(s_check_points[number], "CheckPoint #%d: Didn't reach\n", number)
 
#define NEVER_COME(number)
 

Functions

static void TEST_setjmp_normal (void)
 
static void TEST_setjmp_return_check (void)
 
static void TEST_longjmp (int value)
 
static void TEST_setjmp_longjmp_integration (void)
 
static void TEST_setjmp_zero_longjmp_check (void)
 
void call_setjmp (_JUMP_BUFFER *Buf)
 
ULONG_PTR get_sp (void)
 
static void check_buffer_registers_ (ULONG Line, _JUMP_BUFFER *Buf, ULONG_PTR Sp, void *Pc)
 
static void TEST_buffer_contents (void)
 
 START_TEST (setjmp)
 

Variables

static jmp_buf g_jmp_buf
 
static INT s_check_points [16] = { 0 }
 
char setjmp_return_address
 

Macro Definition Documentation

◆ check_buffer_registers

#define check_buffer_registers (   Buf,
  Sp,
  Pc 
)     check_buffer_registers_(__LINE__, Buf, Sp, Pc)

Definition at line 259 of file setjmp.c.

◆ CHECK_POINT

#define CHECK_POINT (   number)
Value:
do { \
s_check_points[number] = __LINE__; \
} while (0)
static unsigned int number
Definition: dsound.c:1479
static INT s_check_points[16]
Definition: setjmp.c:102
#define _countof(array)
Definition: sndvol32.h:70

Definition at line 104 of file setjmp.c.

◆ DO_COME

#define DO_COME (   number)     ok(s_check_points[number], "CheckPoint #%d: Didn't reach\n", number)

◆ NEVER_COME

#define NEVER_COME (   number)
Value:
ok(!s_check_points[number], "CheckPoint #%d: Wrongly reached Line %d\n", \
#define ok(value,...)
Definition: atltest.h:57

◆ todo_pseh

#define todo_pseh

Definition at line 19 of file setjmp.c.

Function Documentation

◆ call_setjmp()

void call_setjmp ( _JUMP_BUFFER *  Buf)

Referenced by TEST_buffer_contents().

◆ check_buffer_registers_()

static void check_buffer_registers_ ( ULONG  Line,
_JUMP_BUFFER *  Buf,
ULONG_PTR  Sp,
void Pc 
)
static

Definition at line 213 of file setjmp.c.

214{
215#ifdef _M_AMD64
216 ok_eq_hex64_(__FILE__, Line, Buf->Frame, Sp - 0xF0);
217 ok_eq_hex64_(__FILE__, Line, Buf->Rbx, 0xA1A1A1A1A1A1A1A1ULL);
218 ok_eq_hex64_(__FILE__, Line, Buf->Rsp, Sp - 0xF0);
219 ok_eq_hex64_(__FILE__, Line, Buf->Rbp, 0xA2A2A2A2A2A2A2A2ULL);
220 ok_eq_hex64_(__FILE__, Line, Buf->Rsi, 0xA3A3A3A3A3A3A3A3ULL);
221 ok_eq_hex64_(__FILE__, Line, Buf->Rdi, 0xA4A4A4A4A4A4A4A4ULL);
222 ok_eq_hex64_(__FILE__, Line, Buf->R12, 0xACACACACACACACACULL);
223 ok_eq_hex64_(__FILE__, Line, Buf->R13, 0xADADADADADADADADULL);
224 ok_eq_hex64_(__FILE__, Line, Buf->R14, 0xAEAEAEAEAEAEAEAEULL);
225 ok_eq_hex64_(__FILE__, Line, Buf->R15, 0xAFAFAFAFAFAFAFAFULL);
226 ok_eq_hex64_(__FILE__, Line, Buf->Rip, (ULONG64)Pc);
227 ok_eq_hex_(__FILE__, Line, Buf->MxCsr, 0x00001f80);
228 ok_eq_hex64_(__FILE__, Line, Buf->FpCsr, 0x27F);
229 ok_eq_hex64_(__FILE__, Line, Buf->Spare, 0xCCCC);
230 ok_eq_hex64_(__FILE__, Line, Buf->Xmm6.Part[0], 0x0606060606060606ULL);
231 ok_eq_hex64_(__FILE__, Line, Buf->Xmm6.Part[1], 0x1616161616161616ULL);
232 ok_eq_hex64_(__FILE__, Line, Buf->Xmm7.Part[0], 0x0707070707070707ULL);
233 ok_eq_hex64_(__FILE__, Line, Buf->Xmm7.Part[1], 0x1717171717171717ULL);
234 ok_eq_hex64_(__FILE__, Line, Buf->Xmm8.Part[0], 0x0808080808080808ULL);
235 ok_eq_hex64_(__FILE__, Line, Buf->Xmm8.Part[1], 0x1818181818181818ULL);
236 ok_eq_hex64_(__FILE__, Line, Buf->Xmm9.Part[0], 0x0909090909090909ULL);
237 ok_eq_hex64_(__FILE__, Line, Buf->Xmm9.Part[1], 0x1919191919191919ULL);
238 ok_eq_hex64_(__FILE__, Line, Buf->Xmm10.Part[0], 0x0A0A0A0A0A0A0A0AULL);
239 ok_eq_hex64_(__FILE__, Line, Buf->Xmm10.Part[1], 0x1A1A1A1A1A1A1A1AULL);
240 ok_eq_hex64_(__FILE__, Line, Buf->Xmm11.Part[0], 0x0B0B0B0B0B0B0B0BULL);
241 ok_eq_hex64_(__FILE__, Line, Buf->Xmm11.Part[1], 0x1B1B1B1B1B1B1B1BULL);
242 ok_eq_hex64_(__FILE__, Line, Buf->Xmm12.Part[0], 0x0C0C0C0C0C0C0C0CULL);
243 ok_eq_hex64_(__FILE__, Line, Buf->Xmm12.Part[1], 0x1C1C1C1C1C1C1C1CULL);
244 ok_eq_hex64_(__FILE__, Line, Buf->Xmm13.Part[0], 0x0D0D0D0D0D0D0D0DULL);
245 ok_eq_hex64_(__FILE__, Line, Buf->Xmm13.Part[1], 0x1D1D1D1D1D1D1D1DULL);
246 ok_eq_hex64_(__FILE__, Line, Buf->Xmm14.Part[0], 0x0E0E0E0E0E0E0E0EULL);
247 ok_eq_hex64_(__FILE__, Line, Buf->Xmm14.Part[1], 0x1E1E1E1E1E1E1E1EULL);
248 ok_eq_hex64_(__FILE__, Line, Buf->Xmm15.Part[0], 0x0F0F0F0F0F0F0F0FULL);
249 ok_eq_hex64_(__FILE__, Line, Buf->Xmm15.Part[1], 0x1F1F1F1F1F1F1F1FULL);
250#elif defined(_M_IX86)
251 ok_eq_hex_(__FILE__, Line, Buf->Ebp, 0xA1A1A1A1ul);
252 ok_eq_hex_(__FILE__, Line, Buf->Ebx, 0xA2A2A2A2ul);
253 ok_eq_hex_(__FILE__, Line, Buf->Edi, 0xA3A3A3A3ul);
254 ok_eq_hex_(__FILE__, Line, Buf->Esi, 0xA4A4A4A4ul);
255 ok_eq_hex_(__FILE__, Line, Buf->Esp, Sp - 0x38);
256 ok_eq_hex_(__FILE__, Line, Buf->Eip, (ULONG)Pc);
257#endif
258}
#define ok_eq_hex_(file, line, value, expected)
Definition: apitest.h:144
#define ok_eq_hex64_(file, line, value, expected)
Definition: apitest.h:145
ULONG Sp
Definition: kdb_expr.c:99
unsigned __int64 ULONG64
Definition: imports.h:198
Definition: ncftp.h:79
uint32_t ULONG
Definition: typedefs.h:59

◆ get_sp()

ULONG_PTR get_sp ( void  )

Referenced by TEST_buffer_contents().

◆ START_TEST()

START_TEST ( setjmp  )

Definition at line 558 of file setjmp.c.

559{
561
562 /* FIXME: These tests are insufficient */
568#ifdef _M_IX86
569 Test_setjmp1_longjmp_inside_SEH();
570 Test_setjmp1_external_inside_SEH();
571 //Test_setjmp1_no_SEH_registration();
572 Test_setjmp3();
573 Test_setjmp3_with_SEH();
574#endif /* _M_IX86 */
575
576#define DO_COME(number) \
577 ok(s_check_points[number], "CheckPoint #%d: Didn't reach\n", number)
578#define NEVER_COME(number) \
579 ok(!s_check_points[number], "CheckPoint #%d: Wrongly reached Line %d\n", \
580 number, s_check_points[number])
581
582 DO_COME(0);
583 NEVER_COME(1);
584
585 DO_COME(0);
586 NEVER_COME(1);
587 DO_COME(2);
588 NEVER_COME(3);
589 DO_COME(4);
590 NEVER_COME(5);
591 DO_COME(6);
592 NEVER_COME(7);
593 DO_COME(8);
594 NEVER_COME(9);
595 NEVER_COME(10);
596 DO_COME(11);
597 NEVER_COME(12);
598 DO_COME(13);
599 NEVER_COME(14);
600 NEVER_COME(15);
601}
#define ZeroMemory
Definition: minwinbase.h:31
static void TEST_buffer_contents(void)
Definition: setjmp.c:262
static void TEST_setjmp_normal(void)
Definition: setjmp.c:24
#define NEVER_COME(number)
static void TEST_setjmp_return_check(void)
Definition: setjmp.c:109
#define DO_COME(number)
static void TEST_setjmp_zero_longjmp_check(void)
Definition: setjmp.c:162
static void TEST_setjmp_longjmp_integration(void)
Definition: setjmp.c:139

◆ TEST_buffer_contents()

static void TEST_buffer_contents ( void  )
static

Definition at line 262 of file setjmp.c.

263{
264 _JUMP_BUFFER buf;
265
266 memset(&buf, 0xCC, sizeof(buf));
269
270#ifdef _M_AMD64
271
272 memset(&buf, 0xCC, sizeof(buf));
273 call_setjmpex(&buf);
275
276#elif defined(_M_IX86)
277
278 ok_eq_hex(buf.Registration, __readfsdword(0));
279 todo_pseh ok_eq_hex(buf.TryLevel, 0xFFFFFFFF);
280 ok_eq_hex(buf.Cookie, 0xCCCCCCCC);
281 ok_eq_hex(buf.UnwindFunc, 0xCCCCCCCC);
282 ok_eq_hex(buf.UnwindData[0], 0xCCCCCCCC);
283 ok_eq_hex(buf.UnwindData[1], 0xCCCCCCCC);
284 ok_eq_hex(buf.UnwindData[2], 0xCCCCCCCC);
285 ok_eq_hex(buf.UnwindData[3], 0xCCCCCCCC);
286 ok_eq_hex(buf.UnwindData[4], 0xCCCCCCCC);
287 ok_eq_hex(buf.UnwindData[5], 0xCCCCCCCC);
288
289 // Temporarily remove the SEH registration (__writefsdword(0, ...) is not allowed with MSVC)
290 PULONG ExceptionRegistrationPtr = (PULONG)NtCurrentTeb();
291 ULONG Registration = *ExceptionRegistrationPtr;
292 *ExceptionRegistrationPtr = 0xFFFFFFFF;
293
294 memset(&buf, 0xCC, sizeof(buf));
296 ok_eq_hex(buf.Registration, 0xFFFFFFFF);
297 ok_eq_hex(buf.TryLevel, 0xFFFFFFFF);
298 ok_eq_hex(buf.Cookie, 0xCCCCCCCC);
299 ok_eq_hex(buf.UnwindFunc, 0xCCCCCCCC);
300
301 // Restore the SEH registration
302 *ExceptionRegistrationPtr = Registration;
303
305 {
308 {
310 memset(&buf, 0xCC, sizeof(buf));
312 }
314 {
315 /* This is to ensure that the exception handler is not optimized out. */
317 }
318 _SEH2_END;
319 }
321 {
322 /* This is to ensure that the exception handler is not optimized out. */
324 }
325 _SEH2_END;
326
327 ok_eq_hex(buf.Registration, Registration);
328 todo_pseh ok_eq_hex(buf.TryLevel, 1);
329 ok_eq_hex(buf.Cookie, 0xCCCCCCCC);
330 ok_eq_hex(buf.UnwindFunc, 0xCCCCCCCC);
331#endif
332}
#define ok_eq_hex(value, expected)
Definition: apitest.h:134
#define ok_int(expression, result)
Definition: atltest.h:134
_Must_inspect_result_ _In_ CONST FLT_REGISTRATION * Registration
Definition: fltkernel.h:991
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define GetExceptionCode
Definition: excpt.h:83
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
PPC_QUAL unsigned long __readfsdword(const unsigned long Offset)
Definition: intrin_ppc.h:382
#define NtCurrentTeb
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:82
#define _SEH2_END
Definition: pseh2_64.h:171
#define _SEH2_TRY
Definition: pseh2_64.h:71
#define memset(x, y, z)
Definition: compat.h:39
char setjmp_return_address
#define todo_pseh
Definition: setjmp.c:19
void call_setjmp(_JUMP_BUFFER *Buf)
ULONG_PTR get_sp(void)
#define check_buffer_registers(Buf, Sp, Pc)
Definition: setjmp.c:259
uint32_t * PULONG
Definition: typedefs.h:59

Referenced by START_TEST().

◆ TEST_longjmp()

static void TEST_longjmp ( int  value)
static

Definition at line 132 of file setjmp.c.

133{
134 CHECK_POINT(4);
135 longjmp(g_jmp_buf, value);
136 CHECK_POINT(5);
137}
#define CHECK_POINT(number)
Definition: setjmp.c:104
static jmp_buf g_jmp_buf
Definition: setjmp.c:22
Definition: pdh_main.c:96

Referenced by TEST_setjmp_longjmp_integration(), and TEST_setjmp_zero_longjmp_check().

◆ TEST_setjmp_longjmp_integration()

static void TEST_setjmp_longjmp_integration ( void  )
static

Definition at line 139 of file setjmp.c.

140{
141 volatile int value;
142
143 memset(&g_jmp_buf, 0xCC, sizeof(g_jmp_buf));
145
146 if (value == 0)
147 {
148 CHECK_POINT(6);
149 TEST_longjmp(0xBEEFCAFE);
150 CHECK_POINT(7);
151 }
152 else if (value == 0xBEEFCAFE)
153 {
154 CHECK_POINT(8);
155 }
156 else
157 {
158 CHECK_POINT(9);
159 }
160}
static void TEST_longjmp(int value)
Definition: setjmp.c:132
#define setjmp
Definition: setjmp.h:211

Referenced by START_TEST().

◆ TEST_setjmp_normal()

static void TEST_setjmp_normal ( void  )
static

Definition at line 24 of file setjmp.c.

25{
26 volatile int stage = 0;
27 volatile DWORD exception = 0;
28 volatile BOOL abnormal = FALSE, finally_called = FALSE;
29 int value;
30
32 switch (stage)
33 {
34 case 0:
35 ok_int(value, 0);
36 stage = 1;
37 longjmp(g_jmp_buf, 999);
39 break;
40 case 1:
41 ok_int(value, 999);
42 stage = 2;
43 longjmp(g_jmp_buf, 0);
45 break;
46 case 2:
47 ok_int(value, 1);
48 stage = 3;
49#ifdef __clang__ /* avoiding clang build hung up */
50 skip("avoiding clang build crash\n");
51#else /* ndef __clang__ */
53 {
54 longjmp(g_jmp_buf, 333);
55 }
57 {
58 finally_called = TRUE;
59 abnormal = AbnormalTermination();
60 }
63 break;
64#endif /* ndef __clang__ */
65 case 3:
66 ok_int(value, 333);
67#ifdef _M_AMD64 // This is broken on Windows 2003 x64
68 if (NtCurrentPeb()->OSMajorVersion >= 6)
69#endif
70 {
71 ok_int(finally_called, TRUE);
72 ok_int(abnormal, TRUE);
73 }
74 stage = 4;
75#ifdef __clang__ /* avoiding clang build hung up */
76 skip("avoiding clang build crash\n");
77#else /* ndef __clang__ */
79 {
80 longjmp(g_jmp_buf, 444);
81 }
83 {
84 exception = -1;
85 }
88 break;
89#endif /* ndef __clang__ */
90 case 4:
91 ok_int(value, 444);
92 ok_int(exception, 0);
93 break;
94 default:
96 break;
97 }
98
99 ok_int(stage, 4);
100}
#define NtCurrentPeb()
Definition: FLS.c:22
#define skip(...)
Definition: atltest.h:64
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define assert(x)
Definition: debug.h:53
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define AbnormalTermination
Definition: excpt.h:87
#define _SEH2_FINALLY
Definition: pseh2_64.h:130

Referenced by START_TEST().

◆ TEST_setjmp_return_check()

static void TEST_setjmp_return_check ( void  )
static

Definition at line 109 of file setjmp.c.

110{
111 volatile int x = 1001, value;
112 memset(&g_jmp_buf, 0xCC, sizeof(g_jmp_buf));
114
115 if (value == 0)
116 {
117 CHECK_POINT(0);
118 longjmp(g_jmp_buf, 999);
119 CHECK_POINT(1);
120 }
121 else if (value == 999)
122 {
123 CHECK_POINT(2);
124 ok_int(x, 1001);
125 }
126 else
127 {
128 CHECK_POINT(3);
129 }
130}
GLint GLint GLint GLint GLint x
Definition: gl.h:1548

Referenced by START_TEST().

◆ TEST_setjmp_zero_longjmp_check()

static void TEST_setjmp_zero_longjmp_check ( void  )
static

Definition at line 162 of file setjmp.c.

163{
164 volatile int value;
165 volatile BOOL went_zero = FALSE;
166
167 memset(&g_jmp_buf, 0xCC, sizeof(g_jmp_buf));
169
170 if (value == 0)
171 {
172 if (went_zero)
173 {
174 CHECK_POINT(10);
175 return;
176 }
177 went_zero = TRUE;
178
179 CHECK_POINT(11);
180
181 TEST_longjmp(0); /* giving zero should go to one */
182
183 CHECK_POINT(12);
184 }
185 else if (value == 1)
186 {
187 if (went_zero)
188 {
189 CHECK_POINT(13);
190 }
191 else
192 {
193 CHECK_POINT(14);
194 }
195 }
196 else
197 {
198 CHECK_POINT(15);
199 }
200}

Referenced by START_TEST().

Variable Documentation

◆ g_jmp_buf

◆ s_check_points

INT s_check_points[16] = { 0 }
static

Definition at line 102 of file setjmp.c.

Referenced by START_TEST().

◆ setjmp_return_address

char setjmp_return_address
extern

Referenced by TEST_buffer_contents().