[DBGHELP_APITEST] Add rsym+pdb tests on loaded modules 1445/head
authorMark Jansen <mark.jansen@reactos.org>
Wed, 27 Mar 2019 22:09:36 +0000 (23:09 +0100)
committerMark Jansen <mark.jansen@reactos.org>
Thu, 15 Aug 2019 13:21:55 +0000 (15:21 +0200)
Also reorder some stuff to make the tests more alike

modules/rostests/apitests/dbghelp/data.c
modules/rostests/apitests/dbghelp/pdb.c
modules/rostests/apitests/dbghelp/rsym.c

index 13c823d..4898551 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * PROJECT:         ReactOS api tests
- * LICENSE:         GPLv2+ - See COPYING in the top level directory
- * PURPOSE:         Support functions for dbghelp api test
- * PROGRAMMER:      Mark Jansen
+ * PROJECT:     ReactOS api tests
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     Support functions for dbghelp api test
+ * COPYRIGHT:   Copyright 2017-2019 Mark Jansen (mark.jansen@reactos.org)
  */
 
 #include <windows.h>
@@ -69,7 +69,7 @@ static int extract_one(const char* filename, const char* resid)
 }
 
 
-int extract_msvc_exe(char szFile[MAX_PATH])
+int extract_msvc_dll(char szFile[MAX_PATH], char szPath[MAX_PATH])
 {
     const char* dir = tmpdir();
     BOOL ret = CreateDirectoryA(dir, NULL);
@@ -83,10 +83,11 @@ int extract_msvc_exe(char szFile[MAX_PATH])
     if (!extract_one(szFile, "msvc_uffs.dll"))
         return 0;
 
+    strcpy(szPath, dir);
     return 1;
 }
 
-void cleanup_msvc_exe()
+void cleanup_msvc_dll()
 {
     char szFile[MAX_PATH];
     BOOL ret;
@@ -103,7 +104,7 @@ void cleanup_msvc_exe()
     ok(ret, "RemoveDirectoryA failed(%d)\n", GetLastError());
 }
 
-int extract_gcc_exe(char szFile[MAX_PATH])
+int extract_gcc_dll(char szFile[MAX_PATH])
 {
     const char* dir = tmpdir();
     BOOL ret = CreateDirectoryA(dir, NULL);
@@ -116,7 +117,7 @@ int extract_gcc_exe(char szFile[MAX_PATH])
     return 1;
 }
 
