This revision was automatically updated to reflect the committed changes. Closed by commit rG87a2dba14ec8: [lldb] Fix loading DLL from some ramdisk on Windows (authored by alvinhochun, committed by mstorsjo). Herald added a subscriber: Michael137.
Changed prior to commit: https://reviews.llvm.org/D126657?vs=432931&id=437144#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D126657/new/ https://reviews.llvm.org/D126657 Files: lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
Index: lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp =================================================================== --- lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp +++ lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp @@ -13,6 +13,7 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Host/ProcessLaunchInfo.h" #include "lldb/Host/ThreadLauncher.h" +#include "lldb/Host/windows/AutoHandle.h" #include "lldb/Host/windows/HostProcessWindows.h" #include "lldb/Host/windows/HostThreadWindows.h" #include "lldb/Host/windows/ProcessLauncherWindows.h" @@ -29,6 +30,8 @@ #include "llvm/Support/Threading.h" #include "llvm/Support/raw_ostream.h" +#include <psapi.h> + #ifndef STATUS_WX86_BREAKPOINT #define STATUS_WX86_BREAKPOINT 0x4000001FL // For WOW64 #endif @@ -409,6 +412,61 @@ return DBG_CONTINUE; } +static llvm::Optional<std::string> GetFileNameFromHandleFallback(HANDLE hFile) { + // Check that file is not empty as we cannot map a file with zero length. + DWORD dwFileSizeHi = 0; + DWORD dwFileSizeLo = ::GetFileSize(hFile, &dwFileSizeHi); + if (dwFileSizeLo == 0 && dwFileSizeHi == 0) + return llvm::None; + + AutoHandle filemap( + ::CreateFileMappingW(hFile, nullptr, PAGE_READONLY, 0, 1, NULL), nullptr); + if (!filemap.IsValid()) + return llvm::None; + + auto view_deleter = [](void *pMem) { ::UnmapViewOfFile(pMem); }; + std::unique_ptr<void, decltype(view_deleter)> pMem( + ::MapViewOfFile(filemap.get(), FILE_MAP_READ, 0, 0, 1), view_deleter); + if (!pMem) + return llvm::None; + + std::array<wchar_t, MAX_PATH + 1> mapped_filename; + if (!::GetMappedFileNameW(::GetCurrentProcess(), pMem.get(), + mapped_filename.data(), mapped_filename.size())) + return llvm::None; + + // A series of null-terminated strings, plus an additional null character + std::array<wchar_t, 512> drive_strings; + drive_strings[0] = L'\0'; + if (!::GetLogicalDriveStringsW(drive_strings.size(), drive_strings.data())) + return llvm::None; + + std::array<wchar_t, 3> drive = {L"_:"}; + for (const wchar_t *it = drive_strings.data(); *it != L'\0'; + it += wcslen(it) + 1) { + // Copy the drive letter to the template string + drive[0] = it[0]; + std::array<wchar_t, MAX_PATH> device_name; + if (::QueryDosDeviceW(drive.data(), device_name.data(), + device_name.size())) { + size_t device_name_len = wcslen(device_name.data()); + if (device_name_len < mapped_filename.size()) { + bool match = _wcsnicmp(mapped_filename.data(), device_name.data(), + device_name_len) == 0; + if (match && mapped_filename[device_name_len] == L'\\') { + // Replace device path with its drive letter + std::wstring rebuilt_path(drive.data()); + rebuilt_path.append(&mapped_filename[device_name_len]); + std::string path_utf8; + llvm::convertWideToUTF8(rebuilt_path, path_utf8); + return path_utf8; + } + } + } + } + return llvm::None; +} + DWORD DebuggerThread::HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info, DWORD thread_id) { @@ -420,6 +478,17 @@ return DBG_CONTINUE; } + auto on_load_dll = [&](llvm::StringRef path) { + FileSpec file_spec(path); + ModuleSpec module_spec(file_spec); + lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll); + + LLDB_LOG(log, "Inferior {0} - DLL '{1}' loaded at address {2:x}...", + m_process.GetProcessId(), path, info.lpBaseOfDll); + + m_debug_delegate->OnLoadDll(module_spec, load_addr); + }; + std::vector<wchar_t> buffer(1); DWORD required_size = GetFinalPathNameByHandleW(info.hFile, &buffer[0], 0, VOLUME_NAME_DOS); @@ -434,14 +503,10 @@ if (path_str.startswith("\\\\?\\")) path += 4; - FileSpec file_spec(path); - ModuleSpec module_spec(file_spec); - lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll); - - LLDB_LOG(log, "Inferior {0} - DLL '{1}' loaded at address {2:x}...", - m_process.GetProcessId(), path, info.lpBaseOfDll); - - m_debug_delegate->OnLoadDll(module_spec, load_addr); + on_load_dll(path); + } else if (llvm::Optional<std::string> path = + GetFileNameFromHandleFallback(info.hFile)) { + on_load_dll(*path); } else { LLDB_LOG( log,
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits