mfplat: Read queue subscriber within the critical section.
[wine/zf.git] / dlls / dbghelp / tests / dbghelp.c
blob214adb7b16b32134e2e22a12bf818dec264d3533
1 /*
2 * Copyright 2018 Zebediah Figura
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include "windef.h"
20 #include "verrsrc.h"
21 #include "dbghelp.h"
22 #include "wine/test.h"
24 #if defined(__i386__) || defined(__x86_64__)
26 static DWORD CALLBACK stack_walk_thread(void *arg)
28 DWORD count = SuspendThread(GetCurrentThread());
29 ok(!count, "got %d\n", count);
30 return 0;
33 static void test_stack_walk(void)
35 char si_buf[sizeof(SYMBOL_INFO) + 200];
36 SYMBOL_INFO *si = (SYMBOL_INFO *)si_buf;
37 STACKFRAME64 frame = {{0}}, frame0;
38 BOOL found_our_frame = FALSE;
39 DWORD machine;
40 HANDLE thread;
41 DWORD64 disp;
42 CONTEXT ctx;
43 DWORD count;
44 BOOL ret;
46 thread = CreateThread(NULL, 0, stack_walk_thread, NULL, 0, NULL);
48 /* wait for the thread to suspend itself */
51 Sleep(50);
52 count = SuspendThread(thread);
53 ResumeThread(thread);
55 while (!count);
57 ctx.ContextFlags = CONTEXT_CONTROL;
58 ret = GetThreadContext(thread, &ctx);
59 ok(ret, "got error %u\n", ret);
61 frame.AddrPC.Mode = AddrModeFlat;
62 frame.AddrFrame.Mode = AddrModeFlat;
63 frame.AddrStack.Mode = AddrModeFlat;
65 #ifdef __i386__
66 machine = IMAGE_FILE_MACHINE_I386;
68 frame.AddrPC.Segment = ctx.SegCs;
69 frame.AddrPC.Offset = ctx.Eip;
70 frame.AddrFrame.Segment = ctx.SegSs;
71 frame.AddrFrame.Offset = ctx.Ebp;
72 frame.AddrStack.Segment = ctx.SegSs;
73 frame.AddrStack.Offset = ctx.Esp;
74 #elif defined(__x86_64__)
75 machine = IMAGE_FILE_MACHINE_AMD64;
77 frame.AddrPC.Segment = ctx.SegCs;
78 frame.AddrPC.Offset = ctx.Rip;
79 frame.AddrFrame.Segment = ctx.SegSs;
80 frame.AddrFrame.Offset = ctx.Rbp;
81 frame.AddrStack.Segment = ctx.SegSs;
82 frame.AddrStack.Offset = ctx.Rsp;
83 #endif
84 frame0 = frame;
86 /* first invocation just calculates the return address */
87 ret = StackWalk64(machine, GetCurrentProcess(), thread, &frame, &ctx, NULL,
88 SymFunctionTableAccess64, SymGetModuleBase64, NULL);
89 ok(ret, "StackWalk64() failed: %u\n", GetLastError());
90 ok(frame.AddrPC.Offset == frame0.AddrPC.Offset, "expected %s, got %s\n",
91 wine_dbgstr_longlong(frame0.AddrPC.Offset),
92 wine_dbgstr_longlong(frame.AddrPC.Offset));
93 ok(frame.AddrStack.Offset == frame0.AddrStack.Offset, "expected %s, got %s\n",
94 wine_dbgstr_longlong(frame0.AddrStack.Offset),
95 wine_dbgstr_longlong(frame.AddrStack.Offset));
96 ok(frame.AddrReturn.Offset && frame.AddrReturn.Offset != frame.AddrPC.Offset,
97 "got bad return address %s\n", wine_dbgstr_longlong(frame.AddrReturn.Offset));
99 while (frame.AddrReturn.Offset)
101 char *addr;
103 ret = StackWalk64(machine, GetCurrentProcess(), thread, &frame, &ctx, NULL,
104 SymFunctionTableAccess64, SymGetModuleBase64, NULL);
105 ok(ret, "StackWalk64() failed: %u\n", GetLastError());
107 addr = (void *)(DWORD_PTR)frame.AddrPC.Offset;
109 if (addr > (char *)stack_walk_thread && addr < (char *)stack_walk_thread + 0x100)
111 found_our_frame = TRUE;
113 si->SizeOfStruct = sizeof(SYMBOL_INFO);
114 si->MaxNameLen = 200;
115 if (SymFromAddr(GetCurrentProcess(), frame.AddrPC.Offset, &disp, si))
116 ok(!strcmp(si->Name, "stack_walk_thread"), "got wrong name %s\n", si->Name);
120 ret = StackWalk64(machine, GetCurrentProcess(), thread, &frame, &ctx, NULL,
121 SymFunctionTableAccess64, SymGetModuleBase64, NULL);
122 ok(!ret, "StackWalk64() should have failed\n");
124 ok(found_our_frame, "didn't find stack_walk_thread frame\n");
127 #else /* __i386__ || __x86_64__ */
129 static void test_stack_walk(void)
133 #endif /* __i386__ || __x86_64__ */
135 START_TEST(dbghelp)
137 BOOL ret = SymInitialize(GetCurrentProcess(), NULL, TRUE);
138 ok(ret, "got error %u\n", GetLastError());
140 test_stack_walk();
142 ret = SymCleanup(GetCurrentProcess());
143 ok(ret, "got error %u\n", GetLastError());