-void cleanup_gcc_exe()
+void cleanup_gcc_dll()
 {
     char szFile[MAX_PATH];
     BOOL ret;
index 8f4988a..dc56ae7 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * PROJECT:         ReactOS api tests
- * LICENSE:         GPLv2+ - See COPYING in the top level directory
- * PURPOSE:         Test for dbghelp PDB functions
- * PROGRAMMER:      Mark Jansen
+ * PROJECT:     ReactOS api tests
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     Test for dbghelp PDB functions
+ * COPYRIGHT:   Copyright 2017-2019 Mark Jansen (mark.jansen@reactos.org)
  */
 
 #include <ntstatus.h>
 
 // data.c
 void create_compressed_files();
-int extract_msvc_exe(char szFile[MAX_PATH]);
-void cleanup_msvc_exe();
+int extract_msvc_dll(char szFile[MAX_PATH], char szPath[MAX_PATH]);
+void cleanup_msvc_dll();
 
 static HANDLE proc()
 {
     return GetCurrentProcess();
 }
 
-static BOOL init_sym_imp(const char* file, int line)
+static BOOL init_sym_imp(BOOL fInvadeProcess, const char* file, int line)
 {
-    if (!SymInitialize(proc(), NULL, FALSE))
+    if (!SymInitialize(proc(), NULL, fInvadeProcess))
     {
         DWORD err = GetLastError();
         ok_(file, line)(0, "Failed to init: 0x%x\n", err);
@@ -50,7 +50,7 @@ static void deinit_sym()
     SymCleanup(proc());
 }
 
-#define init_sym()          init_sym_imp(__FILE__, __LINE__)
+#define init_sym(fInvadeProcess)          init_sym_imp(fInvadeProcess, __FILE__, __LINE__)
 
 #define INIT_PSYM(buff) do { \
     memset((buff), 0, sizeof((buff))); \
@@ -222,7 +222,7 @@ PfnDliHook __pfnDliFailureHook2 = DliFailHook;
 
 
 /* Maybe our dbghelp.dll is too old? */
-static BOOL can_enumerate(HANDLE hProc, DWORD64 BaseAddress)
+static BOOL supports_pdb(HANDLE hProc, DWORD64 BaseAddress)
 {
     IMAGEHLP_MODULE64 ModuleInfo;
     BOOL Ret;
@@ -235,26 +235,13 @@ static BOOL can_enumerate(HANDLE hProc, DWORD64 BaseAddress)
 }
 
 
-static void test_SymFromName(HANDLE hProc, const char* szModuleName)
+static void test_SymFromName(HANDLE hProc, DWORD64 BaseAddress)
 {
     BOOL Ret;
     char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
     PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
 
-    DWORD64 BaseAddress;
-    DWORD dwErr;
-
-    if (!init_sym())
-        return;
-
-    SetLastError(ERROR_SUCCESS);
-    BaseAddress = SymLoadModule64(hProc, NULL, szModuleName, NULL, 0x600000, 0);
-    dwErr = GetLastError();
-
-    ok_ulonglong(BaseAddress, 0x600000);
-    ok_hex(dwErr, ERROR_SUCCESS);
-
-    if (!can_enumerate(hProc, BaseAddress))
+    if (!supports_pdb(hProc, BaseAddress))
     {
         skip("dbghelp.dll too old or cannot enumerate symbols!\n");
     }
@@ -314,29 +301,17 @@ static void test_SymFromName(HANDLE hProc, const char* szModuleName)
         ok_hex(pSymbol->Tag, SymTagPublicSymbol);
         ok_str(pSymbol->Name, "_FfsFormat@24");
     }
-
-    deinit_sym();
 }
 
-static void test_SymFromAddr(HANDLE hProc, const char* szModuleName)
+static void test_SymFromAddr(HANDLE hProc, DWORD64 BaseAddress)
 {
     BOOL Ret;
     char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
     PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
 
-    DWORD64 BaseAddress, Displacement;
+    DWORD64 Displacement;
     DWORD dwErr;
 
-    if (!init_sym())
-        return;
-
-    SetLastError(ERROR_SUCCESS);
-    BaseAddress = SymLoadModule64(hProc, NULL, szModuleName, NULL, 0x600000, 0);
-    dwErr = GetLastError();
-
-    ok_ulonglong(BaseAddress, 0x600000);
-    ok_hex(dwErr, ERROR_SUCCESS);
-
     /* No address found before load address of module */
     Displacement = 0;
     INIT_PSYM(buffer);
@@ -417,7 +392,7 @@ static void test_SymFromAddr(HANDLE hProc, const char* szModuleName)
     ok_hex(pSymbol->Tag, SymTagFunction);
     ok_str(pSymbol->Name, "FfsChkdsk");
 
-    if (!can_enumerate(hProc, BaseAddress))
+    if (!supports_pdb(hProc, BaseAddress))
     {
         skip("dbghelp.dll too old or cannot read this symbol!\n");
     }
@@ -435,8 +410,6 @@ static void test_SymFromAddr(HANDLE hProc, const char* szModuleName)
         ok_hex(pSymbol->Tag, SymTagPublicSymbol);
         ok_str(pSymbol->Name, "__imp__DbgPrint");
     }
-
-    deinit_sym();
 }
 
 typedef struct _test_context
