diff options
author | Mike McLaughlin <mikem@microsoft.com> | 2015-12-02 16:47:27 -0800 |
---|---|---|
committer | Mike McLaughlin <mikem@microsoft.com> | 2015-12-08 15:58:28 -0800 |
commit | 160de625e36f120af8454c7333e476176791380f (patch) | |
tree | a318b590168f9d69305c15ac9908ba1800bafc97 | |
parent | d1633211ee01ed05f467cacd36418f313e7a3d71 (diff) | |
download | coreclr-160de625e36f120af8454c7333e476176791380f.tar.gz coreclr-160de625e36f120af8454c7333e476176791380f.tar.bz2 coreclr-160de625e36f120af8454c7333e476176791380f.zip |
Use dbi's path to load dac and add RPATH to make files.
Fixes VS's problems with debugging and running different versions of coreclr.
Set RPATH for OSX is @loader_path and removed now unnecessary load of mscordaccore
in the lldb sos plugin.
Simplify the GetDacModule code to use PAL_GetPALDirectoryW instead of depending on GetModuleInst()
and the module handle passed to DllMain.
Changed PAL_RegisterModule not to also call the DllMain of the module so it wouldn't be called twice.
-rw-r--r-- | src/ToolBox/SOS/Strike/CMakeLists.txt | 8 | ||||
-rw-r--r-- | src/ToolBox/SOS/lldbplugin/soscommand.cpp | 5 | ||||
-rw-r--r-- | src/debug/di/cordb.cpp | 14 | ||||
-rw-r--r-- | src/debug/di/rsmain.cpp | 4 | ||||
-rw-r--r-- | src/debug/di/rspriv.h | 2 | ||||
-rw-r--r-- | src/debug/di/shimprocess.cpp | 20 | ||||
-rw-r--r-- | src/dlls/mscordbi/CMakeLists.txt | 9 | ||||
-rw-r--r-- | src/pal/inc/pal.h | 12 | ||||
-rw-r--r-- | src/pal/src/loader/module.cpp | 184 |
9 files changed, 145 insertions, 113 deletions
diff --git a/src/ToolBox/SOS/Strike/CMakeLists.txt b/src/ToolBox/SOS/Strike/CMakeLists.txt index 2825df5efa..edb046e99e 100644 --- a/src/ToolBox/SOS/Strike/CMakeLists.txt +++ b/src/ToolBox/SOS/Strike/CMakeLists.txt @@ -1,3 +1,11 @@ +# Set the RPATH of sos so that it can find dependencies without needing to set LD_LIBRARY_PATH +# For more information: http://www.cmake.org/Wiki/CMake_RPATH_handling. +if(CLR_CMAKE_PLATFORM_DARWIN) + set(CMAKE_INSTALL_RPATH "@loader_path") +else() + set(CMAKE_INSTALL_RPATH "\$ORIGIN") +endif(CLR_CMAKE_PLATFORM_DARWIN) + if(CLR_CMAKE_PLATFORM_ARCH_AMD64) add_definitions(-DSOS_TARGET_AMD64=1) add_definitions(-D_TARGET_WIN64_=1) diff --git a/src/ToolBox/SOS/lldbplugin/soscommand.cpp b/src/ToolBox/SOS/lldbplugin/soscommand.cpp index 71065b866b..518d62c441 100644 --- a/src/ToolBox/SOS/lldbplugin/soscommand.cpp +++ b/src/ToolBox/SOS/lldbplugin/soscommand.cpp @@ -90,11 +90,6 @@ exit: if (g_coreclrDirectory != NULL) { - - // Load the DAC module first explicitly because SOS and DBI - // have implicit references to the DAC's PAL. - LoadModule(client, MAKEDLLNAME_A("mscordaccore")); - m_sosHandle = LoadModule(client, MAKEDLLNAME_A("sos")); } } diff --git a/src/debug/di/cordb.cpp b/src/debug/di/cordb.cpp index d05d7f7b42..11596cc941 100644 --- a/src/debug/di/cordb.cpp +++ b/src/debug/di/cordb.cpp @@ -21,11 +21,10 @@ #include "dbgtransportmanager.h" #endif // FEATURE_DBGIPC_TRANSPORT_DI -// Helper function returns the instance handle of this module. -HINSTANCE GetModuleInst(); - //********** Globals. ********************************************************* +#ifndef FEATURE_PAL HINSTANCE g_hInst; // Instance handle to this piece of code. +#endif //----------------------------------------------------------------------------- // SxS Versioning story for Mscordbi (ICorDebug + friends) @@ -180,9 +179,9 @@ BOOL WINAPI DbgDllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) case DLL_PROCESS_ATTACH: { +#ifndef FEATURE_PAL g_hInst = hInstance; - -#ifdef FEATURE_PAL +#else int err = PAL_InitializeDLL(); if(err != 0) { @@ -429,16 +428,15 @@ HRESULT STDMETHODCALLTYPE CClassFactory::LockServer( } - - - //***************************************************************************** // This helper provides access to the instance handle of the loaded image. //***************************************************************************** +#ifndef FEATURE_PAL HINSTANCE GetModuleInst() { return g_hInst; } +#endif //----------------------------------------------------------------------------- diff --git a/src/debug/di/rsmain.cpp b/src/debug/di/rsmain.cpp index 1103d8e3f9..ae5832088f 100644 --- a/src/debug/di/rsmain.cpp +++ b/src/debug/di/rsmain.cpp @@ -486,7 +486,11 @@ void CordbCommonBase::InitializeCommon() unsigned level = REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::EXTERNAL_LogLevel, LL_INFO1000); unsigned bytesPerThread = REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_StressLogSize, STRESSLOG_CHUNK_SIZE * 2); unsigned totalBytes = REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_TotalStressLogSize, STRESSLOG_CHUNK_SIZE * 1024); +#ifndef FEATURE_PAL StressLog::Initialize(facilities, level, bytesPerThread, totalBytes, GetModuleInst()); +#else + StressLog::Initialize(facilities, level, bytesPerThread, totalBytes, NULL); +#endif } } diff --git a/src/debug/di/rspriv.h b/src/debug/di/rspriv.h index e2f7ea6d8d..a89b17d49b 100644 --- a/src/debug/di/rspriv.h +++ b/src/debug/di/rspriv.h @@ -138,7 +138,9 @@ class DbgTransportSession; class ShimProcess; +#ifndef FEATURE_PAL extern HINSTANCE GetModuleInst(); +#endif template <class T> diff --git a/src/debug/di/shimprocess.cpp b/src/debug/di/shimprocess.cpp index ed315b6cad..4c13c3f3d2 100644 --- a/src/debug/di/shimprocess.cpp +++ b/src/debug/di/shimprocess.cpp @@ -1825,16 +1825,16 @@ HRESULT ShimProcess::FindLoadedCLR(CORDB_ADDRESS * pClrInstanceId) HMODULE ShimProcess::GetDacModule() { - HModuleHolder hDacDll; + WCHAR wszAccessDllPath[MAX_LONGPATH]; #ifdef FEATURE_PAL - // For now on Unix we'll just search for DAC in the default location. - // Debugger can always control it by setting LD_LIBRARY_PATH env var. - WCHAR wszAccessDllPath[MAX_LONGPATH] = MAKEDLLNAME_W(W("mscordaccore")); - -#else - WCHAR wszAccessDllPath[MAX_LONGPATH]; + if (!PAL_GetPALDirectoryW(wszAccessDllPath, _countof(wszAccessDllPath))) + { + ThrowLastError(); + } + wcscat_s(wszAccessDllPath, _countof(wszAccessDllPath), MAKEDLLNAME_W(W("mscordaccore"))); +#else // // Load the access DLL from the same directory as the the current CLR Debugging Services DLL. // @@ -1844,7 +1844,7 @@ HMODULE ShimProcess::GetDacModule() ThrowLastError(); } - PWSTR pPathTail = wcsrchr(wszAccessDllPath, '\\'); + PWSTR pPathTail = wcsrchr(wszAccessDllPath, DIRECTORY_SEPARATOR_CHAR_W); if (!pPathTail) { ThrowHR(E_INVALIDARG); @@ -1855,7 +1855,7 @@ HMODULE ShimProcess::GetDacModule() // mscordaccore.dll <-- coreclr // mscordacwks.dll <-- desktop PCWSTR eeFlavor = -#ifdef FEATURE_MAIN_CLR_MODULE_USES_CORE_NAME +#if defined(FEATURE_MAIN_CLR_MODULE_USES_CORE_NAME) W("core"); #else W("wks"); @@ -1869,7 +1869,7 @@ HMODULE ShimProcess::GetDacModule() { ThrowHR(E_INVALIDARG); } -#endif //!FEATURE_PAL +#endif // FEATURE_PAL hDacDll.Assign(WszLoadLibrary(wszAccessDllPath)); if (!hDacDll) diff --git a/src/dlls/mscordbi/CMakeLists.txt b/src/dlls/mscordbi/CMakeLists.txt index e89fb05858..ea5bf4091a 100644 --- a/src/dlls/mscordbi/CMakeLists.txt +++ b/src/dlls/mscordbi/CMakeLists.txt @@ -1,3 +1,12 @@ + +# Set the RPATH of mscordbi so that it can find dependencies without needing to set LD_LIBRARY_PATH +# For more information: http://www.cmake.org/Wiki/CMake_RPATH_handling. +if(CLR_CMAKE_PLATFORM_DARWIN) + set(CMAKE_INSTALL_RPATH "@loader_path") +else() + set(CMAKE_INSTALL_RPATH "\$ORIGIN") +endif(CLR_CMAKE_PLATFORM_DARWIN) + set(MSCORDBI_SOURCES mscordbi.cpp ) diff --git a/src/pal/inc/pal.h b/src/pal/inc/pal.h index 294502b73b..0bf1fb6de5 100644 --- a/src/pal/inc/pal.h +++ b/src/pal/inc/pal.h @@ -3642,13 +3642,13 @@ PALIMPORT HMODULE PALAPI LoadLibraryA( - IN LPCSTR lpLibFileName); + IN LPCSTR lpLibFileName); PALIMPORT HMODULE PALAPI LoadLibraryW( - IN LPCWSTR lpLibFileName); + IN LPCWSTR lpLibFileName); PALIMPORT HMODULE @@ -3667,17 +3667,17 @@ LoadLibraryExW( IN DWORD dwFlags); PALIMPORT -HMODULE +void * PALAPI PAL_LoadLibraryDirect( - IN LPCWSTR lpLibFileName); + IN LPCWSTR lpLibFileName); PALIMPORT HMODULE PALAPI PAL_RegisterLibraryDirect( - IN HMODULE dl_handle, - IN LPCWSTR lpLibFileName); + IN void *dl_handle, + IN LPCWSTR lpLibFileName); /*++ Function: diff --git a/src/pal/src/loader/module.cpp b/src/pal/src/loader/module.cpp index 4d0426d8b5..04e4b9cd59 100644 --- a/src/pal/src/loader/module.cpp +++ b/src/pal/src/loader/module.cpp @@ -107,11 +107,11 @@ bool LOADConvertLibraryPathWideStringToMultibyteString( static BOOL LOADValidateModule(MODSTRUCT *module); static LPWSTR LOADGetModuleFileName(MODSTRUCT *module); -static HMODULE LOADLoadLibraryDirect(LPCSTR libraryNameOrPath, bool setLastError); -static HMODULE LOADRegisterLibraryDirect(HMODULE dl_handle, LPCSTR libraryNameOrPath, BOOL fDynamic); +static MODSTRUCT *LOADAddModule(void *dl_handle, LPCSTR libraryNameOrPath); +static void *LOADLoadLibraryDirect(LPCSTR libraryNameOrPath); +static HMODULE LOADRegisterLibraryDirect(void *dl_handle, LPCSTR libraryNameOrPath, BOOL fDynamic); static HMODULE LOADLoadLibrary(LPCSTR shortAsciiName, BOOL fDynamic); static void LOAD_SEH_CallDllMain(MODSTRUCT *module, DWORD dwReason, LPVOID lpReserved); -static MODSTRUCT *LOADAllocModule(void *dl_handle, LPCSTR name); /* API function definitions ***************************************************/ @@ -267,7 +267,7 @@ Loads a library using a system call, without registering the library with the mo Returns the system handle to the loaded library, or nullptr upon failure (error is set via SetLastError()). */ -HMODULE +void * PALAPI PAL_LoadLibraryDirect( IN LPCWSTR lpLibFileName) @@ -275,7 +275,7 @@ PAL_LoadLibraryDirect( PathCharString pathstr; CHAR * lpstr = NULL; INT name_length; - HMODULE hModule = NULL; + void *dl_handle = NULL; PERF_ENTRY(LoadLibraryDirect); ENTRY("LoadLibraryDirect (lpLibFileName=%p (%S)) \n", @@ -301,13 +301,12 @@ PAL_LoadLibraryDirect( FILEDosToUnixPathA(lpstr); pathstr.CloseBuffer(name_length); - /* let LOADLoadLibraryDirect call SetLastError in case of failure */ - hModule = LOADLoadLibraryDirect(lpstr, true /* setLastError */); + dl_handle = LOADLoadLibraryDirect(lpstr); done: - LOGEXIT("LoadLibraryDirect returns HMODULE %p\n", hModule); + LOGEXIT("LoadLibraryDirect returns HMODULE %p\n", dl_handle); PERF_EXIT(LoadLibraryDirect); - return hModule; + return dl_handle; } /* @@ -321,7 +320,7 @@ Returns a PAL handle to the loaded library, or nullptr upon failure (error is se HMODULE PALAPI PAL_RegisterLibraryDirect( - IN HMODULE dl_handle, + IN void *dl_handle, IN LPCWSTR lpLibFileName) { PathCharString pathstr; @@ -355,7 +354,7 @@ PAL_RegisterLibraryDirect( /* let LOADRegisterLibraryDirect call SetLastError in case of failure */ LockModuleList(); - hModule = LOADRegisterLibraryDirect(dl_handle, lpstr, true /* fDynamic */); + hModule = LOADRegisterLibraryDirect((void *)dl_handle, lpstr, true /* fDynamic */); UnlockModuleList(); done: @@ -446,7 +445,7 @@ GetProcAddress( // inside the PAL, fall back to a normal search. if (ProcAddress == NULL) { - ProcAddress = (FARPROC) dlsym(module->dl_handle, lpProcName); + ProcAddress = (FARPROC) dlsym(module->dl_handle, lpProcName); } if (ProcAddress) @@ -454,8 +453,7 @@ GetProcAddress( TRACE("Symbol %s found at address %p in module %p (named %S)\n", lpProcName, ProcAddress, module, MODNAME(module)); - /* if we don't know the module's full name yet, this is our chance to - obtain it */ + /* if we don't know the module's full name yet, this is our chance to obtain it */ if (!module->lib_name && module->dl_handle) { const char* libName = PAL_dladdr((LPVOID)ProcAddress); @@ -577,7 +575,7 @@ FreeLibrary( if (module->hinstance) { PUNREGISTER_MODULE unregisterModule = (PUNREGISTER_MODULE)dlsym(module->dl_handle, "PAL_UnregisterModule"); - if (unregisterModule) + if (unregisterModule != nullptr) { unregisterModule(module->hinstance); } @@ -771,7 +769,8 @@ Function: PAL_RegisterModule Register the module with the target module and return a module handle in - the target module's context. + the target module's context. Doesn't call the DllMain because it is used + as part of calling DllMain in the calling module. --*/ @@ -788,7 +787,16 @@ PAL_RegisterModule( PERF_ENTRY(PAL_RegisterModule); ENTRY("PAL_RegisterModule(%s)\n", lpLibFileName ? lpLibFileName : ""); - hinstance = (HINSTANCE)LOADLoadLibrary(lpLibFileName, FALSE); + LockModuleList(); + + void *dl_handle = LOADLoadLibraryDirect(lpLibFileName); + if (dl_handle) + { + // This only creates/adds the module handle and doesn't call DllMain + hinstance = LOADAddModule(dl_handle, lpLibFileName); + } + + UnlockModuleList(); LOGEXIT("PAL_RegisterModule returns HINSTANCE %p\n", hinstance); PERF_EXIT(PAL_RegisterModule); @@ -811,6 +819,8 @@ PAL_UnregisterModule( PERF_ENTRY(PAL_UnregisterModule); ENTRY("PAL_UnregisterModule(hInstance=%p)\n", hInstance); + // DllMain won't be called because PAL_UnregisterModule didn't + // query its address and save it. FreeLibrary(hInstance); LOGEXIT("PAL_UnregisterModule returns\n"); @@ -1364,6 +1374,37 @@ static LPWSTR LOADGetModuleFileName(MODSTRUCT *module) return module->lib_name; } +/* +Function: + LOADLoadLibraryDirect [internal] + + Loads a library using a system call, without registering the library with the module list. + +Parameters: + LPCSTR libraryNameOrPath: The library to load. + +Return value: + System handle to the loaded library, or nullptr upon failure (error is set via SetLastError()). +*/ +static void *LOADLoadLibraryDirect(LPCSTR libraryNameOrPath) +{ + _ASSERTE(libraryNameOrPath != nullptr); + _ASSERTE(libraryNameOrPath[0] != '\0'); + + void *dl_handle = dlopen(libraryNameOrPath, RTLD_LAZY); + if (dl_handle == nullptr) + { + WARN("dlopen() failed; dlerror says '%s'\n", dlerror()); + SetLastError(ERROR_MOD_NOT_FOUND); + } + else + { + TRACE("dlopen() found module %s\n", libraryNameOrPath); + } + + return dl_handle; +} + /*++ Function : LOADAllocModule @@ -1430,82 +1471,49 @@ static MODSTRUCT *LOADAllocModule(void *dl_handle, LPCSTR name) /* Function: - LOADLoadLibraryDirect [internal] - - Loads a library using a system call, without registering the library with the module list. - -Parameters: - LPCSTR libraryNameOrPath: The library to load. - bool setLastError: True to set the last error upon failure, false otherwise. - -Return value: - System handle to the loaded library, or nullptr upon failure (error is set via SetLastError() if 'setLastError' is true). -*/ -static HMODULE LOADLoadLibraryDirect(LPCSTR libraryNameOrPath, bool setLastError) -{ - _ASSERTE(libraryNameOrPath != nullptr); - _ASSERTE(libraryNameOrPath[0] != '\0'); - - HMODULE dl_handle = dlopen(libraryNameOrPath, RTLD_LAZY); - if (dl_handle != nullptr) - { - TRACE("dlopen() found module %s\n", libraryNameOrPath); - } - else if (setLastError) - { - WARN("dlopen() failed; dlerror says '%s'\n", dlerror()); - SetLastError(ERROR_MOD_NOT_FOUND); - } - - return dl_handle; -} - -/* -Function: - LOADRegisterLibraryDirect [internal] + LOADAddModule [internal] Registers a system handle to a loaded library with the module list. Parameters: - HMODULE dl_handle: System handle to the loaded library. + void *dl_handle: System handle to the loaded library. LPCSTR libraryNameOrPath: The library that was loaded. - BOOL fDynamic: TRUE if dynamic load through LoadLibrary, FALSE if static load through RegisterLibrary. Return value: PAL handle to the loaded library, or nullptr upon failure (error is set via SetLastError()). */ -static HMODULE LOADRegisterLibraryDirect(HMODULE dl_handle, LPCSTR libraryNameOrPath, BOOL fDynamic) +static MODSTRUCT *LOADAddModule(void *dl_handle, LPCSTR libraryNameOrPath) { _ASSERTE(dl_handle != nullptr); _ASSERTE(libraryNameOrPath != nullptr); _ASSERTE(libraryNameOrPath[0] != '\0'); - MODSTRUCT *module; - DWORD dwError; - #if !RETURNS_NEW_HANDLES_ON_REPEAT_DLOPEN /* search module list for a match. */ - module = &exe_module; + MODSTRUCT *module = &exe_module; do { if (dl_handle == module->dl_handle) { /* found the handle. increment the refcount and return the existing module structure */ - TRACE("Found matching module %p for module name %s\n", - module, libraryNameOrPath); + TRACE("Found matching module %p for module name %s\n", module, libraryNameOrPath); + if (module->refcount != -1) + { module->refcount++; + } dlclose(dl_handle); return module; } module = module->next; + } while (module != &exe_module); #endif TRACE("Module doesn't exist : creating %s.\n", libraryNameOrPath); - module = LOADAllocModule(dl_handle, libraryNameOrPath); + module = LOADAllocModule(dl_handle, libraryNameOrPath); if (NULL == module) { ERROR("couldn't create new module\n"); @@ -1525,14 +1533,33 @@ static HMODULE LOADRegisterLibraryDirect(HMODULE dl_handle, LPCSTR libraryNameOr module->device = stat_buf.st_dev; #endif - /* We now get the address of DllMain if the module contains one. We save - the last error and restore it afterward, because our caller doesn't - care about GetProcAddress failures. */ - dwError = GetLastError(); + return module; +} + +/* +Function: + LOADRegisterLibraryDirect [internal] - module->pDllMain = (PDLLMAIN)GetProcAddress((HMODULE)module, "DllMain"); + Registers a system handle to a loaded library with the module list. - SetLastError(dwError); +Parameters: + void *dl_handle: System handle to the loaded library. + LPCSTR libraryNameOrPath: The library that was loaded. + BOOL fDynamic: TRUE if dynamic load through LoadLibrary, FALSE if static load through RegisterLibrary. + +Return value: + PAL handle to the loaded library, or nullptr upon failure (error is set via SetLastError()). +*/ +static HMODULE LOADRegisterLibraryDirect(void *dl_handle, LPCSTR libraryNameOrPath, BOOL fDynamic) +{ + MODSTRUCT *module = LOADAddModule(dl_handle, libraryNameOrPath); + if (module == nullptr) + { + return nullptr; + } + + /* We now get the address of DllMain if the module contains one. */ + module->pDllMain = (PDLLMAIN)dlsym(module->dl_handle, "DllMain"); /* If it did contain a DllMain, call it. */ if (module->pDllMain) @@ -1544,7 +1571,7 @@ static HMODULE LOADRegisterLibraryDirect(HMODULE dl_handle, LPCSTR libraryNameOr if (NULL == module->hinstance) { PREGISTER_MODULE registerModule = (PREGISTER_MODULE)dlsym(module->dl_handle, "PAL_RegisterModule"); - if (registerModule) + if (registerModule != nullptr) { module->hinstance = registerModule(libraryNameOrPath); } @@ -1615,7 +1642,7 @@ Return value : static HMODULE LOADLoadLibrary(LPCSTR shortAsciiName, BOOL fDynamic) { HMODULE module = NULL; - HMODULE dl_handle = NULL; + void *dl_handle = NULL; // Check whether we have been requested to load 'libc'. If that's the case then use the // full name of the library that is defined in <gnu/lib-names.h> by the LIBC_SO constant. @@ -1635,25 +1662,14 @@ static HMODULE LOADLoadLibrary(LPCSTR shortAsciiName, BOOL fDynamic) LockModuleList(); - // See if file can be dlopen()ed; this should work even if it's already loaded - { - // See GetProcAddress for an explanation why we leave the PAL. - PAL_LeaveHolder holder; - - dl_handle = LOADLoadLibraryDirect(shortAsciiName, false /* setLastError */); - } - - if (!dl_handle) + dl_handle = LOADLoadLibraryDirect(shortAsciiName); + if (dl_handle) { - WARN("dlopen() failed; dlerror says '%s'\n", dlerror()); - SetLastError(ERROR_MOD_NOT_FOUND); - goto done; + module = LOADRegisterLibraryDirect(dl_handle, shortAsciiName, fDynamic); } - module = LOADRegisterLibraryDirect(dl_handle, shortAsciiName, fDynamic); - -done: UnlockModuleList(); + return module; } @@ -1886,7 +1902,7 @@ MODSTRUCT *LOADGetPalLibrary() { if (pal_module == NULL) { - // Initialize the pal module (the module containing LOADPalLibrary). Assumes that + // Initialize the pal module (the module containing LOADGetPalLibrary). Assumes that // the PAL is linked into the coreclr module because we use the module name containing // this function for the coreclr path. TRACE("Loading module for PAL library\n"); |