ReactOS  0.4.15-dev-1397-g19779b3
dbghelp.c
Go to the documentation of this file.
1 /*
2  * Copyright 2018 Zebediah Figura
3  *
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.
8  *
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.
13  *
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
17  */
18 
19 #include "windef.h"
20 #include "verrsrc.h"
21 #include "dbghelp.h"
22 #include "wine/test.h"
23 
24 #if defined(__i386__) || defined(__x86_64__)
25 
26 static DWORD CALLBACK stack_walk_thread(void *arg)
27 {
29  ok(!count, "got %d\n", count);
30  return 0;
31 }
32 
33 static void test_stack_walk(void)
34 {
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;
45 
46  thread = CreateThread(NULL, 0, stack_walk_thread, NULL, 0, NULL);
47 
48  /* wait for the thread to suspend itself */
49  do
50  {
51  Sleep(50);
54  }
55  while (!count);
56 
57  ctx.ContextFlags = CONTEXT_CONTROL;
59  ok(ret, "got error %u\n", ret);
60 
61  frame.AddrPC.Mode = AddrModeFlat;
62  frame.AddrFrame.Mode = AddrModeFlat;
63  frame.AddrStack.Mode = AddrModeFlat;
64 
65 #ifdef __i386__
67 
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__)
76 
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;
85 
86  /* first invocation just calculates the return address */
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),
93  ok(frame.AddrStack.Offset == frame0.AddrStack.Offset, "expected %s, got %s\n",
94  wine_dbgstr_longlong(frame0.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));
98 
99  while (frame.AddrReturn.Offset)
100  {
101  char *addr;
102 
105  ok(ret, "StackWalk64() failed: %u\n", GetLastError());
106 
107  addr = (void *)(DWORD_PTR)frame.AddrPC.Offset;
108 
109  if (addr > (char *)stack_walk_thread && addr < (char *)stack_walk_thread + 0x100)
110  {
111  found_our_frame = TRUE;
112 
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);
117  }
118  }
119 
122  ok(!ret, "StackWalk64() should have failed\n");
123 
124  ok(found_our_frame, "didn't find stack_walk_thread frame\n");
125 }
126 
127 #else /* __i386__ || __x86_64__ */
128 
129 static void test_stack_walk(void)
130 {
131 }
132 
133 #endif /* __i386__ || __x86_64__ */
134 
135 START_TEST(dbghelp)
136 {
138  ok(ret, "got error %u\n", GetLastError());
139 
140  test_stack_walk();
141 
143  ok(ret, "got error %u\n", GetLastError());
144 }
#define CONTEXT_CONTROL
Definition: nt_native.h:1369
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
#define TRUE
Definition: types.h:120
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define CALLBACK
Definition: compat.h:35
PVOID WINAPI SymFunctionTableAccess64(HANDLE, DWORD64)
Definition: module.c:1367
BOOL WINAPI StackWalk64(DWORD MachineType, HANDLE hProcess, HANDLE hThread, LPSTACKFRAME64 frame, PVOID ctx, PREAD_PROCESS_MEMORY_ROUTINE64 f_read_mem, PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, PTRANSLATE_ADDRESS_ROUTINE64 f_xlat_adr)
Definition: stack.c:210
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1044
#define IMAGE_FILE_MACHINE_AMD64
Definition: ntimage.h:17
static void test_stack_walk(void)
Definition: dbghelp.c:129
WORD Segment
Definition: compat.h:1034
BOOL WINAPI GetThreadContext(IN HANDLE hThread, OUT LPCONTEXT lpContext)
Definition: thread.c:500
#define FALSE
Definition: types.h:117
HANDLE WINAPI GetCurrentThread(VOID)
Definition: proc.c:1148
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL WINAPI SymCleanup(HANDLE hProcess)
Definition: dbghelp.c:531
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:136
#define IMAGE_FILE_MACHINE_I386
Definition: pedump.c:174
BOOL WINAPI SymInitialize(HANDLE hProcess, PCSTR UserSearchPath, BOOL fInvadeProcess)
Definition: dbghelp.c:508
DWORD64 Offset
Definition: compat.h:1033
struct _SYMBOL_INFO SYMBOL_INFO
ADDRESS64 AddrReturn
Definition: compat.h:1261
unsigned long DWORD
Definition: ntddk_ex.h:95
static HANDLE thread
Definition: service.c:33
int ret
ADDRESS64 AddrStack
Definition: compat.h:1263
GLenum const GLvoid * addr
Definition: glext.h:9621
DWORD WINAPI SuspendThread(IN HANDLE hThread)
Definition: thread.c:641
static const char machine[]
Definition: profile.c:104
DWORD64 WINAPI SymGetModuleBase64(HANDLE, DWORD64)
Definition: module.c:1309
START_TEST(dbghelp)
Definition: dbghelp.c:135
#define GetCurrentProcess()
Definition: compat.h:618
uint32_t DWORD_PTR
Definition: typedefs.h:65
BOOL WINAPI SymFromAddr(HANDLE hProcess, DWORD64 Address, DWORD64 *Displacement, PSYMBOL_INFO Symbol)
Definition: symbol.c:1263
uint64_t DWORD64
Definition: typedefs.h:67
#define ok(value,...)
Definition: atltest.h:57
#define NULL
Definition: types.h:112
ADDRESS64 AddrPC
Definition: compat.h:1260
DWORD WINAPI ResumeThread(IN HANDLE hThread)
Definition: thread.c:566
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ADDRESS_MODE Mode
Definition: compat.h:1035
ADDRESS64 AddrFrame
Definition: compat.h:1262