@@ -484,25 +457,15 @@ static BOOL CALLBACK EnumSymProc(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID
     return TRUE;
 }
 
-static void test_SymEnumSymbols(HANDLE hProc, const char* szModuleName)
+static void test_SymEnumSymbols(HANDLE hProc, DWORD64 BaseAddress)
 {
     BOOL Ret;
-    DWORD dwErr;
-
     test_context ctx;
 
-    if (!init_sym())
-        return;
-
     ctx.Index = 0;
-    SetLastError(ERROR_SUCCESS);
-    ctx.BaseAddress = SymLoadModule64(hProc, NULL, szModuleName, NULL, 0x600000, 0);
-    dwErr = GetLastError();
-
-    ok_ulonglong(ctx.BaseAddress, 0x600000);
-    ok_hex(dwErr, ERROR_SUCCESS);
+    ctx.BaseAddress = BaseAddress;
 
-    if (!can_enumerate(hProc, ctx.BaseAddress))
+    if (!supports_pdb(hProc, ctx.BaseAddress))
     {
         skip("dbghelp.dll too old or cannot enumerate symbols!\n");
     }
@@ -512,8 +475,6 @@ static void test_SymEnumSymbols(HANDLE hProc, const char* szModuleName)
         ok_int(Ret, TRUE);
         ok_int(ctx.Index, ARRAYSIZE(test_data));
     }
-
-    deinit_sym();
 }
 
 typedef struct _symregcallback_context
