From: noahfalk Date: Tue, 5 Feb 2019 08:17:42 +0000 (-0800) Subject: Fix dotnet/coreclr#20205 X-Git-Tag: submit/tizen/20190813.035844~58^2~2^2~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=74f3e849066fd133afb4b978c7c2c9545c603fed;p=platform%2Fcore%2Fdotnet%2Fdiagnostics.git Fix dotnet/coreclr#20205 1) Create a symlink to the DAC in a temp directory where libcoreclrtraceptprovider.so doesn't exist so it doesn't get loaded by the DAC causing a LTTng-UST exception. To workaround issue #dotnet/coreclr#20205. 2) Add temporary file clean up on SOS exit for both the above symlink and the native symbol downloader code. (work originally by mikem, I just split his mega-commit so history would a little more understandable) --- diff --git a/src/SOS/Strike/exts.cpp b/src/SOS/Strike/exts.cpp index 4f5d97dc3..b14be2e6b 100644 --- a/src/SOS/Strike/exts.cpp +++ b/src/SOS/Strike/exts.cpp @@ -14,6 +14,8 @@ #define VER_PRODUCTVERSION_W (0x0100) +extern void SOSShutdown(); + // // globals // @@ -256,6 +258,7 @@ DebugExtensionInitialize(PULONG Version, PULONG Flags) ExtRelease(); OnUnloadTask::Register(CleanupEventCallbacks); + OnUnloadTask::Register(SOSShutdown); g_pCallbacksClient = DebugClient; EventCallbacks* pCallbacksObj = new EventCallbacks(DebugClient); IDebugEventCallbacks* pCallbacks = NULL; diff --git a/src/SOS/Strike/hostcoreclr.cpp b/src/SOS/Strike/hostcoreclr.cpp index 306411554..7c8e06e03 100644 --- a/src/SOS/Strike/hostcoreclr.cpp +++ b/src/SOS/Strike/hostcoreclr.cpp @@ -282,6 +282,71 @@ HRESULT GetHostRuntime(std::string& coreClrPath, std::string& hostRuntimeDirecto return S_OK; } +// +// Returns the unique temporary directory for this instnace of SOS +// +static LPCSTR GetTempDirectory() +{ + if (g_tmpPath == nullptr) + { + char tmpPath[MAX_LONGPATH]; + if (::GetTempPathA(MAX_LONGPATH, tmpPath) == 0) + { + strcpy_s(tmpPath, MAX_LONGPATH, "."); + strcat_s(tmpPath, MAX_LONGPATH, DIRECTORY_SEPARATOR_STR_A); + } + char pidstr[128]; + sprintf_s(pidstr, _countof(pidstr), "%d", GetCurrentProcessId()); + strcat_s(tmpPath, MAX_LONGPATH, pidstr); + strcat_s(tmpPath, MAX_LONGPATH, DIRECTORY_SEPARATOR_STR_A); + + CreateDirectoryA(tmpPath, NULL); + g_tmpPath = _strdup(tmpPath); + } + return g_tmpPath; +} + +/**********************************************************************\ + * Clean up the temporary directory files and DAC symlink. +\**********************************************************************/ +#ifdef FEATURE_PAL +__attribute__((destructor)) +#endif +void SOSShutdown() +{ + LPCSTR tmpPath = (LPCSTR)InterlockedExchangePointer((PVOID *)&g_tmpPath, nullptr); + if (tmpPath != nullptr) + { + std::string directory(tmpPath); + directory.append("*"); + + WIN32_FIND_DATAA data; + HANDLE findHandle = FindFirstFileA(directory.c_str(), &data); + + if (findHandle != INVALID_HANDLE_VALUE) + { + do + { + if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) + { + std::string file(tmpPath); + file.append(data.cFileName); + DeleteFileA(file.c_str()); + } + } + while (0 != FindNextFileA(findHandle, &data)); + + FindClose(findHandle); + } + + RemoveDirectoryA(tmpPath); + free((void*)tmpPath); + } +} + +/**********************************************************************\ + * Returns the DAC module path to the rest of SOS. +\**********************************************************************/ LPCSTR GetDacFilePath() { // If the DAC path hasn't been set by the symbol download support, use the one in the runtime directory. @@ -296,8 +361,33 @@ LPCSTR GetDacFilePath() #ifdef FEATURE_PAL // if DAC file exists if (access(dacModulePath.c_str(), F_OK) == 0) +#endif + { +#if defined(__linux__) + // We are creating a symlink to the DAC in a temp directory + // where libcoreclrtraceptprovider.so doesn't exist so it + // doesn't get loaded by the DAC causing a LTTng-UST exception. + // + // Issue #https://github.com/dotnet/coreclr/issues/20205 + LPCSTR tmpPath = GetTempDirectory(); + if (tmpPath != nullptr) + { + std::string dacSymLink(tmpPath); + dacSymLink.append(MAKEDLLNAME_A("mscordaccore")); + + int error = symlink(dacModulePath.c_str(), dacSymLink.c_str()); + if (error == 0) + { + dacModulePath.assign(dacSymLink); + } + else + { + ExtErr("symlink(%s, %s) FAILED %s\n", dacModulePath.c_str(), dacSymLink.c_str(), strerror(errno)); + } + } #endif g_dacFilePath = _strdup(dacModulePath.c_str()); + } } } return g_dacFilePath;