diff --git a/modules/rostests/winetests/CMakeLists.txt b/modules/rostests/winetests/CMakeLists.txt index fb8df2e9709..45a146c75d9 100644 --- a/modules/rostests/winetests/CMakeLists.txt +++ b/modules/rostests/winetests/CMakeLists.txt @@ -36,6 +36,7 @@ add_subdirectory(cryptui) add_subdirectory(d3dcompiler_43) add_subdirectory(d3drm) add_subdirectory(d3dx9_36) +add_subdirectory(dbghelp) add_subdirectory(devenum) add_subdirectory(dinput) add_subdirectory(dinput8) diff --git a/modules/rostests/winetests/dbghelp/CMakeLists.txt b/modules/rostests/winetests/dbghelp/CMakeLists.txt new file mode 100644 index 00000000000..2cc768a42ff --- /dev/null +++ b/modules/rostests/winetests/dbghelp/CMakeLists.txt @@ -0,0 +1,6 @@ + +add_executable(dbghelp_winetest dbghelp.c testlist.c) +target_compile_definitions(dbghelp_winetest PRIVATE WINETEST_USE_DBGSTR_LONGLONG) +set_module_type(dbghelp_winetest win32cui) +add_importlibs(dbghelp_winetest dbghelp gdi32 user32 msvcrt kernel32 ntdll) +add_rostests_file(TARGET dbghelp_winetest) diff --git a/modules/rostests/winetests/dbghelp/dbghelp.c b/modules/rostests/winetests/dbghelp/dbghelp.c new file mode 100644 index 00000000000..214adb7b16b --- /dev/null +++ b/modules/rostests/winetests/dbghelp/dbghelp.c @@ -0,0 +1,144 @@ +/* + * Copyright 2018 Zebediah Figura + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "windef.h" +#include "verrsrc.h" +#include "dbghelp.h" +#include "wine/test.h" + +#if defined(__i386__) || defined(__x86_64__) + +static DWORD CALLBACK stack_walk_thread(void *arg) +{ + DWORD count = SuspendThread(GetCurrentThread()); + ok(!count, "got %d\n", count); + return 0; +} + +static void test_stack_walk(void) +{ + char si_buf[sizeof(SYMBOL_INFO) + 200]; + SYMBOL_INFO *si = (SYMBOL_INFO *)si_buf; + STACKFRAME64 frame = {{0}}, frame0; + BOOL found_our_frame = FALSE; + DWORD machine; + HANDLE thread; + DWORD64 disp; + CONTEXT ctx; + DWORD count; + BOOL ret; + + thread = CreateThread(NULL, 0, stack_walk_thread, NULL, 0, NULL); + + /* wait for the thread to suspend itself */ + do + { + Sleep(50); + count = SuspendThread(thread); + ResumeThread(thread); + } + while (!count); + + ctx.ContextFlags = CONTEXT_CONTROL; + ret = GetThreadContext(thread, &ctx); + ok(ret, "got error %u\n", ret); + + frame.AddrPC.Mode = AddrModeFlat; + frame.AddrFrame.Mode = AddrModeFlat; + frame.AddrStack.Mode = AddrModeFlat; + +#ifdef __i386__ + machine = IMAGE_FILE_MACHINE_I386; + + frame.AddrPC.Segment = ctx.SegCs; + frame.AddrPC.Offset = ctx.Eip; + frame.AddrFrame.Segment = ctx.SegSs; + frame.AddrFrame.Offset = ctx.Ebp; + frame.AddrStack.Segment = ctx.SegSs; + frame.AddrStack.Offset = ctx.Esp; +#elif defined(__x86_64__) + machine = IMAGE_FILE_MACHINE_AMD64; + + frame.AddrPC.Segment = ctx.SegCs; + frame.AddrPC.Offset = ctx.Rip; + frame.AddrFrame.Segment = ctx.SegSs; + frame.AddrFrame.Offset = ctx.Rbp; + frame.AddrStack.Segment = ctx.SegSs; + frame.AddrStack.Offset = ctx.Rsp; +#endif + frame0 = frame; + + /* first invocation just calculates the return address */ + ret = StackWalk64(machine, GetCurrentProcess(), thread, &frame, &ctx, NULL, + SymFunctionTableAccess64, SymGetModuleBase64, NULL); + ok(ret, "StackWalk64() failed: %u\n", GetLastError()); + ok(frame.AddrPC.Offset == frame0.AddrPC.Offset, "expected %s, got %s\n", + wine_dbgstr_longlong(frame0.AddrPC.Offset), + wine_dbgstr_longlong(frame.AddrPC.Offset)); + ok(frame.AddrStack.Offset == frame0.AddrStack.Offset, "expected %s, got %s\n", + wine_dbgstr_longlong(frame0.AddrStack.Offset), + wine_dbgstr_longlong(frame.AddrStack.Offset)); + ok(frame.AddrReturn.Offset && frame.AddrReturn.Offset != frame.AddrPC.Offset, + "got bad return address %s\n", wine_dbgstr_longlong(frame.AddrReturn.Offset)); + + while (frame.AddrReturn.Offset) + { + char *addr; + + ret = StackWalk64(machine, GetCurrentProcess(), thread, &frame, &ctx, NULL, + SymFunctionTableAccess64, SymGetModuleBase64, NULL); + ok(ret, "StackWalk64() failed: %u\n", GetLastError()); + + addr = (void *)(DWORD_PTR)frame.AddrPC.Offset; + + if (addr > (char *)stack_walk_thread && addr < (char *)stack_walk_thread + 0x100) + { + found_our_frame = TRUE; + + si->SizeOfStruct = sizeof(SYMBOL_INFO); + si->MaxNameLen = 200; + if (SymFromAddr(GetCurrentProcess(), frame.AddrPC.Offset, &disp, si)) + ok(!strcmp(si->Name, "stack_walk_thread"), "got wrong name %s\n", si->Name); + } + } + + ret = StackWalk64(machine, GetCurrentProcess(), thread, &frame, &ctx, NULL, + SymFunctionTableAccess64, SymGetModuleBase64, NULL); + ok(!ret, "StackWalk64() should have failed\n"); + + ok(found_our_frame, "didn't find stack_walk_thread frame\n"); +} + +#else /* __i386__ || __x86_64__ */ + +static void test_stack_walk(void) +{ +} + +#endif /* __i386__ || __x86_64__ */ + +START_TEST(dbghelp) +{ + BOOL ret = SymInitialize(GetCurrentProcess(), NULL, TRUE); + ok(ret, "got error %u\n", GetLastError()); + + test_stack_walk(); + + ret = SymCleanup(GetCurrentProcess()); + ok(ret, "got error %u\n", GetLastError()); +} diff --git a/modules/rostests/winetests/dbghelp/testlist.c b/modules/rostests/winetests/dbghelp/testlist.c new file mode 100644 index 00000000000..b78c165301a --- /dev/null +++ b/modules/rostests/winetests/dbghelp/testlist.c @@ -0,0 +1,12 @@ +/* Automatically generated file; DO NOT EDIT!! */ + +#define STANDALONE +#include + +extern void func_dbghelp(void); + +const struct test winetest_testlist[] = +{ + { "dbghelp", func_dbghelp }, + { 0, 0 } +}; diff --git a/sdk/tools/winesync/dbghelp.cfg b/sdk/tools/winesync/dbghelp.cfg index 3b1605ae74b..bd721b981a3 100644 --- a/sdk/tools/winesync/dbghelp.cfg +++ b/sdk/tools/winesync/dbghelp.cfg @@ -1,5 +1,6 @@ directories: dlls/dbghelp: dll/win32/dbghelp + dlls/dbghelp/tests: modules/rostests/winetests/dbghelp files: include/dbghelp.h: sdk/include/psdk/dbghelp.h include/wine/mscvpdb.h: sdk/include/reactos/wine/mscvpdb.h