1 //===-- ProcessWindows.cpp --------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "ProcessWindows.h" 11 12 // Windows includes 13 #include "lldb/Host/windows/windows.h" 14 #include <psapi.h> 15 16 // Other libraries and framework includes 17 #include "lldb/Core/Module.h" 18 #include "lldb/Core/ModuleSpec.h" 19 #include "lldb/Core/PluginManager.h" 20 #include "lldb/Core/Section.h" 21 #include "lldb/Core/State.h" 22 #include "lldb/Host/HostNativeProcessBase.h" 23 #include "lldb/Host/HostProcess.h" 24 #include "lldb/Host/windows/HostThreadWindows.h" 25 #include "lldb/Host/windows/windows.h" 26 #include "lldb/Target/DynamicLoader.h" 27 #include "lldb/Target/MemoryRegionInfo.h" 28 #include "lldb/Target/StopInfo.h" 29 #include "lldb/Target/Target.h" 30 31 #include "llvm/Support/ConvertUTF.h" 32 #include "llvm/Support/Format.h" 33 #include "llvm/Support/Threading.h" 34 #include "llvm/Support/raw_ostream.h" 35 36 #include "DebuggerThread.h" 37 #include "ExceptionRecord.h" 38 #include "ForwardDecl.h" 39 #include "LocalDebugDelegate.h" 40 #include "ProcessWindowsLog.h" 41 #include "TargetThreadWindows.h" 42 43 using namespace lldb; 44 using namespace lldb_private; 45 46 namespace { 47 std::string GetProcessExecutableName(HANDLE process_handle) { 48 std::vector<wchar_t> file_name; 49 DWORD file_name_size = MAX_PATH; // first guess, not an absolute limit 50 DWORD copied = 0; 51 do { 52 file_name_size *= 2; 53 file_name.resize(file_name_size); 54 copied = ::GetModuleFileNameExW(process_handle, NULL, file_name.data(), 55 file_name_size); 56 } while (copied >= file_name_size); 57 file_name.resize(copied); 58 std::string result; 59 llvm::convertWideToUTF8(file_name.data(), result); 60 return result; 61 } 62 63 std::string GetProcessExecutableName(DWORD pid) { 64 std::string file_name; 65 HANDLE process_handle = 66 ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid); 67 if (process_handle != NULL) { 68 file_name = GetProcessExecutableName(process_handle); 69 ::CloseHandle(process_handle); 70 } 71 return file_name; 72 } 73 74 } // anonymous namespace 75 76 namespace lldb_private { 77 78 // We store a pointer to this class in the ProcessWindows, so that we don't 79 // expose Windows-specific types and implementation details from a public header 80 // file. 81 class ProcessWindowsData { 82 public: 83 ProcessWindowsData(bool stop_at_entry) : m_stop_at_entry(stop_at_entry) { 84 m_initial_stop_event = ::CreateEvent(nullptr, TRUE, FALSE, nullptr); 85 } 86 87 ~ProcessWindowsData() { ::CloseHandle(m_initial_stop_event); } 88 89 Error m_launch_error; 90 DebuggerThreadSP m_debugger; 91 StopInfoSP m_pending_stop_info; 92 HANDLE m_initial_stop_event = nullptr; 93 bool m_initial_stop_received = false; 94 bool m_stop_at_entry; 95 std::map<lldb::tid_t, HostThread> m_new_threads; 96 std::set<lldb::tid_t> m_exited_threads; 97 }; 98 99 ProcessSP ProcessWindows::CreateInstance(lldb::TargetSP target_sp, 100 lldb::ListenerSP listener_sp, 101 const FileSpec *) { 102 return ProcessSP(new ProcessWindows(target_sp, listener_sp)); 103 } 104 105 void ProcessWindows::Initialize() { 106 static llvm::once_flag g_once_flag; 107 108 llvm::call_once(g_once_flag, []() { 109 PluginManager::RegisterPlugin(GetPluginNameStatic(), 110 GetPluginDescriptionStatic(), CreateInstance); 111 }); 112 } 113 114 void ProcessWindows::Terminate() {} 115 116 lldb_private::ConstString ProcessWindows::GetPluginNameStatic() { 117 static ConstString g_name("windows"); 118 return g_name; 119 } 120 121 const char *ProcessWindows::GetPluginDescriptionStatic() { 122 return "Process plugin for Windows"; 123 } 124 125 //------------------------------------------------------------------------------ 126 // Constructors and destructors. 127 128 ProcessWindows::ProcessWindows(lldb::TargetSP target_sp, 129 lldb::ListenerSP listener_sp) 130 : lldb_private::Process(target_sp, listener_sp) {} 131 132 ProcessWindows::~ProcessWindows() {} 133 134 size_t ProcessWindows::GetSTDOUT(char *buf, size_t buf_size, Error &error) { 135 error.SetErrorString("GetSTDOUT unsupported on Windows"); 136 return 0; 137 } 138 139 size_t ProcessWindows::GetSTDERR(char *buf, size_t buf_size, Error &error) { 140 error.SetErrorString("GetSTDERR unsupported on Windows"); 141 return 0; 142 } 143 144 size_t ProcessWindows::PutSTDIN(const char *buf, size_t buf_size, 145 Error &error) { 146 error.SetErrorString("PutSTDIN unsupported on Windows"); 147 return 0; 148 } 149 150 //------------------------------------------------------------------------------ 151 // ProcessInterface protocol. 152 153 lldb_private::ConstString ProcessWindows::GetPluginName() { 154 return GetPluginNameStatic(); 155 } 156 157 uint32_t ProcessWindows::GetPluginVersion() { return 1; } 158 159 Error ProcessWindows::EnableBreakpointSite(BreakpointSite *bp_site) { 160 WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS, 161 "EnableBreakpointSite called with bp_site 0x%p " 162 "(id=%d, addr=0x%llx)", 163 bp_site, bp_site->GetID(), bp_site->GetLoadAddress()); 164 165 Error error = EnableSoftwareBreakpoint(bp_site); 166 if (!error.Success()) { 167 WINERR_IFALL(WINDOWS_LOG_BREAKPOINTS, "EnableBreakpointSite failed. %s", 168 error.AsCString()); 169 } 170 return error; 171 } 172 173 Error ProcessWindows::DisableBreakpointSite(BreakpointSite *bp_site) { 174 WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS, 175 "DisableBreakpointSite called with bp_site 0x%p " 176 "(id=%d, addr=0x%llx)", 177 bp_site, bp_site->GetID(), bp_site->GetLoadAddress()); 178 179 Error error = DisableSoftwareBreakpoint(bp_site); 180 181 if (!error.Success()) { 182 WINERR_IFALL(WINDOWS_LOG_BREAKPOINTS, "DisableBreakpointSite failed. %s", 183 error.AsCString()); 184 } 185 return error; 186 } 187 188 Error ProcessWindows::DoDetach(bool keep_stopped) { 189 DebuggerThreadSP debugger_thread; 190 StateType private_state; 191 { 192 // Acquire the lock only long enough to get the DebuggerThread. 193 // StopDebugging() will trigger a call back into ProcessWindows which 194 // will also acquire the lock. Thus we have to release the lock before 195 // calling StopDebugging(). 196 llvm::sys::ScopedLock lock(m_mutex); 197 198 private_state = GetPrivateState(); 199 200 if (!m_session_data) { 201 WINWARN_IFALL( 202 WINDOWS_LOG_PROCESS, 203 "DoDetach called while state = %u, but there is no active session.", 204 private_state); 205 return Error(); 206 } 207 208 debugger_thread = m_session_data->m_debugger; 209 } 210 211 Error error; 212 if (private_state != eStateExited && private_state != eStateDetached) { 213 WINLOG_IFALL( 214 WINDOWS_LOG_PROCESS, 215 "DoDetach called for process %p while state = %d. Detaching...", 216 debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(), 217 private_state); 218 error = debugger_thread->StopDebugging(false); 219 if (error.Success()) { 220 SetPrivateState(eStateDetached); 221 } 222 223 // By the time StopDebugging returns, there is no more debugger thread, so 224 // we can be assured that no other thread will race for the session data. 225 m_session_data.reset(); 226 } else { 227 WINERR_IFALL( 228 WINDOWS_LOG_PROCESS, "DoDetach called for process %p while state = " 229 "%d, but cannot destroy in this state.", 230 debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(), 231 private_state); 232 } 233 234 return error; 235 } 236 237 Error ProcessWindows::DoLaunch(Module *exe_module, 238 ProcessLaunchInfo &launch_info) { 239 // Even though m_session_data is accessed here, it is before a debugger thread 240 // has been 241 // kicked off. So there's no race conditions, and it shouldn't be necessary 242 // to acquire 243 // the mutex. 244 245 Error result; 246 if (!launch_info.GetFlags().Test(eLaunchFlagDebug)) { 247 StreamString stream; 248 stream.Printf("ProcessWindows unable to launch '%s'. ProcessWindows can " 249 "only be used for debug launches.", 250 launch_info.GetExecutableFile().GetPath().c_str()); 251 std::string message = stream.GetString(); 252 result.SetErrorString(message.c_str()); 253 254 WINERR_IFALL(WINDOWS_LOG_PROCESS, "%s", message.c_str()); 255 return result; 256 } 257 258 bool stop_at_entry = launch_info.GetFlags().Test(eLaunchFlagStopAtEntry); 259 m_session_data.reset(new ProcessWindowsData(stop_at_entry)); 260 261 SetPrivateState(eStateLaunching); 262 DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this())); 263 m_session_data->m_debugger.reset(new DebuggerThread(delegate)); 264 DebuggerThreadSP debugger = m_session_data->m_debugger; 265 266 // Kick off the DebugLaunch asynchronously and wait for it to complete. 267 result = debugger->DebugLaunch(launch_info); 268 if (result.Fail()) { 269 WINERR_IFALL(WINDOWS_LOG_PROCESS, "DoLaunch failed launching '%s'. %s", 270 launch_info.GetExecutableFile().GetPath().c_str(), 271 result.AsCString()); 272 return result; 273 } 274 275 HostProcess process; 276 Error error = WaitForDebuggerConnection(debugger, process); 277 if (error.Fail()) { 278 WINERR_IFALL(WINDOWS_LOG_PROCESS, "DoLaunch failed launching '%s'. %s", 279 launch_info.GetExecutableFile().GetPath().c_str(), 280 error.AsCString()); 281 return error; 282 } 283 284 WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoLaunch successfully launched '%s'", 285 launch_info.GetExecutableFile().GetPath().c_str()); 286 287 // We've hit the initial stop. If eLaunchFlagsStopAtEntry was specified, the 288 // private state 289 // should already be set to eStateStopped as a result of hitting the initial 290 // breakpoint. If 291 // it was not set, the breakpoint should have already been resumed from and 292 // the private state 293 // should already be eStateRunning. 294 launch_info.SetProcessID(process.GetProcessId()); 295 SetID(process.GetProcessId()); 296 297 return result; 298 } 299 300 Error ProcessWindows::DoAttachToProcessWithID( 301 lldb::pid_t pid, const ProcessAttachInfo &attach_info) { 302 m_session_data.reset( 303 new ProcessWindowsData(!attach_info.GetContinueOnceAttached())); 304 305 DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this())); 306 DebuggerThreadSP debugger(new DebuggerThread(delegate)); 307 308 m_session_data->m_debugger = debugger; 309 310 DWORD process_id = static_cast<DWORD>(pid); 311 Error error = debugger->DebugAttach(process_id, attach_info); 312 if (error.Fail()) { 313 WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoAttachToProcessWithID encountered an " 314 "error occurred initiating the " 315 "asynchronous attach. %s", 316 error.AsCString()); 317 return error; 318 } 319 320 HostProcess process; 321 error = WaitForDebuggerConnection(debugger, process); 322 if (error.Fail()) { 323 WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DoAttachToProcessWithID encountered an " 324 "error waiting for the debugger to " 325 "connect. %s", 326 error.AsCString()); 327 return error; 328 } 329 330 WINLOG_IFALL( 331 WINDOWS_LOG_PROCESS, 332 "DoAttachToProcessWithID successfully attached to process with pid=%lu", 333 process_id); 334 335 // We've hit the initial stop. If eLaunchFlagsStopAtEntry was specified, the 336 // private state 337 // should already be set to eStateStopped as a result of hitting the initial 338 // breakpoint. If 339 // it was not set, the breakpoint should have already been resumed from and 340 // the private state 341 // should already be eStateRunning. 342 SetID(process.GetProcessId()); 343 return error; 344 } 345 346 Error ProcessWindows::DoResume() { 347 llvm::sys::ScopedLock lock(m_mutex); 348 Error error; 349 350 StateType private_state = GetPrivateState(); 351 if (private_state == eStateStopped || private_state == eStateCrashed) { 352 WINLOG_IFALL( 353 WINDOWS_LOG_PROCESS, 354 "DoResume called for process %I64u while state is %u. Resuming...", 355 m_session_data->m_debugger->GetProcess().GetProcessId(), 356 GetPrivateState()); 357 358 ExceptionRecordSP active_exception = 359 m_session_data->m_debugger->GetActiveException().lock(); 360 if (active_exception) { 361 // Resume the process and continue processing debug events. Mask 362 // the exception so that from the process's view, there is no 363 // indication that anything happened. 364 m_session_data->m_debugger->ContinueAsyncException( 365 ExceptionResult::MaskException); 366 } 367 368 WINLOG_IFANY(WINDOWS_LOG_PROCESS | WINDOWS_LOG_THREAD, 369 "DoResume resuming %u threads.", m_thread_list.GetSize()); 370 371 for (uint32_t i = 0; i < m_thread_list.GetSize(); ++i) { 372 auto thread = std::static_pointer_cast<TargetThreadWindows>( 373 m_thread_list.GetThreadAtIndex(i)); 374 thread->DoResume(); 375 } 376 377 SetPrivateState(eStateRunning); 378 } else { 379 WINERR_IFALL( 380 WINDOWS_LOG_PROCESS, 381 "DoResume called for process %I64u but state is %u. Returning...", 382 m_session_data->m_debugger->GetProcess().GetProcessId(), 383 GetPrivateState()); 384 } 385 return error; 386 } 387 388 Error ProcessWindows::DoDestroy() { 389 DebuggerThreadSP debugger_thread; 390 StateType private_state; 391 { 392 // Acquire this lock inside an inner scope, only long enough to get the 393 // DebuggerThread. 394 // StopDebugging() will trigger a call back into ProcessWindows which will 395 // acquire the lock 396 // again, so we need to not deadlock. 397 llvm::sys::ScopedLock lock(m_mutex); 398 399 private_state = GetPrivateState(); 400 401 if (!m_session_data) { 402 WINWARN_IFALL( 403 WINDOWS_LOG_PROCESS, 404 "DoDestroy called while state = %u, but there is no active session.", 405 private_state); 406 return Error(); 407 } 408 409 debugger_thread = m_session_data->m_debugger; 410 } 411 412 Error error; 413 if (private_state != eStateExited && private_state != eStateDetached) { 414 WINLOG_IFALL( 415 WINDOWS_LOG_PROCESS, "DoDestroy called for process %p while state = " 416 "%u. Shutting down...", 417 debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(), 418 private_state); 419 error = debugger_thread->StopDebugging(true); 420 421 // By the time StopDebugging returns, there is no more debugger thread, so 422 // we can be assured that no other thread will race for the session data. 423 m_session_data.reset(); 424 } else { 425 WINERR_IFALL( 426 WINDOWS_LOG_PROCESS, "DoDestroy called for process %p while state = " 427 "%d, but cannot destroy in this state.", 428 debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(), 429 private_state); 430 } 431 432 return error; 433 } 434 435 Error ProcessWindows::DoHalt(bool &caused_stop) { 436 Error error; 437 StateType state = GetPrivateState(); 438 if (state == eStateStopped) 439 caused_stop = false; 440 else { 441 llvm::sys::ScopedLock lock(m_mutex); 442 caused_stop = ::DebugBreakProcess(m_session_data->m_debugger->GetProcess() 443 .GetNativeProcess() 444 .GetSystemHandle()); 445 if (!caused_stop) { 446 error.SetError(::GetLastError(), eErrorTypeWin32); 447 WINERR_IFALL( 448 WINDOWS_LOG_PROCESS, 449 "DoHalt called DebugBreakProcess, but it failed with error %u", 450 error.GetError()); 451 } 452 } 453 return error; 454 } 455 456 void ProcessWindows::DidLaunch() { 457 ArchSpec arch_spec; 458 DidAttach(arch_spec); 459 } 460 461 void ProcessWindows::DidAttach(ArchSpec &arch_spec) { 462 llvm::sys::ScopedLock lock(m_mutex); 463 464 // The initial stop won't broadcast the state change event, so account for 465 // that here. 466 if (m_session_data && GetPrivateState() == eStateStopped && 467 m_session_data->m_stop_at_entry) 468 RefreshStateAfterStop(); 469 } 470 471 void ProcessWindows::RefreshStateAfterStop() { 472 llvm::sys::ScopedLock lock(m_mutex); 473 474 if (!m_session_data) { 475 WINWARN_IFALL( 476 WINDOWS_LOG_PROCESS, 477 "RefreshStateAfterStop called with no active session. Returning..."); 478 return; 479 } 480 481 m_thread_list.RefreshStateAfterStop(); 482 483 std::weak_ptr<ExceptionRecord> exception_record = 484 m_session_data->m_debugger->GetActiveException(); 485 ExceptionRecordSP active_exception = exception_record.lock(); 486 if (!active_exception) { 487 WINERR_IFALL( 488 WINDOWS_LOG_PROCESS, 489 "RefreshStateAfterStop called for process %I64u but there is no " 490 "active exception. Why is the process stopped?", 491 m_session_data->m_debugger->GetProcess().GetProcessId()); 492 return; 493 } 494 495 StopInfoSP stop_info; 496 m_thread_list.SetSelectedThreadByID(active_exception->GetThreadID()); 497 ThreadSP stop_thread = m_thread_list.GetSelectedThread(); 498 if (!stop_thread) 499 return; 500 501 switch (active_exception->GetExceptionCode()) { 502 case EXCEPTION_SINGLE_STEP: { 503 RegisterContextSP register_context = stop_thread->GetRegisterContext(); 504 const uint64_t pc = register_context->GetPC(); 505 BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc)); 506 if (site && site->ValidForThisThread(stop_thread.get())) { 507 WINLOG_IFANY(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION | 508 WINDOWS_LOG_STEP, 509 "Single-stepped onto a breakpoint in process %I64u at " 510 "address 0x%I64x with breakpoint site %d", 511 m_session_data->m_debugger->GetProcess().GetProcessId(), pc, 512 site->GetID()); 513 stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*stop_thread, 514 site->GetID()); 515 stop_thread->SetStopInfo(stop_info); 516 } else { 517 WINLOG_IFANY(WINDOWS_LOG_EXCEPTION | WINDOWS_LOG_STEP, 518 "RefreshStateAfterStop single stepping thread %llu", 519 stop_thread->GetID()); 520 stop_info = StopInfo::CreateStopReasonToTrace(*stop_thread); 521 stop_thread->SetStopInfo(stop_info); 522 } 523 return; 524 } 525 526 case EXCEPTION_BREAKPOINT: { 527 RegisterContextSP register_context = stop_thread->GetRegisterContext(); 528 529 // The current EIP is AFTER the BP opcode, which is one byte. 530 uint64_t pc = register_context->GetPC() - 1; 531 532 BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc)); 533 if (site) { 534 WINLOG_IFANY( 535 WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION, 536 "RefreshStateAfterStop detected breakpoint in process %I64u at " 537 "address 0x%I64x with breakpoint site %d", 538 m_session_data->m_debugger->GetProcess().GetProcessId(), pc, 539 site->GetID()); 540 541 if (site->ValidForThisThread(stop_thread.get())) { 542 WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION, 543 "Breakpoint site %d is valid for this thread (0x%I64x), " 544 "creating stop info.", 545 site->GetID(), stop_thread->GetID()); 546 547 stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID( 548 *stop_thread, site->GetID()); 549 register_context->SetPC(pc); 550 } else { 551 WINLOG_IFALL(WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION, 552 "Breakpoint site %d is not valid for this thread, " 553 "creating empty stop info.", 554 site->GetID()); 555 } 556 stop_thread->SetStopInfo(stop_info); 557 return; 558 } else { 559 // The thread hit a hard-coded breakpoint like an `int 3` or 560 // `__debugbreak()`. 561 WINLOG_IFALL( 562 WINDOWS_LOG_BREAKPOINTS | WINDOWS_LOG_EXCEPTION, 563 "No breakpoint site matches for this thread. __debugbreak()? " 564 "Creating stop info with the exception."); 565 // FALLTHROUGH: We'll treat this as a generic exception record in the 566 // default case. 567 } 568 } 569 570 default: { 571 std::string desc; 572 llvm::raw_string_ostream desc_stream(desc); 573 desc_stream << "Exception " 574 << llvm::format_hex(active_exception->GetExceptionCode(), 8) 575 << " encountered at address " 576 << llvm::format_hex(active_exception->GetExceptionAddress(), 8); 577 stop_info = StopInfo::CreateStopReasonWithException( 578 *stop_thread, desc_stream.str().c_str()); 579 stop_thread->SetStopInfo(stop_info); 580 WINLOG_IFALL(WINDOWS_LOG_EXCEPTION, "%s", desc_stream.str().c_str()); 581 return; 582 } 583 } 584 } 585 586 bool ProcessWindows::CanDebug(lldb::TargetSP target_sp, 587 bool plugin_specified_by_name) { 588 if (plugin_specified_by_name) 589 return true; 590 591 // For now we are just making sure the file exists for a given module 592 ModuleSP exe_module_sp(target_sp->GetExecutableModule()); 593 if (exe_module_sp.get()) 594 return exe_module_sp->GetFileSpec().Exists(); 595 // However, if there is no executable module, we return true since we might be 596 // preparing to attach. 597 return true; 598 } 599 600 bool ProcessWindows::UpdateThreadList(ThreadList &old_thread_list, 601 ThreadList &new_thread_list) { 602 // Add all the threads that were previously running and for which we did not 603 // detect a thread exited event. 604 int new_size = 0; 605 int continued_threads = 0; 606 int exited_threads = 0; 607 int new_threads = 0; 608 609 for (ThreadSP old_thread : old_thread_list.Threads()) { 610 lldb::tid_t old_thread_id = old_thread->GetID(); 611 auto exited_thread_iter = 612 m_session_data->m_exited_threads.find(old_thread_id); 613 if (exited_thread_iter == m_session_data->m_exited_threads.end()) { 614 new_thread_list.AddThread(old_thread); 615 ++new_size; 616 ++continued_threads; 617 WINLOGV_IFALL( 618 WINDOWS_LOG_THREAD, 619 "UpdateThreadList - Thread %llu was running and is still running.", 620 old_thread_id); 621 } else { 622 WINLOGV_IFALL( 623 WINDOWS_LOG_THREAD, 624 "UpdateThreadList - Thread %llu was running and has exited.", 625 old_thread_id); 626 ++exited_threads; 627 } 628 } 629 630 // Also add all the threads that are new since the last time we broke into the 631 // debugger. 632 for (const auto &thread_info : m_session_data->m_new_threads) { 633 ThreadSP thread(new TargetThreadWindows(*this, thread_info.second)); 634 thread->SetID(thread_info.first); 635 new_thread_list.AddThread(thread); 636 ++new_size; 637 ++new_threads; 638 WINLOGV_IFALL(WINDOWS_LOG_THREAD, 639 "UpdateThreadList - Thread %llu is new since last update.", 640 thread_info.first); 641 } 642 643 WINLOG_IFALL( 644 WINDOWS_LOG_THREAD, 645 "UpdateThreadList - %d new threads, %d old threads, %d exited threads.", 646 new_threads, continued_threads, exited_threads); 647 648 m_session_data->m_new_threads.clear(); 649 m_session_data->m_exited_threads.clear(); 650 651 return new_size > 0; 652 } 653 654 bool ProcessWindows::IsAlive() { 655 StateType state = GetPrivateState(); 656 switch (state) { 657 case eStateCrashed: 658 case eStateDetached: 659 case eStateUnloaded: 660 case eStateExited: 661 case eStateInvalid: 662 return false; 663 default: 664 return true; 665 } 666 } 667 668 size_t ProcessWindows::DoReadMemory(lldb::addr_t vm_addr, void *buf, 669 size_t size, Error &error) { 670 llvm::sys::ScopedLock lock(m_mutex); 671 672 if (!m_session_data) 673 return 0; 674 675 WINLOG_IFALL(WINDOWS_LOG_MEMORY, 676 "DoReadMemory attempting to read %u bytes from address 0x%I64x", 677 size, vm_addr); 678 679 HostProcess process = m_session_data->m_debugger->GetProcess(); 680 void *addr = reinterpret_cast<void *>(vm_addr); 681 SIZE_T bytes_read = 0; 682 if (!ReadProcessMemory(process.GetNativeProcess().GetSystemHandle(), addr, 683 buf, size, &bytes_read)) { 684 error.SetError(GetLastError(), eErrorTypeWin32); 685 WINERR_IFALL(WINDOWS_LOG_MEMORY, "DoReadMemory failed with error code %u", 686 error.GetError()); 687 } 688 return bytes_read; 689 } 690 691 size_t ProcessWindows::DoWriteMemory(lldb::addr_t vm_addr, const void *buf, 692 size_t size, Error &error) { 693 llvm::sys::ScopedLock lock(m_mutex); 694 WINLOG_IFALL( 695 WINDOWS_LOG_MEMORY, 696 "DoWriteMemory attempting to write %u bytes into address 0x%I64x", size, 697 vm_addr); 698 699 if (!m_session_data) { 700 WINERR_IFANY( 701 WINDOWS_LOG_MEMORY, 702 "DoWriteMemory cannot write, there is no active debugger connection."); 703 return 0; 704 } 705 706 HostProcess process = m_session_data->m_debugger->GetProcess(); 707 void *addr = reinterpret_cast<void *>(vm_addr); 708 SIZE_T bytes_written = 0; 709 lldb::process_t handle = process.GetNativeProcess().GetSystemHandle(); 710 if (WriteProcessMemory(handle, addr, buf, size, &bytes_written)) 711 FlushInstructionCache(handle, addr, bytes_written); 712 else { 713 error.SetError(GetLastError(), eErrorTypeWin32); 714 WINLOG_IFALL(WINDOWS_LOG_MEMORY, "DoWriteMemory failed with error code %u", 715 error.GetError()); 716 } 717 return bytes_written; 718 } 719 720 #define BOOL_STR(b) ((b) ? "true" : "false") 721 722 Error ProcessWindows::GetMemoryRegionInfo(lldb::addr_t vm_addr, 723 MemoryRegionInfo &info) { 724 Error error; 725 llvm::sys::ScopedLock lock(m_mutex); 726 info.Clear(); 727 728 if (!m_session_data) { 729 error.SetErrorString( 730 "GetMemoryRegionInfo called with no debugging session."); 731 WINERR_IFALL(WINDOWS_LOG_MEMORY, "%s", error.AsCString()); 732 return error; 733 } 734 HostProcess process = m_session_data->m_debugger->GetProcess(); 735 lldb::process_t handle = process.GetNativeProcess().GetSystemHandle(); 736 if (handle == nullptr || handle == LLDB_INVALID_PROCESS) { 737 error.SetErrorString( 738 "GetMemoryRegionInfo called with an invalid target process."); 739 WINERR_IFALL(WINDOWS_LOG_MEMORY, "%s", error.AsCString()); 740 return error; 741 } 742 743 WINLOG_IFALL(WINDOWS_LOG_MEMORY, 744 "GetMemoryRegionInfo getting info for address 0x%I64x", vm_addr); 745 746 void *addr = reinterpret_cast<void *>(vm_addr); 747 MEMORY_BASIC_INFORMATION mem_info = {}; 748 SIZE_T result = ::VirtualQueryEx(handle, addr, &mem_info, sizeof(mem_info)); 749 if (result == 0) { 750 if (::GetLastError() == ERROR_INVALID_PARAMETER) { 751 // ERROR_INVALID_PARAMETER is returned if VirtualQueryEx is called with an 752 // address 753 // past the highest accessible address. We should return a range from the 754 // vm_addr 755 // to LLDB_INVALID_ADDRESS 756 info.GetRange().SetRangeBase(vm_addr); 757 info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS); 758 info.SetReadable(MemoryRegionInfo::eNo); 759 info.SetExecutable(MemoryRegionInfo::eNo); 760 info.SetWritable(MemoryRegionInfo::eNo); 761 info.SetMapped(MemoryRegionInfo::eNo); 762 return error; 763 } else { 764 error.SetError(::GetLastError(), eErrorTypeWin32); 765 WINERR_IFALL(WINDOWS_LOG_MEMORY, "VirtualQueryEx returned error %u while " 766 "getting memory region info for address " 767 "0x%I64x", 768 error.GetError(), vm_addr); 769 return error; 770 } 771 } 772 773 // Protect bits are only valid for MEM_COMMIT regions. 774 if (mem_info.State == MEM_COMMIT) { 775 const bool readable = IsPageReadable(mem_info.Protect); 776 const bool executable = IsPageExecutable(mem_info.Protect); 777 const bool writable = IsPageWritable(mem_info.Protect); 778 info.SetReadable(readable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo); 779 info.SetExecutable(executable ? MemoryRegionInfo::eYes 780 : MemoryRegionInfo::eNo); 781 info.SetWritable(writable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo); 782 } else { 783 info.SetReadable(MemoryRegionInfo::eNo); 784 info.SetExecutable(MemoryRegionInfo::eNo); 785 info.SetWritable(MemoryRegionInfo::eNo); 786 } 787 788 // AllocationBase is defined for MEM_COMMIT and MEM_RESERVE but not MEM_FREE. 789 if (mem_info.State != MEM_FREE) { 790 info.GetRange().SetRangeBase( 791 reinterpret_cast<addr_t>(mem_info.AllocationBase)); 792 info.GetRange().SetRangeEnd(reinterpret_cast<addr_t>(mem_info.BaseAddress) + 793 mem_info.RegionSize); 794 info.SetMapped(MemoryRegionInfo::eYes); 795 } else { 796 // In the unmapped case we need to return the distance to the next block of 797 // memory. 798 // VirtualQueryEx nearly does that except that it gives the distance from 799 // the start 800 // of the page containing vm_addr. 801 SYSTEM_INFO data; 802 GetSystemInfo(&data); 803 DWORD page_offset = vm_addr % data.dwPageSize; 804 info.GetRange().SetRangeBase(vm_addr); 805 info.GetRange().SetByteSize(mem_info.RegionSize - page_offset); 806 info.SetMapped(MemoryRegionInfo::eNo); 807 } 808 809 error.SetError(::GetLastError(), eErrorTypeWin32); 810 WINLOGV_IFALL(WINDOWS_LOG_MEMORY, "Memory region info for address %llu: " 811 "readable=%s, executable=%s, writable=%s", 812 vm_addr, BOOL_STR(info.GetReadable()), 813 BOOL_STR(info.GetExecutable()), BOOL_STR(info.GetWritable())); 814 return error; 815 } 816 817 lldb::addr_t ProcessWindows::GetImageInfoAddress() { 818 Target &target = GetTarget(); 819 ObjectFile *obj_file = target.GetExecutableModule()->GetObjectFile(); 820 Address addr = obj_file->GetImageInfoAddress(&target); 821 if (addr.IsValid()) 822 return addr.GetLoadAddress(&target); 823 else 824 return LLDB_INVALID_ADDRESS; 825 } 826 827 void ProcessWindows::OnExitProcess(uint32_t exit_code) { 828 // No need to acquire the lock since m_session_data isn't accessed. 829 WINLOG_IFALL(WINDOWS_LOG_PROCESS, "Process %llu exited with code %u", GetID(), 830 exit_code); 831 832 TargetSP target = m_target_sp.lock(); 833 if (target) { 834 ModuleSP executable_module = target->GetExecutableModule(); 835 ModuleList unloaded_modules; 836 unloaded_modules.Append(executable_module); 837 target->ModulesDidUnload(unloaded_modules, true); 838 } 839 840 SetProcessExitStatus(GetID(), true, 0, exit_code); 841 SetPrivateState(eStateExited); 842 } 843 844 void ProcessWindows::OnDebuggerConnected(lldb::addr_t image_base) { 845 DebuggerThreadSP debugger = m_session_data->m_debugger; 846 847 WINLOG_IFALL(WINDOWS_LOG_PROCESS, 848 "Debugger connected to process %I64u. Image base = 0x%I64x", 849 debugger->GetProcess().GetProcessId(), image_base); 850 851 ModuleSP module = GetTarget().GetExecutableModule(); 852 if (!module) { 853 // During attach, we won't have the executable module, so find it now. 854 const DWORD pid = debugger->GetProcess().GetProcessId(); 855 const std::string file_name = GetProcessExecutableName(pid); 856 if (file_name.empty()) { 857 return; 858 } 859 860 FileSpec executable_file(file_name, true); 861 ModuleSpec module_spec(executable_file); 862 Error error; 863 module = GetTarget().GetSharedModule(module_spec, &error); 864 if (!module) { 865 return; 866 } 867 868 GetTarget().SetExecutableModule(module, false); 869 } 870 871 bool load_addr_changed; 872 module->SetLoadAddress(GetTarget(), image_base, false, load_addr_changed); 873 874 ModuleList loaded_modules; 875 loaded_modules.Append(module); 876 GetTarget().ModulesDidLoad(loaded_modules); 877 878 // Add the main executable module to the list of pending module loads. We 879 // can't call 880 // GetTarget().ModulesDidLoad() here because we still haven't returned from 881 // DoLaunch() / DoAttach() yet 882 // so the target may not have set the process instance to `this` yet. 883 llvm::sys::ScopedLock lock(m_mutex); 884 const HostThreadWindows &wmain_thread = 885 debugger->GetMainThread().GetNativeThread(); 886 m_session_data->m_new_threads[wmain_thread.GetThreadId()] = 887 debugger->GetMainThread(); 888 } 889 890 ExceptionResult 891 ProcessWindows::OnDebugException(bool first_chance, 892 const ExceptionRecord &record) { 893 llvm::sys::ScopedLock lock(m_mutex); 894 895 // FIXME: Without this check, occasionally when running the test suite there 896 // is 897 // an issue where m_session_data can be null. It's not clear how this could 898 // happen 899 // but it only surfaces while running the test suite. In order to properly 900 // diagnose 901 // this, we probably need to first figure allow the test suite to print out 902 // full 903 // lldb logs, and then add logging to the process plugin. 904 if (!m_session_data) { 905 WINERR_IFANY(WINDOWS_LOG_EXCEPTION, "Debugger thread reported exception " 906 "0x%lx at address 0x%llu, but there is " 907 "no session.", 908 record.GetExceptionCode(), record.GetExceptionAddress()); 909 return ExceptionResult::SendToApplication; 910 } 911 912 if (!first_chance) { 913 // Any second chance exception is an application crash by definition. 914 SetPrivateState(eStateCrashed); 915 } 916 917 ExceptionResult result = ExceptionResult::SendToApplication; 918 switch (record.GetExceptionCode()) { 919 case EXCEPTION_BREAKPOINT: 920 // Handle breakpoints at the first chance. 921 result = ExceptionResult::BreakInDebugger; 922 923 if (!m_session_data->m_initial_stop_received) { 924 WINLOG_IFANY(WINDOWS_LOG_BREAKPOINTS, "Hit loader breakpoint at address " 925 "0x%I64x, setting initial stop " 926 "event.", 927 record.GetExceptionAddress()); 928 m_session_data->m_initial_stop_received = true; 929 ::SetEvent(m_session_data->m_initial_stop_event); 930 } else { 931 WINLOG_IFANY(WINDOWS_LOG_BREAKPOINTS, 932 "Hit non-loader breakpoint at address 0x%I64x.", 933 record.GetExceptionAddress()); 934 } 935 SetPrivateState(eStateStopped); 936 break; 937 case EXCEPTION_SINGLE_STEP: 938 result = ExceptionResult::BreakInDebugger; 939 SetPrivateState(eStateStopped); 940 break; 941 default: 942 WINLOG_IFANY(WINDOWS_LOG_EXCEPTION, "Debugger thread reported exception " 943 "0x%lx at address 0x%llx " 944 "(first_chance=%s)", 945 record.GetExceptionCode(), record.GetExceptionAddress(), 946 BOOL_STR(first_chance)); 947 // For non-breakpoints, give the application a chance to handle the 948 // exception first. 949 if (first_chance) 950 result = ExceptionResult::SendToApplication; 951 else 952 result = ExceptionResult::BreakInDebugger; 953 } 954 955 return result; 956 } 957 958 void ProcessWindows::OnCreateThread(const HostThread &new_thread) { 959 llvm::sys::ScopedLock lock(m_mutex); 960 const HostThreadWindows &wnew_thread = new_thread.GetNativeThread(); 961 m_session_data->m_new_threads[wnew_thread.GetThreadId()] = new_thread; 962 } 963 964 void ProcessWindows::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) { 965 llvm::sys::ScopedLock lock(m_mutex); 966 967 // On a forced termination, we may get exit thread events after the session 968 // data has been cleaned up. 969 if (!m_session_data) 970 return; 971 972 // A thread may have started and exited before the debugger stopped allowing a 973 // refresh. 974 // Just remove it from the new threads list in that case. 975 auto iter = m_session_data->m_new_threads.find(thread_id); 976 if (iter != m_session_data->m_new_threads.end()) 977 m_session_data->m_new_threads.erase(iter); 978 else 979 m_session_data->m_exited_threads.insert(thread_id); 980 } 981 982 void ProcessWindows::OnLoadDll(const ModuleSpec &module_spec, 983 lldb::addr_t module_addr) { 984 // Confusingly, there is no Target::AddSharedModule. Instead, calling 985 // GetSharedModule() with 986 // a new module will add it to the module list and return a corresponding 987 // ModuleSP. 988 Error error; 989 ModuleSP module = GetTarget().GetSharedModule(module_spec, &error); 990 bool load_addr_changed = false; 991 module->SetLoadAddress(GetTarget(), module_addr, false, load_addr_changed); 992 993 ModuleList loaded_modules; 994 loaded_modules.Append(module); 995 GetTarget().ModulesDidLoad(loaded_modules); 996 } 997 998 void ProcessWindows::OnUnloadDll(lldb::addr_t module_addr) { 999 Address resolved_addr; 1000 if (GetTarget().ResolveLoadAddress(module_addr, resolved_addr)) { 1001 ModuleSP module = resolved_addr.GetModule(); 1002 if (module) { 1003 ModuleList unloaded_modules; 1004 unloaded_modules.Append(module); 1005 GetTarget().ModulesDidUnload(unloaded_modules, false); 1006 } 1007 } 1008 } 1009 1010 void ProcessWindows::OnDebugString(const std::string &string) {} 1011 1012 void ProcessWindows::OnDebuggerError(const Error &error, uint32_t type) { 1013 llvm::sys::ScopedLock lock(m_mutex); 1014 1015 if (m_session_data->m_initial_stop_received) { 1016 // This happened while debugging. Do we shutdown the debugging session, try 1017 // to continue, 1018 // or do something else? 1019 WINERR_IFALL(WINDOWS_LOG_PROCESS, "Error %u occurred during debugging. " 1020 "Unexpected behavior may result. %s", 1021 error.GetError(), error.AsCString()); 1022 } else { 1023 // If we haven't actually launched the process yet, this was an error 1024 // launching the 1025 // process. Set the internal error and signal the initial stop event so 1026 // that the DoLaunch 1027 // method wakes up and returns a failure. 1028 m_session_data->m_launch_error = error; 1029 ::SetEvent(m_session_data->m_initial_stop_event); 1030 WINERR_IFALL( 1031 WINDOWS_LOG_PROCESS, 1032 "Error %u occurred launching the process before the initial stop. %s", 1033 error.GetError(), error.AsCString()); 1034 return; 1035 } 1036 } 1037 1038 Error ProcessWindows::WaitForDebuggerConnection(DebuggerThreadSP debugger, 1039 HostProcess &process) { 1040 Error result; 1041 WINLOG_IFANY(WINDOWS_LOG_PROCESS | WINDOWS_LOG_BREAKPOINTS, 1042 "WaitForDebuggerConnection Waiting for loader breakpoint."); 1043 1044 // Block this function until we receive the initial stop from the process. 1045 if (::WaitForSingleObject(m_session_data->m_initial_stop_event, INFINITE) == 1046 WAIT_OBJECT_0) { 1047 WINLOG_IFANY(WINDOWS_LOG_PROCESS | WINDOWS_LOG_BREAKPOINTS, 1048 "WaitForDebuggerConnection hit loader breakpoint, returning."); 1049 1050 process = debugger->GetProcess(); 1051 return m_session_data->m_launch_error; 1052 } else 1053 return Error(::GetLastError(), eErrorTypeWin32); 1054 } 1055 1056 // The Windows page protection bits are NOT independent masks that can be 1057 // bitwise-ORed together. For example, PAGE_EXECUTE_READ is not 1058 // (PAGE_EXECUTE | PAGE_READ). To test for an access type, it's necessary to 1059 // test for any of the bits that provide that access type. 1060 bool ProcessWindows::IsPageReadable(uint32_t protect) { 1061 return (protect & PAGE_NOACCESS) == 0; 1062 } 1063 1064 bool ProcessWindows::IsPageWritable(uint32_t protect) { 1065 return (protect & (PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY | 1066 PAGE_READWRITE | PAGE_WRITECOPY)) != 0; 1067 } 1068 1069 bool ProcessWindows::IsPageExecutable(uint32_t protect) { 1070 return (protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | 1071 PAGE_EXECUTE_WRITECOPY)) != 0; 1072 } 1073 1074 } // namespace lldb_private 1075