diff options
Diffstat (limited to 'source/Plugins/Process/Windows')
9 files changed, 118 insertions, 35 deletions
diff --git a/source/Plugins/Process/Windows/Common/DebuggerThread.cpp b/source/Plugins/Process/Windows/Common/DebuggerThread.cpp index ad43551a4c6db..81ec25871c577 100644 --- a/source/Plugins/Process/Windows/Common/DebuggerThread.cpp +++ b/source/Plugins/Process/Windows/Common/DebuggerThread.cpp @@ -12,7 +12,6 @@ #include "IDebugDelegate.h" #include "lldb/Core/ModuleSpec.h" -#include "lldb/Host/Predicate.h" #include "lldb/Host/ThreadLauncher.h" #include "lldb/Host/windows/HostProcessWindows.h" #include "lldb/Host/windows/HostThreadWindows.h" @@ -21,6 +20,7 @@ #include "lldb/Target/ProcessLaunchInfo.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Predicate.h" #include "lldb/Utility/Status.h" #include "Plugins/Process/Windows/Common/ProcessWindowsLog.h" @@ -50,7 +50,7 @@ struct DebugAttachContext { lldb::pid_t m_pid; ProcessAttachInfo m_attach_info; }; -} +} // namespace DebuggerThread::DebuggerThread(DebugDelegateSP debug_delegate) : m_debug_delegate(debug_delegate), m_pid_to_detach(0), @@ -191,7 +191,8 @@ Status DebuggerThread::StopDebugging(bool terminate) { handle, pid, terminate_suceeded); } else { LLDB_LOG(log, - "NOT calling TerminateProcess because the inferior is not valid ({0}, 0) (inferior={1})", + "NOT calling TerminateProcess because the inferior is not valid " + "({0}, 0) (inferior={1})", handle, pid); } } @@ -267,6 +268,8 @@ void DebuggerThread::DebugLoop() { if (wait_result) { DWORD continue_status = DBG_CONTINUE; switch (dbe.dwDebugEventCode) { + default: + llvm_unreachable("Unhandle debug event code!"); case EXCEPTION_DEBUG_EVENT: { ExceptionResult status = HandleExceptionEvent(dbe.u.Exception, dbe.dwThreadId); @@ -330,7 +333,7 @@ void DebuggerThread::DebugLoop() { FreeProcessHandles(); LLDB_LOG(log, "WaitForDebugEvent loop completed, exiting."); - SetEvent(m_debugging_ended_event); + ::SetEvent(m_debugging_ended_event); } ExceptionResult @@ -381,7 +384,7 @@ DebuggerThread::HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info, DWORD thread_id) { Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT | WINDOWS_LOG_THREAD); - LLDB_LOG(log, "Thread {0:x} spawned in process {1}", thread_id, + LLDB_LOG(log, "Thread {0} spawned in process {1}", thread_id, m_process.GetProcessId()); HostThread thread(info.hThread); thread.GetNativeThread().SetOwnsHandle(false); @@ -439,7 +442,6 @@ DebuggerThread::HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info, m_debug_delegate->OnExitProcess(info.dwExitCode); - FreeProcessHandles(); return DBG_CONTINUE; } @@ -468,7 +470,7 @@ DebuggerThread::HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info, if (path_str.startswith("\\\\?\\")) path += 4; - FileSpec file_spec(path, false); + FileSpec file_spec(path); ModuleSpec module_spec(file_spec); lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll); diff --git a/source/Plugins/Process/Windows/Common/DebuggerThread.h b/source/Plugins/Process/Windows/Common/DebuggerThread.h index fcf36f7dec9bb..047d3ccb7296b 100644 --- a/source/Plugins/Process/Windows/Common/DebuggerThread.h +++ b/source/Plugins/Process/Windows/Common/DebuggerThread.h @@ -16,8 +16,8 @@ #include "ForwardDecl.h" #include "lldb/Host/HostProcess.h" #include "lldb/Host/HostThread.h" -#include "lldb/Host/Predicate.h" #include "lldb/Host/windows/windows.h" +#include "lldb/Utility/Predicate.h" namespace lldb_private { diff --git a/source/Plugins/Process/Windows/Common/ForwardDecl.h b/source/Plugins/Process/Windows/Common/ForwardDecl.h index cfe1b79cee114..ce2af3ca4111a 100644 --- a/source/Plugins/Process/Windows/Common/ForwardDecl.h +++ b/source/Plugins/Process/Windows/Common/ForwardDecl.h @@ -39,4 +39,4 @@ typedef std::shared_ptr<ExceptionRecord> ExceptionRecordSP; typedef std::unique_ptr<ExceptionRecord> ExceptionRecordUP; } -#endif
\ No newline at end of file +#endif diff --git a/source/Plugins/Process/Windows/Common/ProcessWindows.cpp b/source/Plugins/Process/Windows/Common/ProcessWindows.cpp index b14081f76617d..3fe5ab7804cba 100644 --- a/source/Plugins/Process/Windows/Common/ProcessWindows.cpp +++ b/source/Plugins/Process/Windows/Common/ProcessWindows.cpp @@ -13,12 +13,11 @@ #include "lldb/Host/windows/windows.h" #include <psapi.h> -// Other libraries and framework includes #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" -#include "lldb/Core/State.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/HostNativeProcessBase.h" #include "lldb/Host/HostProcess.h" #include "lldb/Host/windows/HostThreadWindows.h" @@ -28,6 +27,7 @@ #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/State.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/Format.h" @@ -72,6 +72,20 @@ std::string GetProcessExecutableName(DWORD pid) { return file_name; } +DWORD ConvertLldbToWinApiProtect(uint32_t protect) { + // We also can process a read / write permissions here, but if the debugger + // will make later a write into the allocated memory, it will fail. To get + // around it is possible inside DoWriteMemory to remember memory permissions, + // allow write, write and restore permissions, but for now we process only + // the executable permission. + // + // TODO: Process permissions other than executable + if (protect & ePermissionsExecutable) + return PAGE_EXECUTE_READWRITE; + + return PAGE_READWRITE; +} + } // anonymous namespace namespace lldb_private { @@ -237,11 +251,13 @@ Status ProcessWindows::DoLaunch(Module *exe_module, FileSpec working_dir = launch_info.GetWorkingDirectory(); namespace fs = llvm::sys::fs; - if (working_dir && (!working_dir.ResolvePath() || - !fs::is_directory(working_dir.GetPath()))) { - result.SetErrorStringWithFormat("No such file or directory: %s", - working_dir.GetCString()); - return result; + if (working_dir) { + FileSystem::Instance().Resolve(working_dir); + if (!FileSystem::Instance().IsDirectory(working_dir)) { + result.SetErrorStringWithFormat("No such file or directory: %s", + working_dir.GetCString()); + return result; + } } if (!launch_info.GetFlags().Test(eLaunchFlagDebug)) { @@ -379,7 +395,7 @@ Status ProcessWindows::DoResume() { SetPrivateState(eStateRunning); } } else { - LLDB_LOG(log, "error: process %I64u is in state %u. Returning...", + LLDB_LOG(log, "error: process {0} is in state {1}. Returning...", m_session_data->m_debugger->GetProcess().GetProcessId(), GetPrivateState()); } @@ -577,7 +593,7 @@ bool ProcessWindows::CanDebug(lldb::TargetSP target_sp, // For now we are just making sure the file exists for a given module ModuleSP exe_module_sp(target_sp->GetExecutableModule()); if (exe_module_sp.get()) - return exe_module_sp->GetFileSpec().Exists(); + return FileSystem::Instance().Exists(exe_module_sp->GetFileSpec()); // However, if there is no executable module, we return true since we might // be preparing to attach. return true; @@ -695,6 +711,58 @@ size_t ProcessWindows::DoWriteMemory(lldb::addr_t vm_addr, const void *buf, return bytes_written; } +lldb::addr_t ProcessWindows::DoAllocateMemory(size_t size, uint32_t permissions, + Status &error) { + Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY); + llvm::sys::ScopedLock lock(m_mutex); + LLDB_LOG(log, "attempting to allocate {0} bytes with permissions {1}", size, + permissions); + + if (!m_session_data) { + LLDB_LOG(log, "cannot allocate, there is no active debugger connection."); + error.SetErrorString( + "cannot allocate, there is no active debugger connection"); + return LLDB_INVALID_ADDRESS; + } + + HostProcess process = m_session_data->m_debugger->GetProcess(); + lldb::process_t handle = process.GetNativeProcess().GetSystemHandle(); + auto protect = ConvertLldbToWinApiProtect(permissions); + auto result = VirtualAllocEx(handle, nullptr, size, MEM_COMMIT, protect); + if (!result) { + error.SetError(GetLastError(), eErrorTypeWin32); + LLDB_LOG(log, "allocating failed with error: {0}", error); + return LLDB_INVALID_ADDRESS; + } + + return reinterpret_cast<addr_t>(result); +} + +Status ProcessWindows::DoDeallocateMemory(lldb::addr_t ptr) { + Status result; + + Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY); + llvm::sys::ScopedLock lock(m_mutex); + LLDB_LOG(log, "attempting to deallocate bytes at address {0}", ptr); + + if (!m_session_data) { + LLDB_LOG(log, "cannot deallocate, there is no active debugger connection."); + result.SetErrorString( + "cannot deallocate, there is no active debugger connection"); + return result; + } + + HostProcess process = m_session_data->m_debugger->GetProcess(); + lldb::process_t handle = process.GetNativeProcess().GetSystemHandle(); + if (!VirtualFreeEx(handle, reinterpret_cast<LPVOID>(ptr), 0, MEM_RELEASE)) { + result.SetError(GetLastError(), eErrorTypeWin32); + LLDB_LOG(log, "deallocating failed with error: {0}", result); + return result; + } + + return result; +} + Status ProcessWindows::GetMemoryRegionInfo(lldb::addr_t vm_addr, MemoryRegionInfo &info) { Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY); @@ -812,6 +880,14 @@ void ProcessWindows::OnExitProcess(uint32_t exit_code) { SetProcessExitStatus(GetID(), true, 0, exit_code); SetPrivateState(eStateExited); + + // If the process exits before any initial stop then notify the debugger + // of the error otherwise WaitForDebuggerConnection() will be blocked. + // An example of this issue is when a process fails to load a dependent DLL. + if (m_session_data && !m_session_data->m_initial_stop_received) { + Status error(exit_code, eErrorTypeWin32); + OnDebuggerError(error, 0); + } } void ProcessWindows::OnDebuggerConnected(lldb::addr_t image_base) { @@ -829,7 +905,8 @@ void ProcessWindows::OnDebuggerConnected(lldb::addr_t image_base) { return; } - FileSpec executable_file(file_name, true); + FileSpec executable_file(file_name); + FileSystem::Instance().Resolve(executable_file); ModuleSpec module_spec(executable_file); Status error; module = GetTarget().GetSharedModule(module_spec, &error); @@ -837,7 +914,7 @@ void ProcessWindows::OnDebuggerConnected(lldb::addr_t image_base) { return; } - GetTarget().SetExecutableModule(module, false); + GetTarget().SetExecutableModule(module, eLoadDependentsNo); } bool load_addr_changed; @@ -880,8 +957,9 @@ ProcessWindows::OnDebugException(bool first_chance, } if (!first_chance) { - // Any second chance exception is an application crash by definition. - SetPrivateState(eStateCrashed); + // Not any second chance exception is an application crash by definition. + // It may be an expression evaluation crash. + SetPrivateState(eStateStopped); } ExceptionResult result = ExceptionResult::SendToApplication; diff --git a/source/Plugins/Process/Windows/Common/ProcessWindows.h b/source/Plugins/Process/Windows/Common/ProcessWindows.h index ed3938beb347c..00e384f584080 100644 --- a/source/Plugins/Process/Windows/Common/ProcessWindows.h +++ b/source/Plugins/Process/Windows/Common/ProcessWindows.h @@ -10,7 +10,6 @@ #ifndef liblldb_Plugins_Process_Windows_Common_ProcessWindows_H_ #define liblldb_Plugins_Process_Windows_Common_ProcessWindows_H_ -// Other libraries and framework includes #include "lldb/Target/Process.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-forward.h" @@ -84,6 +83,9 @@ public: Status &error) override; size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, Status &error) override; + lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions, + Status &error) override; + Status DoDeallocateMemory(lldb::addr_t ptr) override; Status GetMemoryRegionInfo(lldb::addr_t vm_addr, MemoryRegionInfo &info) override; diff --git a/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp b/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp index b3f507128f824..90d43b2cf8284 100644 --- a/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp +++ b/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp @@ -40,12 +40,13 @@ void RegisterContextWindows::InvalidateAllRegisters() { bool RegisterContextWindows::ReadAllRegisterValues( lldb::DataBufferSP &data_sp) { + if (!CacheAllRegisterValues()) return false; - if (data_sp->GetByteSize() < sizeof(m_context)) { - data_sp.reset(new DataBufferHeap(sizeof(CONTEXT), 0)); - } + + data_sp.reset(new DataBufferHeap(sizeof(CONTEXT), 0)); memcpy(data_sp->GetBytes(), &m_context, sizeof(m_context)); + return true; } diff --git a/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp b/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp index 3903280918cc8..b121dc7bf15ea 100644 --- a/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp +++ b/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/State.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/HostNativeThreadBase.h" #include "lldb/Host/windows/HostThreadWindows.h" @@ -15,6 +14,7 @@ #include "lldb/Target/RegisterContext.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Logging.h" +#include "lldb/Utility/State.h" #include "Plugins/Process/Utility/UnwindLLDB.h" #include "ProcessWindows.h" diff --git a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp b/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp index 4aa6c785f83c4..584136a6e5bb4 100644 --- a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp +++ b/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp @@ -7,9 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/RegisterValue.h" #include "lldb/Host/windows/HostThreadWindows.h" #include "lldb/Host/windows/windows.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-private-types.h" @@ -74,12 +74,12 @@ RegisterInfo g_register_infos[] = { nullptr, nullptr}, {DEFINE_GPR(rcx, nullptr), - {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_INVALID_REGNUM, + {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, lldb_rcx_x86_64}, nullptr, nullptr}, {DEFINE_GPR(rdx, nullptr), - {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_INVALID_REGNUM, + {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, lldb_rdx_x86_64}, nullptr, nullptr}, @@ -104,22 +104,22 @@ RegisterInfo g_register_infos[] = { nullptr, nullptr}, {DEFINE_GPR(r8, nullptr), - {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_INVALID_REGNUM, + {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, lldb_r8_x86_64}, nullptr, nullptr}, {DEFINE_GPR(r9, nullptr), - {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_INVALID_REGNUM, + {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, lldb_r9_x86_64}, nullptr, nullptr}, {DEFINE_GPR(r10, nullptr), - {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, + {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM, lldb_r10_x86_64}, nullptr, nullptr}, {DEFINE_GPR(r11, nullptr), - {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, + {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM, lldb_r11_x86_64}, nullptr, nullptr}, diff --git a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp b/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp index fd486f3d08298..e012f9105f31a 100644 --- a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp +++ b/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp @@ -7,9 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/RegisterValue.h" #include "lldb/Host/windows/HostThreadWindows.h" #include "lldb/Host/windows/windows.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-private-types.h" |