1 //===-- ProcessWindows.cpp ------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "ProcessWindows.h" 10 11 // Windows includes 12 #include "lldb/Host/windows/windows.h" 13 #include <psapi.h> 14 15 #include "lldb/Breakpoint/Watchpoint.h" 16 #include "lldb/Core/Module.h" 17 #include "lldb/Core/ModuleSpec.h" 18 #include "lldb/Core/PluginManager.h" 19 #include "lldb/Core/Section.h" 20 #include "lldb/Host/FileSystem.h" 21 #include "lldb/Host/HostInfo.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/Symbol/ObjectFile.h" 27 #include "lldb/Target/DynamicLoader.h" 28 #include "lldb/Target/MemoryRegionInfo.h" 29 #include "lldb/Target/StopInfo.h" 30 #include "lldb/Target/Target.h" 31 #include "lldb/Utility/State.h" 32 33 #include "llvm/Support/ConvertUTF.h" 34 #include "llvm/Support/Format.h" 35 #include "llvm/Support/Threading.h" 36 #include "llvm/Support/raw_ostream.h" 37 38 #include "DebuggerThread.h" 39 #include "ExceptionRecord.h" 40 #include "ForwardDecl.h" 41 #include "LocalDebugDelegate.h" 42 #include "ProcessWindowsLog.h" 43 #include "TargetThreadWindows.h" 44 45 using namespace lldb; 46 using namespace lldb_private; 47 48 LLDB_PLUGIN_DEFINE_ADV(ProcessWindows, ProcessWindowsCommon) 49 50 namespace { 51 std::string GetProcessExecutableName(HANDLE process_handle) { 52 std::vector<wchar_t> file_name; 53 DWORD file_name_size = MAX_PATH; // first guess, not an absolute limit 54 DWORD copied = 0; 55 do { 56 file_name_size *= 2; 57 file_name.resize(file_name_size); 58 copied = ::GetModuleFileNameExW(process_handle, NULL, file_name.data(), 59 file_name_size); 60 } while (copied >= file_name_size); 61 file_name.resize(copied); 62 std::string result; 63 llvm::convertWideToUTF8(file_name.data(), result); 64 return result; 65 } 66 67 std::string GetProcessExecutableName(DWORD pid) { 68 std::string file_name; 69 HANDLE process_handle = 70 ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid); 71 if (process_handle != NULL) { 72 file_name = GetProcessExecutableName(process_handle); 73 ::CloseHandle(process_handle); 74 } 75 return file_name; 76 } 77 } // anonymous namespace 78 79 namespace lldb_private { 80 81 ProcessSP ProcessWindows::CreateInstance(lldb::TargetSP target_sp, 82 lldb::ListenerSP listener_sp, 83 const FileSpec *, 84 bool can_connect) { 85 return ProcessSP(new ProcessWindows(target_sp, listener_sp)); 86 } 87 88 static bool ShouldUseLLDBServer() { 89 llvm::StringRef use_lldb_server = ::getenv("LLDB_USE_LLDB_SERVER"); 90 return use_lldb_server.equals_insensitive("on") || 91 use_lldb_server.equals_insensitive("yes") || 92 use_lldb_server.equals_insensitive("1") || 93 use_lldb_server.equals_insensitive("true"); 94 } 95 96 void ProcessWindows::Initialize() { 97 if (!ShouldUseLLDBServer()) { 98 static llvm::once_flag g_once_flag; 99 100 llvm::call_once(g_once_flag, []() { 101 PluginManager::RegisterPlugin(GetPluginNameStatic(), 102 GetPluginDescriptionStatic(), 103 CreateInstance); 104 }); 105 } 106 } 107 108 void ProcessWindows::Terminate() {} 109 110 llvm::StringRef ProcessWindows::GetPluginDescriptionStatic() { 111 return "Process plugin for Windows"; 112 } 113 114 // Constructors and destructors. 115 116 ProcessWindows::ProcessWindows(lldb::TargetSP target_sp, 117 lldb::ListenerSP listener_sp) 118 : lldb_private::Process(target_sp, listener_sp), 119 m_watchpoint_ids( 120 RegisterContextWindows::GetNumHardwareBreakpointSlots(), 121 LLDB_INVALID_BREAK_ID) {} 122 123 ProcessWindows::~ProcessWindows() {} 124 125 size_t ProcessWindows::GetSTDOUT(char *buf, size_t buf_size, Status &error) { 126 error = Status::FromErrorString("GetSTDOUT unsupported on Windows"); 127 return 0; 128 } 129 130 size_t ProcessWindows::GetSTDERR(char *buf, size_t buf_size, Status &error) { 131 error = Status::FromErrorString("GetSTDERR unsupported on Windows"); 132 return 0; 133 } 134 135 size_t ProcessWindows::PutSTDIN(const char *buf, size_t buf_size, 136 Status &error) { 137 error = Status::FromErrorString("PutSTDIN unsupported on Windows"); 138 return 0; 139 } 140 141 Status ProcessWindows::EnableBreakpointSite(BreakpointSite *bp_site) { 142 if (bp_site->HardwareRequired()) 143 return Status::FromErrorString("Hardware breakpoints are not supported."); 144 145 Log *log = GetLog(WindowsLog::Breakpoints); 146 LLDB_LOG(log, "bp_site = {0:x}, id={1}, addr={2:x}", bp_site, 147 bp_site->GetID(), bp_site->GetLoadAddress()); 148 149 Status error = EnableSoftwareBreakpoint(bp_site); 150 if (!error.Success()) 151 LLDB_LOG(log, "error: {0}", error); 152 return error; 153 } 154 155 Status ProcessWindows::DisableBreakpointSite(BreakpointSite *bp_site) { 156 Log *log = GetLog(WindowsLog::Breakpoints); 157 LLDB_LOG(log, "bp_site = {0:x}, id={1}, addr={2:x}", bp_site, 158 bp_site->GetID(), bp_site->GetLoadAddress()); 159 160 Status error = DisableSoftwareBreakpoint(bp_site); 161 162 if (!error.Success()) 163 LLDB_LOG(log, "error: {0}", error); 164 return error; 165 } 166 167 Status ProcessWindows::DoDetach(bool keep_stopped) { 168 Status error; 169 Log *log = GetLog(WindowsLog::Process); 170 StateType private_state = GetPrivateState(); 171 if (private_state != eStateExited && private_state != eStateDetached) { 172 if (!keep_stopped) { 173 // if the thread is suspended by lldb, we have to resume threads before 174 // detaching process. When we do after DetachProcess(), thread handles 175 // become invalid so we do before detach. 176 if (private_state == eStateStopped || private_state == eStateCrashed) { 177 LLDB_LOG(log, "process {0} is in state {1}. Resuming for detach...", 178 m_session_data->m_debugger->GetProcess().GetProcessId(), 179 GetPrivateState()); 180 181 LLDB_LOG(log, "resuming {0} threads for detach.", 182 m_thread_list.GetSize()); 183 184 bool failed = false; 185 for (uint32_t i = 0; i < m_thread_list.GetSize(); ++i) { 186 auto thread = std::static_pointer_cast<TargetThreadWindows>( 187 m_thread_list.GetThreadAtIndex(i)); 188 Status result = thread->DoResume(); 189 if (result.Fail()) { 190 failed = true; 191 LLDB_LOG(log, 192 "Trying to resume thread at index {0}, but failed with " 193 "error {1}.", 194 i, result); 195 } 196 } 197 198 if (failed) { 199 error = Status::FromErrorString("Resuming Threads for Detach failed"); 200 } 201 } 202 } 203 204 error = DetachProcess(); 205 if (error.Success()) 206 SetPrivateState(eStateDetached); 207 else 208 LLDB_LOG(log, "Detaching process error: {0}", error); 209 } else { 210 error = Status::FromErrorStringWithFormatv( 211 "error: process {0} in state = {1}, but " 212 "cannot detach it in this state.", 213 GetID(), private_state); 214 LLDB_LOG(log, "error: {0}", error); 215 } 216 return error; 217 } 218 219 Status ProcessWindows::DoLaunch(Module *exe_module, 220 ProcessLaunchInfo &launch_info) { 221 Status error; 222 DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this())); 223 error = LaunchProcess(launch_info, delegate); 224 if (error.Success()) 225 SetID(launch_info.GetProcessID()); 226 return error; 227 } 228 229 Status 230 ProcessWindows::DoAttachToProcessWithID(lldb::pid_t pid, 231 const ProcessAttachInfo &attach_info) { 232 DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this())); 233 Status error = AttachProcess(pid, attach_info, delegate); 234 if (error.Success()) 235 SetID(GetDebuggedProcessId()); 236 return error; 237 } 238 239 Status ProcessWindows::DoResume() { 240 Log *log = GetLog(WindowsLog::Process); 241 llvm::sys::ScopedLock lock(m_mutex); 242 Status error; 243 244 StateType private_state = GetPrivateState(); 245 if (private_state == eStateStopped || private_state == eStateCrashed) { 246 LLDB_LOG(log, "process {0} is in state {1}. Resuming...", 247 m_session_data->m_debugger->GetProcess().GetProcessId(), 248 GetPrivateState()); 249 250 LLDB_LOG(log, "resuming {0} threads.", m_thread_list.GetSize()); 251 252 bool failed = false; 253 for (uint32_t i = 0; i < m_thread_list.GetSize(); ++i) { 254 auto thread = std::static_pointer_cast<TargetThreadWindows>( 255 m_thread_list.GetThreadAtIndex(i)); 256 Status result = thread->DoResume(); 257 if (result.Fail()) { 258 failed = true; 259 LLDB_LOG( 260 log, 261 "Trying to resume thread at index {0}, but failed with error {1}.", 262 i, result); 263 } 264 } 265 266 if (failed) { 267 error = Status::FromErrorString("ProcessWindows::DoResume failed"); 268 } else { 269 SetPrivateState(eStateRunning); 270 } 271 272 ExceptionRecordSP active_exception = 273 m_session_data->m_debugger->GetActiveException().lock(); 274 if (active_exception) { 275 // Resume the process and continue processing debug events. Mask the 276 // exception so that from the process's view, there is no indication that 277 // anything happened. 278 m_session_data->m_debugger->ContinueAsyncException( 279 ExceptionResult::MaskException); 280 } 281 } else { 282 LLDB_LOG(log, "error: process {0} is in state {1}. Returning...", 283 m_session_data->m_debugger->GetProcess().GetProcessId(), 284 GetPrivateState()); 285 } 286 return error; 287 } 288 289 Status ProcessWindows::DoDestroy() { 290 StateType private_state = GetPrivateState(); 291 return DestroyProcess(private_state); 292 } 293 294 Status ProcessWindows::DoHalt(bool &caused_stop) { 295 StateType state = GetPrivateState(); 296 if (state != eStateStopped) 297 return HaltProcess(caused_stop); 298 caused_stop = false; 299 return Status(); 300 } 301 302 void ProcessWindows::DidLaunch() { 303 ArchSpec arch_spec; 304 DidAttach(arch_spec); 305 } 306 307 void ProcessWindows::DidAttach(ArchSpec &arch_spec) { 308 llvm::sys::ScopedLock lock(m_mutex); 309 310 // The initial stop won't broadcast the state change event, so account for 311 // that here. 312 if (m_session_data && GetPrivateState() == eStateStopped && 313 m_session_data->m_stop_at_entry) 314 RefreshStateAfterStop(); 315 } 316 317 static void 318 DumpAdditionalExceptionInformation(llvm::raw_ostream &stream, 319 const ExceptionRecordSP &exception) { 320 // Decode additional exception information for specific exception types based 321 // on 322 // https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_exception_record 323 324 const int addr_min_width = 2 + 8; // "0x" + 4 address bytes 325 326 const std::vector<ULONG_PTR> &args = exception->GetExceptionArguments(); 327 switch (exception->GetExceptionCode()) { 328 case EXCEPTION_ACCESS_VIOLATION: { 329 if (args.size() < 2) 330 break; 331 332 stream << ": "; 333 const int access_violation_code = args[0]; 334 const lldb::addr_t access_violation_address = args[1]; 335 switch (access_violation_code) { 336 case 0: 337 stream << "Access violation reading"; 338 break; 339 case 1: 340 stream << "Access violation writing"; 341 break; 342 case 8: 343 stream << "User-mode data execution prevention (DEP) violation at"; 344 break; 345 default: 346 stream << "Unknown access violation (code " << access_violation_code 347 << ") at"; 348 break; 349 } 350 stream << " location " 351 << llvm::format_hex(access_violation_address, addr_min_width); 352 break; 353 } 354 case EXCEPTION_IN_PAGE_ERROR: { 355 if (args.size() < 3) 356 break; 357 358 stream << ": "; 359 const int page_load_error_code = args[0]; 360 const lldb::addr_t page_load_error_address = args[1]; 361 const DWORD underlying_code = args[2]; 362 switch (page_load_error_code) { 363 case 0: 364 stream << "In page error reading"; 365 break; 366 case 1: 367 stream << "In page error writing"; 368 break; 369 case 8: 370 stream << "User-mode data execution prevention (DEP) violation at"; 371 break; 372 default: 373 stream << "Unknown page loading error (code " << page_load_error_code 374 << ") at"; 375 break; 376 } 377 stream << " location " 378 << llvm::format_hex(page_load_error_address, addr_min_width) 379 << " (status code " << llvm::format_hex(underlying_code, 8) << ")"; 380 break; 381 } 382 } 383 } 384 385 void ProcessWindows::RefreshStateAfterStop() { 386 Log *log = GetLog(WindowsLog::Exception); 387 llvm::sys::ScopedLock lock(m_mutex); 388 389 if (!m_session_data) { 390 LLDB_LOG(log, "no active session. Returning..."); 391 return; 392 } 393 394 m_thread_list.RefreshStateAfterStop(); 395 396 std::weak_ptr<ExceptionRecord> exception_record = 397 m_session_data->m_debugger->GetActiveException(); 398 ExceptionRecordSP active_exception = exception_record.lock(); 399 if (!active_exception) { 400 LLDB_LOG(log, 401 "there is no active exception in process {0}. Why is the " 402 "process stopped?", 403 m_session_data->m_debugger->GetProcess().GetProcessId()); 404 return; 405 } 406 407 StopInfoSP stop_info; 408 m_thread_list.SetSelectedThreadByID(active_exception->GetThreadID()); 409 ThreadSP stop_thread = m_thread_list.GetSelectedThread(); 410 if (!stop_thread) 411 return; 412 413 switch (active_exception->GetExceptionCode()) { 414 case EXCEPTION_SINGLE_STEP: { 415 RegisterContextSP register_context = stop_thread->GetRegisterContext(); 416 const uint64_t pc = register_context->GetPC(); 417 BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc)); 418 if (site && site->ValidForThisThread(*stop_thread)) { 419 LLDB_LOG(log, 420 "Single-stepped onto a breakpoint in process {0} at " 421 "address {1:x} with breakpoint site {2}", 422 m_session_data->m_debugger->GetProcess().GetProcessId(), pc, 423 site->GetID()); 424 stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*stop_thread, 425 site->GetID()); 426 stop_thread->SetStopInfo(stop_info); 427 428 return; 429 } 430 431 auto *reg_ctx = static_cast<RegisterContextWindows *>( 432 stop_thread->GetRegisterContext().get()); 433 uint32_t slot_id = reg_ctx->GetTriggeredHardwareBreakpointSlotId(); 434 if (slot_id != LLDB_INVALID_INDEX32) { 435 int id = m_watchpoint_ids[slot_id]; 436 LLDB_LOG(log, 437 "Single-stepped onto a watchpoint in process {0} at address " 438 "{1:x} with watchpoint {2}", 439 m_session_data->m_debugger->GetProcess().GetProcessId(), pc, id); 440 441 stop_info = StopInfo::CreateStopReasonWithWatchpointID(*stop_thread, id); 442 stop_thread->SetStopInfo(stop_info); 443 444 return; 445 } 446 447 LLDB_LOG(log, "single stepping thread {0}", stop_thread->GetID()); 448 stop_info = StopInfo::CreateStopReasonToTrace(*stop_thread); 449 stop_thread->SetStopInfo(stop_info); 450 451 return; 452 } 453 454 case EXCEPTION_BREAKPOINT: { 455 RegisterContextSP register_context = stop_thread->GetRegisterContext(); 456 457 int breakpoint_size = 1; 458 switch (GetTarget().GetArchitecture().GetMachine()) { 459 case llvm::Triple::aarch64: 460 breakpoint_size = 4; 461 break; 462 463 case llvm::Triple::arm: 464 case llvm::Triple::thumb: 465 breakpoint_size = 2; 466 break; 467 468 case llvm::Triple::x86: 469 case llvm::Triple::x86_64: 470 breakpoint_size = 1; 471 break; 472 473 default: 474 LLDB_LOG(log, "Unknown breakpoint size for architecture"); 475 break; 476 } 477 478 // The current PC is AFTER the BP opcode, on all architectures. 479 uint64_t pc = register_context->GetPC() - breakpoint_size; 480 481 BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc)); 482 if (site) { 483 LLDB_LOG(log, 484 "detected breakpoint in process {0} at address {1:x} with " 485 "breakpoint site {2}", 486 m_session_data->m_debugger->GetProcess().GetProcessId(), pc, 487 site->GetID()); 488 489 if (site->ValidForThisThread(*stop_thread)) { 490 LLDB_LOG(log, 491 "Breakpoint site {0} is valid for this thread ({1:x}), " 492 "creating stop info.", 493 site->GetID(), stop_thread->GetID()); 494 495 stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID( 496 *stop_thread, site->GetID()); 497 register_context->SetPC(pc); 498 } else { 499 LLDB_LOG(log, 500 "Breakpoint site {0} is not valid for this thread, " 501 "creating empty stop info.", 502 site->GetID()); 503 } 504 stop_thread->SetStopInfo(stop_info); 505 return; 506 } else { 507 // The thread hit a hard-coded breakpoint like an `int 3` or 508 // `__debugbreak()`. 509 LLDB_LOG(log, 510 "No breakpoint site matches for this thread. __debugbreak()? " 511 "Creating stop info with the exception."); 512 // FALLTHROUGH: We'll treat this as a generic exception record in the 513 // default case. 514 [[fallthrough]]; 515 } 516 } 517 518 default: { 519 std::string desc; 520 llvm::raw_string_ostream desc_stream(desc); 521 desc_stream << "Exception " 522 << llvm::format_hex(active_exception->GetExceptionCode(), 8) 523 << " encountered at address " 524 << llvm::format_hex(active_exception->GetExceptionAddress(), 8); 525 DumpAdditionalExceptionInformation(desc_stream, active_exception); 526 527 stop_info = 528 StopInfo::CreateStopReasonWithException(*stop_thread, desc.c_str()); 529 stop_thread->SetStopInfo(stop_info); 530 LLDB_LOG(log, "{0}", desc); 531 return; 532 } 533 } 534 } 535 536 bool ProcessWindows::CanDebug(lldb::TargetSP target_sp, 537 bool plugin_specified_by_name) { 538 if (plugin_specified_by_name) 539 return true; 540 541 // For now we are just making sure the file exists for a given module 542 ModuleSP exe_module_sp(target_sp->GetExecutableModule()); 543 if (exe_module_sp.get()) 544 return FileSystem::Instance().Exists(exe_module_sp->GetFileSpec()); 545 // However, if there is no executable module, we return true since we might 546 // be preparing to attach. 547 return true; 548 } 549 550 bool ProcessWindows::DoUpdateThreadList(ThreadList &old_thread_list, 551 ThreadList &new_thread_list) { 552 Log *log = GetLog(WindowsLog::Thread); 553 // Add all the threads that were previously running and for which we did not 554 // detect a thread exited event. 555 int new_size = 0; 556 int continued_threads = 0; 557 int exited_threads = 0; 558 int new_threads = 0; 559 560 for (ThreadSP old_thread : old_thread_list.Threads()) { 561 lldb::tid_t old_thread_id = old_thread->GetID(); 562 auto exited_thread_iter = 563 m_session_data->m_exited_threads.find(old_thread_id); 564 if (exited_thread_iter == m_session_data->m_exited_threads.end()) { 565 new_thread_list.AddThread(old_thread); 566 ++new_size; 567 ++continued_threads; 568 LLDB_LOGV(log, "Thread {0} was running and is still running.", 569 old_thread_id); 570 } else { 571 LLDB_LOGV(log, "Thread {0} was running and has exited.", old_thread_id); 572 ++exited_threads; 573 } 574 } 575 576 // Also add all the threads that are new since the last time we broke into 577 // the debugger. 578 for (const auto &thread_info : m_session_data->m_new_threads) { 579 new_thread_list.AddThread(thread_info.second); 580 ++new_size; 581 ++new_threads; 582 LLDB_LOGV(log, "Thread {0} is new since last update.", thread_info.first); 583 } 584 585 LLDB_LOG(log, "{0} new threads, {1} old threads, {2} exited threads.", 586 new_threads, continued_threads, exited_threads); 587 588 m_session_data->m_new_threads.clear(); 589 m_session_data->m_exited_threads.clear(); 590 591 return new_size > 0; 592 } 593 594 bool ProcessWindows::IsAlive() { 595 StateType state = GetPrivateState(); 596 switch (state) { 597 case eStateCrashed: 598 case eStateDetached: 599 case eStateUnloaded: 600 case eStateExited: 601 case eStateInvalid: 602 return false; 603 default: 604 return true; 605 } 606 } 607 608 ArchSpec ProcessWindows::GetSystemArchitecture() { 609 return HostInfo::GetArchitecture(); 610 } 611 612 size_t ProcessWindows::DoReadMemory(lldb::addr_t vm_addr, void *buf, 613 size_t size, Status &error) { 614 size_t bytes_read = 0; 615 error = ProcessDebugger::ReadMemory(vm_addr, buf, size, bytes_read); 616 return bytes_read; 617 } 618 619 size_t ProcessWindows::DoWriteMemory(lldb::addr_t vm_addr, const void *buf, 620 size_t size, Status &error) { 621 size_t bytes_written = 0; 622 error = ProcessDebugger::WriteMemory(vm_addr, buf, size, bytes_written); 623 return bytes_written; 624 } 625 626 lldb::addr_t ProcessWindows::DoAllocateMemory(size_t size, uint32_t permissions, 627 Status &error) { 628 lldb::addr_t vm_addr = LLDB_INVALID_ADDRESS; 629 error = ProcessDebugger::AllocateMemory(size, permissions, vm_addr); 630 return vm_addr; 631 } 632 633 Status ProcessWindows::DoDeallocateMemory(lldb::addr_t ptr) { 634 return ProcessDebugger::DeallocateMemory(ptr); 635 } 636 637 Status ProcessWindows::DoGetMemoryRegionInfo(lldb::addr_t vm_addr, 638 MemoryRegionInfo &info) { 639 return ProcessDebugger::GetMemoryRegionInfo(vm_addr, info); 640 } 641 642 lldb::addr_t ProcessWindows::GetImageInfoAddress() { 643 Target &target = GetTarget(); 644 ObjectFile *obj_file = target.GetExecutableModule()->GetObjectFile(); 645 Address addr = obj_file->GetImageInfoAddress(&target); 646 if (addr.IsValid()) 647 return addr.GetLoadAddress(&target); 648 else 649 return LLDB_INVALID_ADDRESS; 650 } 651 652 DynamicLoaderWindowsDYLD *ProcessWindows::GetDynamicLoader() { 653 if (m_dyld_up.get() == NULL) 654 m_dyld_up.reset(DynamicLoader::FindPlugin( 655 this, DynamicLoaderWindowsDYLD::GetPluginNameStatic())); 656 return static_cast<DynamicLoaderWindowsDYLD *>(m_dyld_up.get()); 657 } 658 659 void ProcessWindows::OnExitProcess(uint32_t exit_code) { 660 // No need to acquire the lock since m_session_data isn't accessed. 661 Log *log = GetLog(WindowsLog::Process); 662 LLDB_LOG(log, "Process {0} exited with code {1}", GetID(), exit_code); 663 664 TargetSP target = CalculateTarget(); 665 if (target) { 666 ModuleSP executable_module = target->GetExecutableModule(); 667 ModuleList unloaded_modules; 668 unloaded_modules.Append(executable_module); 669 target->ModulesDidUnload(unloaded_modules, true); 670 } 671 672 SetProcessExitStatus(GetID(), true, 0, exit_code); 673 SetPrivateState(eStateExited); 674 675 ProcessDebugger::OnExitProcess(exit_code); 676 } 677 678 void ProcessWindows::OnDebuggerConnected(lldb::addr_t image_base) { 679 DebuggerThreadSP debugger = m_session_data->m_debugger; 680 Log *log = GetLog(WindowsLog::Process); 681 LLDB_LOG(log, "Debugger connected to process {0}. Image base = {1:x}", 682 debugger->GetProcess().GetProcessId(), image_base); 683 684 ModuleSP module; 685 // During attach, we won't have the executable module, so find it now. 686 const DWORD pid = debugger->GetProcess().GetProcessId(); 687 const std::string file_name = GetProcessExecutableName(pid); 688 if (file_name.empty()) { 689 return; 690 } 691 692 FileSpec executable_file(file_name); 693 FileSystem::Instance().Resolve(executable_file); 694 ModuleSpec module_spec(executable_file); 695 Status error; 696 module = 697 GetTarget().GetOrCreateModule(module_spec, true /* notify */, &error); 698 if (!module) { 699 return; 700 } 701 702 GetTarget().SetExecutableModule(module, eLoadDependentsNo); 703 704 if (auto dyld = GetDynamicLoader()) 705 dyld->OnLoadModule(module, ModuleSpec(), image_base); 706 707 // Add the main executable module to the list of pending module loads. We 708 // can't call GetTarget().ModulesDidLoad() here because we still haven't 709 // returned from DoLaunch() / DoAttach() yet so the target may not have set 710 // the process instance to `this` yet. 711 llvm::sys::ScopedLock lock(m_mutex); 712 713 const HostThread &host_main_thread = debugger->GetMainThread(); 714 ThreadSP main_thread = 715 std::make_shared<TargetThreadWindows>(*this, host_main_thread); 716 717 tid_t id = host_main_thread.GetNativeThread().GetThreadId(); 718 main_thread->SetID(id); 719 720 m_session_data->m_new_threads[id] = main_thread; 721 } 722 723 ExceptionResult 724 ProcessWindows::OnDebugException(bool first_chance, 725 const ExceptionRecord &record) { 726 Log *log = GetLog(WindowsLog::Exception); 727 llvm::sys::ScopedLock lock(m_mutex); 728 729 // FIXME: Without this check, occasionally when running the test suite there 730 // is 731 // an issue where m_session_data can be null. It's not clear how this could 732 // happen but it only surfaces while running the test suite. In order to 733 // properly diagnose this, we probably need to first figure allow the test 734 // suite to print out full lldb logs, and then add logging to the process 735 // plugin. 736 if (!m_session_data) { 737 LLDB_LOG(log, 738 "Debugger thread reported exception {0:x} at address {1:x}, " 739 "but there is no session.", 740 record.GetExceptionCode(), record.GetExceptionAddress()); 741 return ExceptionResult::SendToApplication; 742 } 743 744 if (!first_chance) { 745 // Not any second chance exception is an application crash by definition. 746 // It may be an expression evaluation crash. 747 SetPrivateState(eStateStopped); 748 } 749 750 ExceptionResult result = ExceptionResult::SendToApplication; 751 switch (record.GetExceptionCode()) { 752 case EXCEPTION_BREAKPOINT: 753 // Handle breakpoints at the first chance. 754 result = ExceptionResult::BreakInDebugger; 755 756 if (!m_session_data->m_initial_stop_received) { 757 LLDB_LOG( 758 log, 759 "Hit loader breakpoint at address {0:x}, setting initial stop event.", 760 record.GetExceptionAddress()); 761 m_session_data->m_initial_stop_received = true; 762 ::SetEvent(m_session_data->m_initial_stop_event); 763 } else { 764 LLDB_LOG(log, "Hit non-loader breakpoint at address {0:x}.", 765 record.GetExceptionAddress()); 766 } 767 SetPrivateState(eStateStopped); 768 break; 769 case EXCEPTION_SINGLE_STEP: 770 result = ExceptionResult::BreakInDebugger; 771 SetPrivateState(eStateStopped); 772 break; 773 default: 774 LLDB_LOG(log, 775 "Debugger thread reported exception {0:x} at address {1:x} " 776 "(first_chance={2})", 777 record.GetExceptionCode(), record.GetExceptionAddress(), 778 first_chance); 779 // For non-breakpoints, give the application a chance to handle the 780 // exception first. 781 if (first_chance) 782 result = ExceptionResult::SendToApplication; 783 else 784 result = ExceptionResult::BreakInDebugger; 785 } 786 787 return result; 788 } 789 790 void ProcessWindows::OnCreateThread(const HostThread &new_thread) { 791 llvm::sys::ScopedLock lock(m_mutex); 792 793 ThreadSP thread = std::make_shared<TargetThreadWindows>(*this, new_thread); 794 795 const HostNativeThread &native_new_thread = new_thread.GetNativeThread(); 796 tid_t id = native_new_thread.GetThreadId(); 797 thread->SetID(id); 798 799 m_session_data->m_new_threads[id] = thread; 800 801 for (const std::map<int, WatchpointInfo>::value_type &p : m_watchpoints) { 802 auto *reg_ctx = static_cast<RegisterContextWindows *>( 803 thread->GetRegisterContext().get()); 804 reg_ctx->AddHardwareBreakpoint(p.second.slot_id, p.second.address, 805 p.second.size, p.second.read, 806 p.second.write); 807 } 808 } 809 810 void ProcessWindows::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) { 811 llvm::sys::ScopedLock lock(m_mutex); 812 813 // On a forced termination, we may get exit thread events after the session 814 // data has been cleaned up. 815 if (!m_session_data) 816 return; 817 818 // A thread may have started and exited before the debugger stopped allowing a 819 // refresh. 820 // Just remove it from the new threads list in that case. 821 auto iter = m_session_data->m_new_threads.find(thread_id); 822 if (iter != m_session_data->m_new_threads.end()) 823 m_session_data->m_new_threads.erase(iter); 824 else 825 m_session_data->m_exited_threads.insert(thread_id); 826 } 827 828 void ProcessWindows::OnLoadDll(const ModuleSpec &module_spec, 829 lldb::addr_t module_addr) { 830 if (auto dyld = GetDynamicLoader()) 831 dyld->OnLoadModule(nullptr, module_spec, module_addr); 832 } 833 834 void ProcessWindows::OnUnloadDll(lldb::addr_t module_addr) { 835 if (auto dyld = GetDynamicLoader()) 836 dyld->OnUnloadModule(module_addr); 837 } 838 839 void ProcessWindows::OnDebugString(const std::string &string) {} 840 841 void ProcessWindows::OnDebuggerError(const Status &error, uint32_t type) { 842 llvm::sys::ScopedLock lock(m_mutex); 843 Log *log = GetLog(WindowsLog::Process); 844 845 if (m_session_data->m_initial_stop_received) { 846 // This happened while debugging. Do we shutdown the debugging session, 847 // try to continue, or do something else? 848 LLDB_LOG(log, 849 "Error {0} occurred during debugging. Unexpected behavior " 850 "may result. {1}", 851 error.GetError(), error); 852 } else { 853 // If we haven't actually launched the process yet, this was an error 854 // launching the process. Set the internal error and signal the initial 855 // stop event so that the DoLaunch method wakes up and returns a failure. 856 m_session_data->m_launch_error = error.Clone(); 857 ::SetEvent(m_session_data->m_initial_stop_event); 858 LLDB_LOG( 859 log, 860 "Error {0} occurred launching the process before the initial stop. {1}", 861 error.GetError(), error); 862 return; 863 } 864 } 865 866 std::optional<uint32_t> ProcessWindows::GetWatchpointSlotCount() { 867 return RegisterContextWindows::GetNumHardwareBreakpointSlots(); 868 } 869 870 Status ProcessWindows::EnableWatchpoint(WatchpointSP wp_sp, bool notify) { 871 Status error; 872 873 if (wp_sp->IsEnabled()) { 874 wp_sp->SetEnabled(true, notify); 875 return error; 876 } 877 878 WatchpointInfo info; 879 for (info.slot_id = 0; 880 info.slot_id < RegisterContextWindows::GetNumHardwareBreakpointSlots(); 881 info.slot_id++) 882 if (m_watchpoint_ids[info.slot_id] == LLDB_INVALID_BREAK_ID) 883 break; 884 if (info.slot_id == RegisterContextWindows::GetNumHardwareBreakpointSlots()) { 885 error = Status::FromErrorStringWithFormat( 886 "Can't find free slot for watchpoint %i", wp_sp->GetID()); 887 return error; 888 } 889 info.address = wp_sp->GetLoadAddress(); 890 info.size = wp_sp->GetByteSize(); 891 info.read = wp_sp->WatchpointRead(); 892 info.write = wp_sp->WatchpointWrite() || wp_sp->WatchpointModify(); 893 894 for (unsigned i = 0U; i < m_thread_list.GetSize(); i++) { 895 Thread *thread = m_thread_list.GetThreadAtIndex(i).get(); 896 auto *reg_ctx = static_cast<RegisterContextWindows *>( 897 thread->GetRegisterContext().get()); 898 if (!reg_ctx->AddHardwareBreakpoint(info.slot_id, info.address, info.size, 899 info.read, info.write)) { 900 error = Status::FromErrorStringWithFormat( 901 "Can't enable watchpoint %i on thread 0x%llx", wp_sp->GetID(), 902 thread->GetID()); 903 break; 904 } 905 } 906 if (error.Fail()) { 907 for (unsigned i = 0U; i < m_thread_list.GetSize(); i++) { 908 Thread *thread = m_thread_list.GetThreadAtIndex(i).get(); 909 auto *reg_ctx = static_cast<RegisterContextWindows *>( 910 thread->GetRegisterContext().get()); 911 reg_ctx->RemoveHardwareBreakpoint(info.slot_id); 912 } 913 return error; 914 } 915 916 m_watchpoints[wp_sp->GetID()] = info; 917 m_watchpoint_ids[info.slot_id] = wp_sp->GetID(); 918 919 wp_sp->SetEnabled(true, notify); 920 921 return error; 922 } 923 924 Status ProcessWindows::DisableWatchpoint(WatchpointSP wp_sp, bool notify) { 925 Status error; 926 927 if (!wp_sp->IsEnabled()) { 928 wp_sp->SetEnabled(false, notify); 929 return error; 930 } 931 932 auto it = m_watchpoints.find(wp_sp->GetID()); 933 if (it == m_watchpoints.end()) { 934 error = Status::FromErrorStringWithFormat( 935 "Info about watchpoint %i is not found", wp_sp->GetID()); 936 return error; 937 } 938 939 for (unsigned i = 0U; i < m_thread_list.GetSize(); i++) { 940 Thread *thread = m_thread_list.GetThreadAtIndex(i).get(); 941 auto *reg_ctx = static_cast<RegisterContextWindows *>( 942 thread->GetRegisterContext().get()); 943 if (!reg_ctx->RemoveHardwareBreakpoint(it->second.slot_id)) { 944 error = Status::FromErrorStringWithFormat( 945 "Can't disable watchpoint %i on thread 0x%llx", wp_sp->GetID(), 946 thread->GetID()); 947 break; 948 } 949 } 950 if (error.Fail()) 951 return error; 952 953 m_watchpoint_ids[it->second.slot_id] = LLDB_INVALID_BREAK_ID; 954 m_watchpoints.erase(it); 955 956 wp_sp->SetEnabled(false, notify); 957 958 return error; 959 } 960 } // namespace lldb_private 961