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