1*5146a9eaSAaron Smith //===-- NativeProcessWindows.cpp --------------------------------*- C++ -*-===// 2*5146a9eaSAaron Smith // 3*5146a9eaSAaron Smith // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*5146a9eaSAaron Smith // See https://llvm.org/LICENSE.txt for license information. 5*5146a9eaSAaron Smith // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*5146a9eaSAaron Smith // 7*5146a9eaSAaron Smith //===----------------------------------------------------------------------===// 8*5146a9eaSAaron Smith 9*5146a9eaSAaron Smith #include "lldb/Host/windows/windows.h" 10*5146a9eaSAaron Smith #include <psapi.h> 11*5146a9eaSAaron Smith 12*5146a9eaSAaron Smith #include "NativeProcessWindows.h" 13*5146a9eaSAaron Smith #include "NativeThreadWindows.h" 14*5146a9eaSAaron Smith #include "lldb/Host/FileSystem.h" 15*5146a9eaSAaron Smith #include "lldb/Host/HostNativeProcessBase.h" 16*5146a9eaSAaron Smith #include "lldb/Host/HostProcess.h" 17*5146a9eaSAaron Smith #include "lldb/Host/ProcessLaunchInfo.h" 18*5146a9eaSAaron Smith #include "lldb/Host/windows/AutoHandle.h" 19*5146a9eaSAaron Smith #include "lldb/Host/windows/HostThreadWindows.h" 20*5146a9eaSAaron Smith #include "lldb/Host/windows/ProcessLauncherWindows.h" 21*5146a9eaSAaron Smith #include "lldb/Target/MemoryRegionInfo.h" 22*5146a9eaSAaron Smith #include "lldb/Target/Process.h" 23*5146a9eaSAaron Smith #include "lldb/Utility/State.h" 24*5146a9eaSAaron Smith #include "llvm/Support/ConvertUTF.h" 25*5146a9eaSAaron Smith #include "llvm/Support/Errc.h" 26*5146a9eaSAaron Smith #include "llvm/Support/Error.h" 27*5146a9eaSAaron Smith #include "llvm/Support/Format.h" 28*5146a9eaSAaron Smith #include "llvm/Support/Threading.h" 29*5146a9eaSAaron Smith #include "llvm/Support/raw_ostream.h" 30*5146a9eaSAaron Smith 31*5146a9eaSAaron Smith #include "DebuggerThread.h" 32*5146a9eaSAaron Smith #include "ExceptionRecord.h" 33*5146a9eaSAaron Smith #include "ProcessWindowsLog.h" 34*5146a9eaSAaron Smith 35*5146a9eaSAaron Smith #include <tlhelp32.h> 36*5146a9eaSAaron Smith 37*5146a9eaSAaron Smith #pragma warning(disable : 4005) 38*5146a9eaSAaron Smith #include "winternl.h" 39*5146a9eaSAaron Smith #include <ntstatus.h> 40*5146a9eaSAaron Smith 41*5146a9eaSAaron Smith using namespace lldb; 42*5146a9eaSAaron Smith using namespace lldb_private; 43*5146a9eaSAaron Smith using namespace llvm; 44*5146a9eaSAaron Smith 45*5146a9eaSAaron Smith namespace lldb_private { 46*5146a9eaSAaron Smith 47*5146a9eaSAaron Smith NativeProcessWindows::NativeProcessWindows(ProcessLaunchInfo &launch_info, 48*5146a9eaSAaron Smith NativeDelegate &delegate, 49*5146a9eaSAaron Smith llvm::Error &E) 50*5146a9eaSAaron Smith : NativeProcessProtocol(LLDB_INVALID_PROCESS_ID, 51*5146a9eaSAaron Smith launch_info.GetPTY().ReleaseMasterFileDescriptor(), 52*5146a9eaSAaron Smith delegate), 53*5146a9eaSAaron Smith ProcessDebugger(), m_arch(launch_info.GetArchitecture()) { 54*5146a9eaSAaron Smith ErrorAsOutParameter EOut(&E); 55*5146a9eaSAaron Smith DebugDelegateSP delegate_sp(new NativeDebugDelegate(*this)); 56*5146a9eaSAaron Smith E = LaunchProcess(launch_info, delegate_sp).ToError(); 57*5146a9eaSAaron Smith if (E) 58*5146a9eaSAaron Smith return; 59*5146a9eaSAaron Smith 60*5146a9eaSAaron Smith SetID(GetDebuggedProcessId()); 61*5146a9eaSAaron Smith } 62*5146a9eaSAaron Smith 63*5146a9eaSAaron Smith NativeProcessWindows::NativeProcessWindows(lldb::pid_t pid, int terminal_fd, 64*5146a9eaSAaron Smith NativeDelegate &delegate, 65*5146a9eaSAaron Smith llvm::Error &E) 66*5146a9eaSAaron Smith : NativeProcessProtocol(pid, terminal_fd, delegate), ProcessDebugger() { 67*5146a9eaSAaron Smith ErrorAsOutParameter EOut(&E); 68*5146a9eaSAaron Smith DebugDelegateSP delegate_sp(new NativeDebugDelegate(*this)); 69*5146a9eaSAaron Smith ProcessAttachInfo attach_info; 70*5146a9eaSAaron Smith attach_info.SetProcessID(pid); 71*5146a9eaSAaron Smith E = AttachProcess(pid, attach_info, delegate_sp).ToError(); 72*5146a9eaSAaron Smith if (E) 73*5146a9eaSAaron Smith return; 74*5146a9eaSAaron Smith 75*5146a9eaSAaron Smith SetID(GetDebuggedProcessId()); 76*5146a9eaSAaron Smith 77*5146a9eaSAaron Smith ProcessInstanceInfo info; 78*5146a9eaSAaron Smith if (!Host::GetProcessInfo(pid, info)) { 79*5146a9eaSAaron Smith E = createStringError(inconvertibleErrorCode(), 80*5146a9eaSAaron Smith "Cannot get process information"); 81*5146a9eaSAaron Smith return; 82*5146a9eaSAaron Smith } 83*5146a9eaSAaron Smith m_arch = info.GetArchitecture(); 84*5146a9eaSAaron Smith } 85*5146a9eaSAaron Smith 86*5146a9eaSAaron Smith Status NativeProcessWindows::Resume(const ResumeActionList &resume_actions) { 87*5146a9eaSAaron Smith Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS); 88*5146a9eaSAaron Smith Status error; 89*5146a9eaSAaron Smith llvm::sys::ScopedLock lock(m_mutex); 90*5146a9eaSAaron Smith 91*5146a9eaSAaron Smith StateType state = GetState(); 92*5146a9eaSAaron Smith if (state == eStateStopped || state == eStateCrashed) { 93*5146a9eaSAaron Smith LLDB_LOG(log, "process {0} is in state {1}. Resuming...", 94*5146a9eaSAaron Smith GetDebuggedProcessId(), state); 95*5146a9eaSAaron Smith LLDB_LOG(log, "resuming {0} threads.", m_threads.size()); 96*5146a9eaSAaron Smith 97*5146a9eaSAaron Smith bool failed = false; 98*5146a9eaSAaron Smith for (uint32_t i = 0; i < m_threads.size(); ++i) { 99*5146a9eaSAaron Smith auto thread = static_cast<NativeThreadWindows *>(m_threads[i].get()); 100*5146a9eaSAaron Smith const ResumeAction *const action = 101*5146a9eaSAaron Smith resume_actions.GetActionForThread(thread->GetID(), true); 102*5146a9eaSAaron Smith if (action == nullptr) 103*5146a9eaSAaron Smith continue; 104*5146a9eaSAaron Smith 105*5146a9eaSAaron Smith switch (action->state) { 106*5146a9eaSAaron Smith case eStateRunning: 107*5146a9eaSAaron Smith case eStateStepping: { 108*5146a9eaSAaron Smith Status result = thread->DoResume(action->state); 109*5146a9eaSAaron Smith if (result.Fail()) { 110*5146a9eaSAaron Smith failed = true; 111*5146a9eaSAaron Smith LLDB_LOG(log, 112*5146a9eaSAaron Smith "Trying to resume thread at index {0}, but failed with " 113*5146a9eaSAaron Smith "error {1}.", 114*5146a9eaSAaron Smith i, result); 115*5146a9eaSAaron Smith } 116*5146a9eaSAaron Smith break; 117*5146a9eaSAaron Smith } 118*5146a9eaSAaron Smith case eStateSuspended: 119*5146a9eaSAaron Smith case eStateStopped: 120*5146a9eaSAaron Smith llvm_unreachable("Unexpected state"); 121*5146a9eaSAaron Smith 122*5146a9eaSAaron Smith default: 123*5146a9eaSAaron Smith return Status( 124*5146a9eaSAaron Smith "NativeProcessWindows::%s (): unexpected state %s specified " 125*5146a9eaSAaron Smith "for pid %" PRIu64 ", tid %" PRIu64, 126*5146a9eaSAaron Smith __FUNCTION__, StateAsCString(action->state), GetID(), 127*5146a9eaSAaron Smith thread->GetID()); 128*5146a9eaSAaron Smith } 129*5146a9eaSAaron Smith } 130*5146a9eaSAaron Smith 131*5146a9eaSAaron Smith if (failed) { 132*5146a9eaSAaron Smith error.SetErrorString("NativeProcessWindows::DoResume failed"); 133*5146a9eaSAaron Smith } else { 134*5146a9eaSAaron Smith SetState(eStateRunning); 135*5146a9eaSAaron Smith } 136*5146a9eaSAaron Smith 137*5146a9eaSAaron Smith // Resume the debug loop. 138*5146a9eaSAaron Smith ExceptionRecordSP active_exception = 139*5146a9eaSAaron Smith m_session_data->m_debugger->GetActiveException().lock(); 140*5146a9eaSAaron Smith if (active_exception) { 141*5146a9eaSAaron Smith // Resume the process and continue processing debug events. Mask the 142*5146a9eaSAaron Smith // exception so that from the process's view, there is no indication that 143*5146a9eaSAaron Smith // anything happened. 144*5146a9eaSAaron Smith m_session_data->m_debugger->ContinueAsyncException( 145*5146a9eaSAaron Smith ExceptionResult::MaskException); 146*5146a9eaSAaron Smith } 147*5146a9eaSAaron Smith } else { 148*5146a9eaSAaron Smith LLDB_LOG(log, "error: process {0} is in state {1}. Returning...", 149*5146a9eaSAaron Smith GetDebuggedProcessId(), GetState()); 150*5146a9eaSAaron Smith } 151*5146a9eaSAaron Smith 152*5146a9eaSAaron Smith return error; 153*5146a9eaSAaron Smith } 154*5146a9eaSAaron Smith 155*5146a9eaSAaron Smith NativeThreadWindows * 156*5146a9eaSAaron Smith NativeProcessWindows::GetThreadByID(lldb::tid_t thread_id) { 157*5146a9eaSAaron Smith return static_cast<NativeThreadWindows *>( 158*5146a9eaSAaron Smith NativeProcessProtocol::GetThreadByID(thread_id)); 159*5146a9eaSAaron Smith } 160*5146a9eaSAaron Smith 161*5146a9eaSAaron Smith Status NativeProcessWindows::Halt() { 162*5146a9eaSAaron Smith bool caused_stop = false; 163*5146a9eaSAaron Smith StateType state = GetState(); 164*5146a9eaSAaron Smith if (state != eStateStopped) 165*5146a9eaSAaron Smith return HaltProcess(caused_stop); 166*5146a9eaSAaron Smith return Status(); 167*5146a9eaSAaron Smith } 168*5146a9eaSAaron Smith 169*5146a9eaSAaron Smith Status NativeProcessWindows::Detach() { 170*5146a9eaSAaron Smith Status error; 171*5146a9eaSAaron Smith Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS); 172*5146a9eaSAaron Smith StateType state = GetState(); 173*5146a9eaSAaron Smith if (state != eStateExited && state != eStateDetached) { 174*5146a9eaSAaron Smith error = DetachProcess(); 175*5146a9eaSAaron Smith if (error.Success()) 176*5146a9eaSAaron Smith SetState(eStateDetached); 177*5146a9eaSAaron Smith else 178*5146a9eaSAaron Smith LLDB_LOG(log, "Detaching process error: {0}", error); 179*5146a9eaSAaron Smith } else { 180*5146a9eaSAaron Smith error.SetErrorStringWithFormat("error: process {0} in state = {1}, but " 181*5146a9eaSAaron Smith "cannot detach it in this state.", 182*5146a9eaSAaron Smith GetID(), state); 183*5146a9eaSAaron Smith LLDB_LOG(log, "error: {0}", error); 184*5146a9eaSAaron Smith } 185*5146a9eaSAaron Smith return error; 186*5146a9eaSAaron Smith } 187*5146a9eaSAaron Smith 188*5146a9eaSAaron Smith Status NativeProcessWindows::Signal(int signo) { 189*5146a9eaSAaron Smith Status error; 190*5146a9eaSAaron Smith error.SetErrorString("Windows does not support sending signals to processes"); 191*5146a9eaSAaron Smith return error; 192*5146a9eaSAaron Smith } 193*5146a9eaSAaron Smith 194*5146a9eaSAaron Smith Status NativeProcessWindows::Interrupt() { return Halt(); } 195*5146a9eaSAaron Smith 196*5146a9eaSAaron Smith Status NativeProcessWindows::Kill() { 197*5146a9eaSAaron Smith StateType state = GetState(); 198*5146a9eaSAaron Smith return DestroyProcess(state); 199*5146a9eaSAaron Smith } 200*5146a9eaSAaron Smith 201*5146a9eaSAaron Smith Status NativeProcessWindows::IgnoreSignals(llvm::ArrayRef<int> signals) { 202*5146a9eaSAaron Smith return Status(); 203*5146a9eaSAaron Smith } 204*5146a9eaSAaron Smith 205*5146a9eaSAaron Smith Status NativeProcessWindows::GetMemoryRegionInfo(lldb::addr_t load_addr, 206*5146a9eaSAaron Smith MemoryRegionInfo &range_info) { 207*5146a9eaSAaron Smith return ProcessDebugger::GetMemoryRegionInfo(load_addr, range_info); 208*5146a9eaSAaron Smith } 209*5146a9eaSAaron Smith 210*5146a9eaSAaron Smith Status NativeProcessWindows::ReadMemory(lldb::addr_t addr, void *buf, 211*5146a9eaSAaron Smith size_t size, size_t &bytes_read) { 212*5146a9eaSAaron Smith return ProcessDebugger::ReadMemory(addr, buf, size, bytes_read); 213*5146a9eaSAaron Smith } 214*5146a9eaSAaron Smith 215*5146a9eaSAaron Smith Status NativeProcessWindows::WriteMemory(lldb::addr_t addr, const void *buf, 216*5146a9eaSAaron Smith size_t size, size_t &bytes_written) { 217*5146a9eaSAaron Smith return ProcessDebugger::WriteMemory(addr, buf, size, bytes_written); 218*5146a9eaSAaron Smith } 219*5146a9eaSAaron Smith 220*5146a9eaSAaron Smith Status NativeProcessWindows::AllocateMemory(size_t size, uint32_t permissions, 221*5146a9eaSAaron Smith lldb::addr_t &addr) { 222*5146a9eaSAaron Smith return ProcessDebugger::AllocateMemory(size, permissions, addr); 223*5146a9eaSAaron Smith } 224*5146a9eaSAaron Smith 225*5146a9eaSAaron Smith Status NativeProcessWindows::DeallocateMemory(lldb::addr_t addr) { 226*5146a9eaSAaron Smith return ProcessDebugger::DeallocateMemory(addr); 227*5146a9eaSAaron Smith } 228*5146a9eaSAaron Smith 229*5146a9eaSAaron Smith lldb::addr_t NativeProcessWindows::GetSharedLibraryInfoAddress() { return 0; } 230*5146a9eaSAaron Smith 231*5146a9eaSAaron Smith bool NativeProcessWindows::IsAlive() const { 232*5146a9eaSAaron Smith StateType state = GetState(); 233*5146a9eaSAaron Smith switch (state) { 234*5146a9eaSAaron Smith case eStateCrashed: 235*5146a9eaSAaron Smith case eStateDetached: 236*5146a9eaSAaron Smith case eStateExited: 237*5146a9eaSAaron Smith case eStateInvalid: 238*5146a9eaSAaron Smith case eStateUnloaded: 239*5146a9eaSAaron Smith return false; 240*5146a9eaSAaron Smith default: 241*5146a9eaSAaron Smith return true; 242*5146a9eaSAaron Smith } 243*5146a9eaSAaron Smith } 244*5146a9eaSAaron Smith 245*5146a9eaSAaron Smith void NativeProcessWindows::SetStopReasonForThread(NativeThreadWindows &thread, 246*5146a9eaSAaron Smith lldb::StopReason reason, 247*5146a9eaSAaron Smith std::string description) { 248*5146a9eaSAaron Smith SetCurrentThreadID(thread.GetID()); 249*5146a9eaSAaron Smith 250*5146a9eaSAaron Smith ThreadStopInfo stop_info; 251*5146a9eaSAaron Smith stop_info.reason = reason; 252*5146a9eaSAaron Smith 253*5146a9eaSAaron Smith // No signal support on Windows but required to provide a 'valid' signum. 254*5146a9eaSAaron Smith if (reason == StopReason::eStopReasonException) { 255*5146a9eaSAaron Smith stop_info.details.exception.type = 0; 256*5146a9eaSAaron Smith stop_info.details.exception.data_count = 0; 257*5146a9eaSAaron Smith } else { 258*5146a9eaSAaron Smith stop_info.details.signal.signo = SIGTRAP; 259*5146a9eaSAaron Smith } 260*5146a9eaSAaron Smith 261*5146a9eaSAaron Smith thread.SetStopReason(stop_info, description); 262*5146a9eaSAaron Smith } 263*5146a9eaSAaron Smith 264*5146a9eaSAaron Smith void NativeProcessWindows::StopThread(lldb::tid_t thread_id, 265*5146a9eaSAaron Smith lldb::StopReason reason, 266*5146a9eaSAaron Smith std::string description) { 267*5146a9eaSAaron Smith NativeThreadWindows *thread = GetThreadByID(thread_id); 268*5146a9eaSAaron Smith if (!thread) 269*5146a9eaSAaron Smith return; 270*5146a9eaSAaron Smith 271*5146a9eaSAaron Smith for (uint32_t i = 0; i < m_threads.size(); ++i) { 272*5146a9eaSAaron Smith auto t = static_cast<NativeThreadWindows *>(m_threads[i].get()); 273*5146a9eaSAaron Smith Status error = t->DoStop(); 274*5146a9eaSAaron Smith if (error.Fail()) 275*5146a9eaSAaron Smith exit(1); 276*5146a9eaSAaron Smith } 277*5146a9eaSAaron Smith SetStopReasonForThread(*thread, reason, description); 278*5146a9eaSAaron Smith } 279*5146a9eaSAaron Smith 280*5146a9eaSAaron Smith size_t NativeProcessWindows::UpdateThreads() { return m_threads.size(); } 281*5146a9eaSAaron Smith 282*5146a9eaSAaron Smith llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> 283*5146a9eaSAaron Smith NativeProcessWindows::GetAuxvData() const { 284*5146a9eaSAaron Smith // Not available on this target. 285*5146a9eaSAaron Smith return llvm::errc::not_supported; 286*5146a9eaSAaron Smith } 287*5146a9eaSAaron Smith 288*5146a9eaSAaron Smith bool NativeProcessWindows::FindSoftwareBreakpoint(lldb::addr_t addr) { 289*5146a9eaSAaron Smith auto it = m_software_breakpoints.find(addr); 290*5146a9eaSAaron Smith if (it == m_software_breakpoints.end()) 291*5146a9eaSAaron Smith return false; 292*5146a9eaSAaron Smith return true; 293*5146a9eaSAaron Smith } 294*5146a9eaSAaron Smith 295*5146a9eaSAaron Smith Status NativeProcessWindows::SetBreakpoint(lldb::addr_t addr, uint32_t size, 296*5146a9eaSAaron Smith bool hardware) { 297*5146a9eaSAaron Smith if (hardware) 298*5146a9eaSAaron Smith return SetHardwareBreakpoint(addr, size); 299*5146a9eaSAaron Smith return SetSoftwareBreakpoint(addr, size); 300*5146a9eaSAaron Smith } 301*5146a9eaSAaron Smith 302*5146a9eaSAaron Smith Status NativeProcessWindows::RemoveBreakpoint(lldb::addr_t addr, 303*5146a9eaSAaron Smith bool hardware) { 304*5146a9eaSAaron Smith if (hardware) 305*5146a9eaSAaron Smith return RemoveHardwareBreakpoint(addr); 306*5146a9eaSAaron Smith return RemoveSoftwareBreakpoint(addr); 307*5146a9eaSAaron Smith } 308*5146a9eaSAaron Smith 309*5146a9eaSAaron Smith Status NativeProcessWindows::CacheLoadedModules() { 310*5146a9eaSAaron Smith Status error; 311*5146a9eaSAaron Smith if (!m_loaded_modules.empty()) 312*5146a9eaSAaron Smith return Status(); 313*5146a9eaSAaron Smith 314*5146a9eaSAaron Smith // Retrieve loaded modules by a Target/Module free implemenation. 315*5146a9eaSAaron Smith AutoHandle snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetID())); 316*5146a9eaSAaron Smith if (snapshot.IsValid()) { 317*5146a9eaSAaron Smith MODULEENTRY32W me; 318*5146a9eaSAaron Smith me.dwSize = sizeof(MODULEENTRY32W); 319*5146a9eaSAaron Smith if (Module32FirstW(snapshot.get(), &me)) { 320*5146a9eaSAaron Smith do { 321*5146a9eaSAaron Smith std::string path; 322*5146a9eaSAaron Smith if (!llvm::convertWideToUTF8(me.szExePath, path)) 323*5146a9eaSAaron Smith continue; 324*5146a9eaSAaron Smith 325*5146a9eaSAaron Smith FileSpec file_spec(path); 326*5146a9eaSAaron Smith FileSystem::Instance().Resolve(file_spec); 327*5146a9eaSAaron Smith m_loaded_modules[file_spec] = (addr_t)me.modBaseAddr; 328*5146a9eaSAaron Smith } while (Module32Next(snapshot.get(), &me)); 329*5146a9eaSAaron Smith } 330*5146a9eaSAaron Smith 331*5146a9eaSAaron Smith if (!m_loaded_modules.empty()) 332*5146a9eaSAaron Smith return Status(); 333*5146a9eaSAaron Smith } 334*5146a9eaSAaron Smith 335*5146a9eaSAaron Smith error.SetError(::GetLastError(), lldb::ErrorType::eErrorTypeWin32); 336*5146a9eaSAaron Smith return error; 337*5146a9eaSAaron Smith } 338*5146a9eaSAaron Smith 339*5146a9eaSAaron Smith Status NativeProcessWindows::GetLoadedModuleFileSpec(const char *module_path, 340*5146a9eaSAaron Smith FileSpec &file_spec) { 341*5146a9eaSAaron Smith Status error = CacheLoadedModules(); 342*5146a9eaSAaron Smith if (error.Fail()) 343*5146a9eaSAaron Smith return error; 344*5146a9eaSAaron Smith 345*5146a9eaSAaron Smith FileSpec module_file_spec(module_path); 346*5146a9eaSAaron Smith FileSystem::Instance().Resolve(module_file_spec); 347*5146a9eaSAaron Smith for (auto &it : m_loaded_modules) { 348*5146a9eaSAaron Smith if (it.first == module_file_spec) { 349*5146a9eaSAaron Smith file_spec = it.first; 350*5146a9eaSAaron Smith return Status(); 351*5146a9eaSAaron Smith } 352*5146a9eaSAaron Smith } 353*5146a9eaSAaron Smith return Status("Module (%s) not found in process %" PRIu64 "!", 354*5146a9eaSAaron Smith module_file_spec.GetCString(), GetID()); 355*5146a9eaSAaron Smith } 356*5146a9eaSAaron Smith 357*5146a9eaSAaron Smith Status 358*5146a9eaSAaron Smith NativeProcessWindows::GetFileLoadAddress(const llvm::StringRef &file_name, 359*5146a9eaSAaron Smith lldb::addr_t &load_addr) { 360*5146a9eaSAaron Smith Status error = CacheLoadedModules(); 361*5146a9eaSAaron Smith if (error.Fail()) 362*5146a9eaSAaron Smith return error; 363*5146a9eaSAaron Smith 364*5146a9eaSAaron Smith load_addr = LLDB_INVALID_ADDRESS; 365*5146a9eaSAaron Smith FileSpec file_spec(file_name); 366*5146a9eaSAaron Smith FileSystem::Instance().Resolve(file_spec); 367*5146a9eaSAaron Smith for (auto &it : m_loaded_modules) { 368*5146a9eaSAaron Smith if (it.first == file_spec) { 369*5146a9eaSAaron Smith load_addr = it.second; 370*5146a9eaSAaron Smith return Status(); 371*5146a9eaSAaron Smith } 372*5146a9eaSAaron Smith } 373*5146a9eaSAaron Smith return Status("Can't get loaded address of file (%s) in process %" PRIu64 "!", 374*5146a9eaSAaron Smith file_spec.GetCString(), GetID()); 375*5146a9eaSAaron Smith } 376*5146a9eaSAaron Smith 377*5146a9eaSAaron Smith void NativeProcessWindows::OnExitProcess(uint32_t exit_code) { 378*5146a9eaSAaron Smith Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS); 379*5146a9eaSAaron Smith LLDB_LOG(log, "Process {0} exited with code {1}", GetID(), exit_code); 380*5146a9eaSAaron Smith 381*5146a9eaSAaron Smith ProcessDebugger::OnExitProcess(exit_code); 382*5146a9eaSAaron Smith 383*5146a9eaSAaron Smith // No signal involved. It is just an exit event. 384*5146a9eaSAaron Smith WaitStatus wait_status(WaitStatus::Exit, exit_code); 385*5146a9eaSAaron Smith SetExitStatus(wait_status, true); 386*5146a9eaSAaron Smith 387*5146a9eaSAaron Smith // Notify the native delegate. 388*5146a9eaSAaron Smith SetState(eStateExited, true); 389*5146a9eaSAaron Smith } 390*5146a9eaSAaron Smith 391*5146a9eaSAaron Smith void NativeProcessWindows::OnDebuggerConnected(lldb::addr_t image_base) { 392*5146a9eaSAaron Smith Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS); 393*5146a9eaSAaron Smith LLDB_LOG(log, "Debugger connected to process {0}. Image base = {1:x}", 394*5146a9eaSAaron Smith GetDebuggedProcessId(), image_base); 395*5146a9eaSAaron Smith 396*5146a9eaSAaron Smith // This is the earliest chance we can resolve the process ID and 397*5146a9eaSAaron Smith // architecutre if we don't know them yet. 398*5146a9eaSAaron Smith if (GetID() == LLDB_INVALID_PROCESS_ID) 399*5146a9eaSAaron Smith SetID(GetDebuggedProcessId()); 400*5146a9eaSAaron Smith 401*5146a9eaSAaron Smith if (GetArchitecture().GetMachine() == llvm::Triple::UnknownArch) { 402*5146a9eaSAaron Smith ProcessInstanceInfo process_info; 403*5146a9eaSAaron Smith if (!Host::GetProcessInfo(GetDebuggedProcessId(), process_info)) { 404*5146a9eaSAaron Smith LLDB_LOG(log, "Cannot get process information during debugger connecting " 405*5146a9eaSAaron Smith "to process"); 406*5146a9eaSAaron Smith return; 407*5146a9eaSAaron Smith } 408*5146a9eaSAaron Smith SetArchitecture(process_info.GetArchitecture()); 409*5146a9eaSAaron Smith } 410*5146a9eaSAaron Smith 411*5146a9eaSAaron Smith // The very first one shall always be the main thread. 412*5146a9eaSAaron Smith assert(m_threads.empty()); 413*5146a9eaSAaron Smith m_threads.push_back(llvm::make_unique<NativeThreadWindows>( 414*5146a9eaSAaron Smith *this, m_session_data->m_debugger->GetMainThread())); 415*5146a9eaSAaron Smith } 416*5146a9eaSAaron Smith 417*5146a9eaSAaron Smith ExceptionResult 418*5146a9eaSAaron Smith NativeProcessWindows::OnDebugException(bool first_chance, 419*5146a9eaSAaron Smith const ExceptionRecord &record) { 420*5146a9eaSAaron Smith Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EXCEPTION); 421*5146a9eaSAaron Smith llvm::sys::ScopedLock lock(m_mutex); 422*5146a9eaSAaron Smith 423*5146a9eaSAaron Smith // Let the debugger establish the internal status. 424*5146a9eaSAaron Smith ProcessDebugger::OnDebugException(first_chance, record); 425*5146a9eaSAaron Smith 426*5146a9eaSAaron Smith static bool initial_stop = false; 427*5146a9eaSAaron Smith if (!first_chance) { 428*5146a9eaSAaron Smith SetState(eStateStopped, false); 429*5146a9eaSAaron Smith } 430*5146a9eaSAaron Smith 431*5146a9eaSAaron Smith ExceptionResult result = ExceptionResult::SendToApplication; 432*5146a9eaSAaron Smith switch (record.GetExceptionCode()) { 433*5146a9eaSAaron Smith case STATUS_SINGLE_STEP: 434*5146a9eaSAaron Smith case STATUS_WX86_SINGLE_STEP: 435*5146a9eaSAaron Smith StopThread(record.GetThreadID(), StopReason::eStopReasonTrace); 436*5146a9eaSAaron Smith SetState(eStateStopped, true); 437*5146a9eaSAaron Smith 438*5146a9eaSAaron Smith // Continue the debugger. 439*5146a9eaSAaron Smith return ExceptionResult::MaskException; 440*5146a9eaSAaron Smith 441*5146a9eaSAaron Smith case STATUS_BREAKPOINT: 442*5146a9eaSAaron Smith case STATUS_WX86_BREAKPOINT: 443*5146a9eaSAaron Smith if (FindSoftwareBreakpoint(record.GetExceptionAddress())) { 444*5146a9eaSAaron Smith LLDB_LOG(log, "Hit non-loader breakpoint at address {0:x}.", 445*5146a9eaSAaron Smith record.GetExceptionAddress()); 446*5146a9eaSAaron Smith 447*5146a9eaSAaron Smith StopThread(record.GetThreadID(), StopReason::eStopReasonBreakpoint); 448*5146a9eaSAaron Smith 449*5146a9eaSAaron Smith if (NativeThreadWindows *stop_thread = 450*5146a9eaSAaron Smith GetThreadByID(record.GetThreadID())) { 451*5146a9eaSAaron Smith auto ®ister_context = stop_thread->GetRegisterContext(); 452*5146a9eaSAaron Smith // The current EIP is AFTER the BP opcode, which is one byte '0xCC' 453*5146a9eaSAaron Smith uint64_t pc = register_context.GetPC() - 1; 454*5146a9eaSAaron Smith register_context.SetPC(pc); 455*5146a9eaSAaron Smith } 456*5146a9eaSAaron Smith 457*5146a9eaSAaron Smith SetState(eStateStopped, true); 458*5146a9eaSAaron Smith return ExceptionResult::MaskException; 459*5146a9eaSAaron Smith } 460*5146a9eaSAaron Smith 461*5146a9eaSAaron Smith if (!initial_stop) { 462*5146a9eaSAaron Smith initial_stop = true; 463*5146a9eaSAaron Smith LLDB_LOG(log, 464*5146a9eaSAaron Smith "Hit loader breakpoint at address {0:x}, setting initial stop " 465*5146a9eaSAaron Smith "event.", 466*5146a9eaSAaron Smith record.GetExceptionAddress()); 467*5146a9eaSAaron Smith 468*5146a9eaSAaron Smith // We are required to report the reason for the first stop after 469*5146a9eaSAaron Smith // launching or being attached. 470*5146a9eaSAaron Smith if (NativeThreadWindows *thread = GetThreadByID(record.GetThreadID())) 471*5146a9eaSAaron Smith SetStopReasonForThread(*thread, StopReason::eStopReasonBreakpoint); 472*5146a9eaSAaron Smith 473*5146a9eaSAaron Smith // Do not notify the native delegate (e.g. llgs) since at this moment 474*5146a9eaSAaron Smith // the program hasn't returned from Factory::Launch() and the delegate 475*5146a9eaSAaron Smith // might not have an valid native process to operate on. 476*5146a9eaSAaron Smith SetState(eStateStopped, false); 477*5146a9eaSAaron Smith 478*5146a9eaSAaron Smith // Hit the initial stop. Continue the application. 479*5146a9eaSAaron Smith return ExceptionResult::BreakInDebugger; 480*5146a9eaSAaron Smith } 481*5146a9eaSAaron Smith 482*5146a9eaSAaron Smith // Fall through 483*5146a9eaSAaron Smith default: 484*5146a9eaSAaron Smith LLDB_LOG(log, 485*5146a9eaSAaron Smith "Debugger thread reported exception {0:x} at address {1:x} " 486*5146a9eaSAaron Smith "(first_chance={2})", 487*5146a9eaSAaron Smith record.GetExceptionCode(), record.GetExceptionAddress(), 488*5146a9eaSAaron Smith first_chance); 489*5146a9eaSAaron Smith 490*5146a9eaSAaron Smith { 491*5146a9eaSAaron Smith std::string desc; 492*5146a9eaSAaron Smith llvm::raw_string_ostream desc_stream(desc); 493*5146a9eaSAaron Smith desc_stream << "Exception " 494*5146a9eaSAaron Smith << llvm::format_hex(record.GetExceptionCode(), 8) 495*5146a9eaSAaron Smith << " encountered at address " 496*5146a9eaSAaron Smith << llvm::format_hex(record.GetExceptionAddress(), 8); 497*5146a9eaSAaron Smith StopThread(record.GetThreadID(), StopReason::eStopReasonException, 498*5146a9eaSAaron Smith desc_stream.str().c_str()); 499*5146a9eaSAaron Smith 500*5146a9eaSAaron Smith SetState(eStateStopped, true); 501*5146a9eaSAaron Smith } 502*5146a9eaSAaron Smith 503*5146a9eaSAaron Smith // For non-breakpoints, give the application a chance to handle the 504*5146a9eaSAaron Smith // exception first. 505*5146a9eaSAaron Smith if (first_chance) 506*5146a9eaSAaron Smith result = ExceptionResult::SendToApplication; 507*5146a9eaSAaron Smith else 508*5146a9eaSAaron Smith result = ExceptionResult::BreakInDebugger; 509*5146a9eaSAaron Smith } 510*5146a9eaSAaron Smith 511*5146a9eaSAaron Smith return result; 512*5146a9eaSAaron Smith } 513*5146a9eaSAaron Smith 514*5146a9eaSAaron Smith void NativeProcessWindows::OnCreateThread(const HostThread &new_thread) { 515*5146a9eaSAaron Smith llvm::sys::ScopedLock lock(m_mutex); 516*5146a9eaSAaron Smith m_threads.push_back( 517*5146a9eaSAaron Smith llvm::make_unique<NativeThreadWindows>(*this, new_thread)); 518*5146a9eaSAaron Smith } 519*5146a9eaSAaron Smith 520*5146a9eaSAaron Smith void NativeProcessWindows::OnExitThread(lldb::tid_t thread_id, 521*5146a9eaSAaron Smith uint32_t exit_code) { 522*5146a9eaSAaron Smith llvm::sys::ScopedLock lock(m_mutex); 523*5146a9eaSAaron Smith NativeThreadWindows *thread = GetThreadByID(thread_id); 524*5146a9eaSAaron Smith if (!thread) 525*5146a9eaSAaron Smith return; 526*5146a9eaSAaron Smith 527*5146a9eaSAaron Smith for (auto t = m_threads.begin(); t != m_threads.end();) { 528*5146a9eaSAaron Smith if ((*t)->GetID() == thread_id) { 529*5146a9eaSAaron Smith t = m_threads.erase(t); 530*5146a9eaSAaron Smith } else { 531*5146a9eaSAaron Smith ++t; 532*5146a9eaSAaron Smith } 533*5146a9eaSAaron Smith } 534*5146a9eaSAaron Smith } 535*5146a9eaSAaron Smith 536*5146a9eaSAaron Smith void NativeProcessWindows::OnLoadDll(const ModuleSpec &module_spec, 537*5146a9eaSAaron Smith lldb::addr_t module_addr) { 538*5146a9eaSAaron Smith // Simply invalidate the cached loaded modules. 539*5146a9eaSAaron Smith if (!m_loaded_modules.empty()) 540*5146a9eaSAaron Smith m_loaded_modules.clear(); 541*5146a9eaSAaron Smith } 542*5146a9eaSAaron Smith 543*5146a9eaSAaron Smith void NativeProcessWindows::OnUnloadDll(lldb::addr_t module_addr) { 544*5146a9eaSAaron Smith if (!m_loaded_modules.empty()) 545*5146a9eaSAaron Smith m_loaded_modules.clear(); 546*5146a9eaSAaron Smith } 547*5146a9eaSAaron Smith 548*5146a9eaSAaron Smith llvm::Expected<std::unique_ptr<NativeProcessProtocol>> 549*5146a9eaSAaron Smith NativeProcessWindows::Factory::Launch( 550*5146a9eaSAaron Smith ProcessLaunchInfo &launch_info, 551*5146a9eaSAaron Smith NativeProcessProtocol::NativeDelegate &native_delegate, 552*5146a9eaSAaron Smith MainLoop &mainloop) const { 553*5146a9eaSAaron Smith Error E = Error::success(); 554*5146a9eaSAaron Smith auto process_up = std::unique_ptr<NativeProcessWindows>( 555*5146a9eaSAaron Smith new NativeProcessWindows(launch_info, native_delegate, E)); 556*5146a9eaSAaron Smith if (E) 557*5146a9eaSAaron Smith return std::move(E); 558*5146a9eaSAaron Smith return std::move(process_up); 559*5146a9eaSAaron Smith } 560*5146a9eaSAaron Smith 561*5146a9eaSAaron Smith llvm::Expected<std::unique_ptr<NativeProcessProtocol>> 562*5146a9eaSAaron Smith NativeProcessWindows::Factory::Attach( 563*5146a9eaSAaron Smith lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate, 564*5146a9eaSAaron Smith MainLoop &mainloop) const { 565*5146a9eaSAaron Smith Error E = Error::success(); 566*5146a9eaSAaron Smith // Set pty master fd invalid since it is not available. 567*5146a9eaSAaron Smith auto process_up = std::unique_ptr<NativeProcessWindows>( 568*5146a9eaSAaron Smith new NativeProcessWindows(pid, -1, native_delegate, E)); 569*5146a9eaSAaron Smith if (E) 570*5146a9eaSAaron Smith return std::move(E); 571*5146a9eaSAaron Smith return std::move(process_up); 572*5146a9eaSAaron Smith } 573*5146a9eaSAaron Smith } // namespace lldb_private 574