@@ -524,7 +485,6 @@ typedef struct _symregcallback_context
 
 static struct _symregcallback_test_data {
     ULONG ActionCode;
-    const char* Name;
 } symregcallback_test_data[] = {
     { CBA_DEFERRED_SYMBOL_LOAD_CANCEL },
     { CBA_DEFERRED_SYMBOL_LOAD_START },
@@ -567,7 +527,7 @@ static void test_SymRegCallback(HANDLE hProc, const char* szModuleName, BOOL tes
     ctx.idx = 0;
     ctx.isANSI = testANSI;
 
-    if (!init_sym())
+    if (!init_sym(FALSE))
         return;
 
     if (testANSI)
@@ -604,14 +564,19 @@ static void test_SymRegCallback(HANDLE hProc, const char* szModuleName, BOOL tes
 START_TEST(pdb)
 {
     char szDllName[MAX_PATH];
-    //create_compressed_files();
+    char szDllPath[MAX_PATH], szOldDir[MAX_PATH];
+#ifdef _M_IX86
+    HMODULE hMod;
+#endif
+    DWORD64 BaseAddress;
+    DWORD dwErr, Options;
 
-    DWORD Options = SymGetOptions();
+    Options = SymGetOptions();
     Options &= ~(SYMOPT_UNDNAME);
     //Options |= SYMOPT_DEBUG;
     SymSetOptions(Options);
 
-    if (!extract_msvc_exe(szDllName))
+    if (!extract_msvc_dll(szDllName, szDllPath))
     {
         ok(0, "Failed extracting files\n");
         return;
@@ -619,12 +584,54 @@ START_TEST(pdb)
 
     init_dbghelp_version();
 
-    test_SymFromName(proc(), szDllName);
-    test_SymFromAddr(proc(), szDllName);
-    test_SymEnumSymbols(proc(), szDllName);
+    if (init_sym(FALSE))
+    {
+        SetLastError(ERROR_SUCCESS);
+        BaseAddress = SymLoadModule64(proc(), NULL, szDllName, NULL, 0x600000, 0);
+        dwErr = GetLastError();
+
+        ok_ulonglong(BaseAddress, 0x600000);
+        ok_hex(dwErr, ERROR_SUCCESS);
+
+        if (BaseAddress == 0x600000)
+        {
+            trace("Module loaded by SymLoadModule64\n");
+            test_SymFromName(proc(), BaseAddress);
+            test_SymFromAddr(proc(), BaseAddress);
+            test_SymEnumSymbols(proc(), BaseAddress);
+        }
+
+        deinit_sym();
+    }
+
+    /* This needs to load the module by itself */
     test_SymRegCallback(proc(), szDllName, TRUE);
     test_SymRegCallback(proc(), szDllName, FALSE);
 
-    cleanup_msvc_exe();
+#ifdef _M_IX86
+    hMod = LoadLibraryA(szDllName);
+    if (hMod)
+    {
+        BaseAddress = (DWORD64)(DWORD_PTR)hMod;
+        /* Make sure we can find the pdb */
+        GetCurrentDirectoryA(_countof(szOldDir), szOldDir);
+        SetCurrentDirectoryA(szDllPath);
+        /* Invade process */
+        if (init_sym(TRUE))
+        {
+            trace("Module loaded by LoadLibraryA\n");
+            test_SymFromName(proc(), BaseAddress);
+            test_SymFromAddr(proc(), BaseAddress);
+            test_SymEnumSymbols(proc(), BaseAddress);
+
+            deinit_sym();
+        }
+        /* Restore working dir */
+        SetCurrentDirectoryA(szOldDir);
+
+        FreeLibrary(hMod);
+    }
+#endif
 
+    cleanup_msvc_dll();
 }
index b471849..16b759c 100644 (file)
@@ -1,10 +1,10 @@
 /*
- * PROJECT:         ReactOS api tests
- * LICENSE:         GPLv2+ - See COPYING in the top level directory
- * PURPOSE:         Test for dbghelp rsym functions
- * PROGRAMMER:      Mark Jansen
- *
- *                  These tests are based on the PDB tests.
+ * PROJECT:     ReactOS api tests
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     Test for dbghelp rsym functions
+ * COPYRIGHT:   Copyright 2017-2019 Mark Jansen (mark.jansen@reactos.org)
+ * 
+ *              These tests are based on the PDB tests.
  */
 
 #include <ntstatus.h>
 
 // data.c
 void dump_rsym(const char* filename);
-int extract_gcc_exe(char szFile[MAX_PATH]);
-void cleanup_gcc_exe();
+int extract_gcc_dll(char szFile[MAX_PATH]);
+void cleanup_gcc_dll();
 
 static HANDLE proc()
 {
     return GetCurrentProcess();
 }
 
-static BOOL init_sym_imp(const char* file, int line)
+static BOOL init_sym_imp(BOOL fInvadeProcess, const char* file, int line)
 {
-    if (!SymInitialize(proc(), NULL, FALSE))
+    if (!SymInitialize(proc(), NULL, fInvadeProcess))
     {
         DWORD err = GetLastError();
         ok_(file, line)(0, "Failed to init: 0x%x\n", err);
@@ -69,6 +69,14 @@ static void deinit_sym()
     SymCleanup(proc());
 }
 
+#define init_sym(fInvadeProcess)          init_sym_imp(fInvadeProcess, __FILE__, __LINE__)
+
+#define INIT_PSYM(buff) do { \
+    memset((buff), 0, sizeof((buff))); \
+    ((PSYMBOL_INFO)(buff))->SizeOfStruct = sizeof(SYMBOL_INFO); \
+    ((PSYMBOL_INFO)(buff))->MaxNameLen = MAX_SYM_NAME; \
+} while (0)
+
 static BOOL supports_rsym(HANDLE hProc, DWORD64 BaseAddress)
 {
     IMAGEHLP_MODULE64 ModuleInfo;
@@ -83,36 +91,19 @@ static BOOL supports_rsym(HANDLE hProc, DWORD64 BaseAddress)
         ModuleInfo.CVSig == ('R' | ('S' << 8) | ('Y' << 16) | ('M' << 24));
 }
 
-#define init_sym()          init_sym_imp(__FILE__, __LINE__)
 
-#define INIT_PSYM(buff) do { \
-    memset((buff), 0, sizeof((buff))); \
-    ((PSYMBOL_INFO)(buff))->SizeOfStruct = sizeof(SYMBOL_INFO); \
-    ((PSYMBOL_INFO)(buff))->MaxNameLen = MAX_SYM_NAME; \
-} while (0)
-
-
-static void test_SymFromName(HANDLE hProc, const char* szModuleName)
+static void test_SymFromName(HANDLE hProc, DWORD64 BaseAddress)
 {
     BOOL Ret;
     char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
     PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
 
-    DWORD64 BaseAddress;
-    DWORD dwErr;
-
-    if (!init_sym())
-        return;
-
-    SetLastError(ERROR_SUCCESS);
-    BaseAddress = SymLoadModule64(hProc, NULL, szModuleName, NULL, 0x600000, 0);
-    dwErr = GetLastError();
-
-    if (supports_rsym(hProc, BaseAddress))
+    if (!supports_rsym(hProc, BaseAddress))
+    {
+        skip("dbghelp.dll cannot parse rsym\n");
+    }
+    else
     {
-        ok_ulonglong(BaseAddress, 0x600000);
-        ok_hex(dwErr, ERROR_SUCCESS);
-
         INIT_PSYM(buffer);
         Ret = SymFromName(hProc, "DllMain", pSymbol);
         ok_int(Ret, TRUE);
@@ -140,35 +131,23 @@ static void test_SymFromName(HANDLE hProc, const char* szModuleName)
         ok_hex(pSymbol->Tag, SymTagFunction);
         ok_str(pSymbol->Name, "FfsFormat");
     }
-    else
-    {
-        skip("dbghelp.dll cannot parse rsym\n");
-    }
-
-    deinit_sym();
 }
 
-static void test_SymFromAddr(HANDLE hProc, const char* szModuleName)
+static void test_SymFromAddr(HANDLE hProc, DWORD64 BaseAddress)
 {
     BOOL Ret;
     char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
     PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
 
-    DWORD64 BaseAddress, Displacement;
+    DWORD64 Displacement;
     DWORD dwErr;
 
-    if (!init_sym())
-        return;
-
-    SetLastError(ERROR_SUCCESS);
-    BaseAddress = SymLoadModule64(hProc, NULL, szModuleName, NULL, 0x600000, 0);
-    dwErr = GetLastError();
-
-    if (supports_rsym(hProc, BaseAddress))
+    if (!supports_rsym(hProc, BaseAddress))
+    {
+        skip("dbghelp.dll cannot parse rsym\n");
+    }
+    else
     {
-        ok_ulonglong(BaseAddress, 0x600000);
-        ok_hex(dwErr, ERROR_SUCCESS);
-
         /* No address found before load address of module */
         Displacement = 0;
         INIT_PSYM(buffer);
@@ -241,12 +220,6 @@ static void test_SymFromAddr(HANDLE hProc, const char* szModuleName)
         ok_hex(pSymbol->Tag, SymTagPublicSymbol);
         ok_str(pSymbol->Name, "_head_dll_ntdll_libntdll_a");
     }
-    else
-    {
-        skip("dbghelp.dll cannot parse rsym\n");
-    }
-
-    deinit_sym();
 }
 
 typedef struct _test_context
@@ -286,7 +259,7 @@ static struct _test_data {
     { 0x4000, 0, SymTagPublicSymbol, "_head_dll_ntdll_libntdll_a", __LINE__ },
 };
 
-BOOL CALLBACK EnumSymProc(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID UserContext)
+static BOOL CALLBACK EnumSymProc(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID UserContext)
 {
     test_context* ctx = UserContext;
 
@@ -310,60 +283,85 @@ BOOL CALLBACK EnumSymProc(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID UserCon
     return TRUE;
 }
 
-static void test_SymEnumSymbols(HANDLE hProc, const char* szModuleName)
+static void test_SymEnumSymbols(HANDLE hProc, DWORD64 BaseAddress)
 {
     BOOL Ret;
-    DWORD dwErr;
-
     test_context ctx;
 
-    if (!init_sym())
-        return;
-
     ctx.Index = 0;
-    SetLastError(ERROR_SUCCESS);
-    ctx.BaseAddress = SymLoadModule64(hProc, NULL, szModuleName, NULL, 0x600000, 0);
-    dwErr = GetLastError();
+    ctx.BaseAddress = BaseAddress;
 
-    if (supports_rsym(hProc, ctx.BaseAddress))
+    if (!supports_rsym(hProc, ctx.BaseAddress))
     {
-        ok_ulonglong(ctx.BaseAddress, 0x600000);
-        ok_hex(dwErr, ERROR_SUCCESS);
-
-        Ret = SymEnumSymbols(hProc, ctx.BaseAddress, NULL, EnumSymProc, &ctx);
-        ok_int(Ret, TRUE);
-        ok_int(ctx.Index, ARRAYSIZE(test_data));
+        skip("dbghelp.dll cannot parse rsym\n");
     }
     else
     {
-        skip("dbghelp.dll cannot parse rsym\n");
+        Ret = SymEnumSymbols(hProc, ctx.BaseAddress, NULL, EnumSymProc, &ctx);
+        ok_int(Ret, TRUE);
+        ok_int(ctx.Index, ARRAYSIZE(test_data));
     }
-
-    deinit_sym();
 }
 
 
-
-
 START_TEST(rsym)
 {
     char szDllName[MAX_PATH];
-    //dump_rsym("R:\\src\\trunk\\reactos\\modules\\rostests\\apitests\\dbghelp\\testdata\\gcc_uffs.dll");
+#ifdef _M_IX86
+    HMODULE hMod;
+#endif
+    DWORD64 BaseAddress;
+    DWORD dwErr, Options;
 
-    DWORD Options = SymGetOptions();
+    Options = SymGetOptions();
     Options &= ~(SYMOPT_UNDNAME);
     //Options |= SYMOPT_DEBUG;
     SymSetOptions(Options);
 
-    if (!extract_gcc_exe(szDllName))
+    if (!extract_gcc_dll(szDllName))
     {
         ok(0, "Failed extracting files\n");
         return;
     }
 
-    test_SymFromName(proc(), szDllName);
-    test_SymFromAddr(proc(), szDllName);
-    test_SymEnumSymbols(proc(), szDllName);
+    if (init_sym(FALSE))
+    {
+        SetLastError(ERROR_SUCCESS);
+        BaseAddress = SymLoadModule64(proc(), NULL, szDllName, NULL, 0x600000, 0);
+        dwErr = GetLastError();
+
+        ok_ulonglong(BaseAddress, 0x600000);
+        ok_hex(dwErr, ERROR_SUCCESS);
+
+        if (BaseAddress == 0x600000)
+        {
+            trace("Module loaded by SymLoadModule64\n");
+            test_SymFromName(proc(), BaseAddress);
+            test_SymFromAddr(proc(), BaseAddress);
+            test_SymEnumSymbols(proc(), BaseAddress);
+        }
+
+        deinit_sym();
+    }
+
+#ifdef _M_IX86
+    hMod = LoadLibraryA(szDllName);
+    if (hMod)
+    {
+        BaseAddress = (DWORD64)(DWORD_PTR)hMod;
+        /* Invade process */
+        if (init_sym(TRUE))
+        {
+            trace("Module loaded by LoadLibraryA\n");
+            test_SymFromName(proc(), BaseAddress);
+            test_SymFromAddr(proc(), BaseAddress);
+            test_SymEnumSymbols(proc(), BaseAddress);
 
-    cleanup_gcc_exe();
+            deinit_sym();
+        }
+
+        FreeLibrary(hMod);
+    }
+#endif
+    cleanup_gcc_dll();
 }