ProcessPOSIX.cpp revision 269025
1//===-- ProcessPOSIX.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 "lldb/lldb-python.h" 11 12// C Includes 13#include <errno.h> 14 15// C++ Includes 16// Other libraries and framework includes 17#include "lldb/Breakpoint/Watchpoint.h" 18#include "lldb/Core/Module.h" 19#include "lldb/Core/PluginManager.h" 20#include "lldb/Core/State.h" 21#include "lldb/Host/FileSpec.h" 22#include "lldb/Host/Host.h" 23#include "lldb/Symbol/ObjectFile.h" 24#include "lldb/Target/DynamicLoader.h" 25#include "lldb/Target/Platform.h" 26#include "lldb/Target/Target.h" 27 28#include "ProcessPOSIX.h" 29#include "ProcessPOSIXLog.h" 30#include "Plugins/Process/Utility/InferiorCallPOSIX.h" 31#include "ProcessMonitor.h" 32#include "POSIXThread.h" 33 34using namespace lldb; 35using namespace lldb_private; 36 37//------------------------------------------------------------------------------ 38// Static functions. 39#if 0 40Process* 41ProcessPOSIX::CreateInstance(Target& target, Listener &listener) 42{ 43 return new ProcessPOSIX(target, listener); 44} 45 46 47void 48ProcessPOSIX::Initialize() 49{ 50 static bool g_initialized = false; 51 52 if (!g_initialized) 53 { 54 g_initialized = true; 55 PluginManager::RegisterPlugin(GetPluginNameStatic(), 56 GetPluginDescriptionStatic(), 57 CreateInstance); 58 59 Log::Callbacks log_callbacks = { 60 ProcessPOSIXLog::DisableLog, 61 ProcessPOSIXLog::EnableLog, 62 ProcessPOSIXLog::ListLogCategories 63 }; 64 65 Log::RegisterLogChannel (ProcessPOSIX::GetPluginNameStatic(), log_callbacks); 66 } 67} 68#endif 69 70//------------------------------------------------------------------------------ 71// Constructors and destructors. 72 73ProcessPOSIX::ProcessPOSIX(Target& target, Listener &listener) 74 : Process(target, listener), 75 m_byte_order(lldb::endian::InlHostByteOrder()), 76 m_monitor(NULL), 77 m_module(NULL), 78 m_message_mutex (Mutex::eMutexTypeRecursive), 79 m_exit_now(false), 80 m_seen_initial_stop() 81{ 82 // FIXME: Putting this code in the ctor and saving the byte order in a 83 // member variable is a hack to avoid const qual issues in GetByteOrder. 84 lldb::ModuleSP module = GetTarget().GetExecutableModule(); 85 if (module && module->GetObjectFile()) 86 m_byte_order = module->GetObjectFile()->GetByteOrder(); 87} 88 89ProcessPOSIX::~ProcessPOSIX() 90{ 91 delete m_monitor; 92} 93 94//------------------------------------------------------------------------------ 95// Process protocol. 96void 97ProcessPOSIX::Finalize() 98{ 99 Process::Finalize(); 100 101 if (m_monitor) 102 m_monitor->StopMonitor(); 103} 104 105bool 106ProcessPOSIX::CanDebug(Target &target, bool plugin_specified_by_name) 107{ 108 // For now we are just making sure the file exists for a given module 109 ModuleSP exe_module_sp(target.GetExecutableModule()); 110 if (exe_module_sp.get()) 111 return exe_module_sp->GetFileSpec().Exists(); 112 // If there is no executable module, we return true since we might be preparing to attach. 113 return true; 114} 115 116Error 117ProcessPOSIX::DoAttachToProcessWithID(lldb::pid_t pid) 118{ 119 Error error; 120 assert(m_monitor == NULL); 121 122 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); 123 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) 124 log->Printf ("ProcessPOSIX::%s(pid = %" PRIi64 ")", __FUNCTION__, GetID()); 125 126 m_monitor = new ProcessMonitor(this, pid, error); 127 128 if (!error.Success()) 129 return error; 130 131 PlatformSP platform_sp (m_target.GetPlatform ()); 132 assert (platform_sp.get()); 133 if (!platform_sp) 134 return error; // FIXME: Detatch? 135 136 // Find out what we can about this process 137 ProcessInstanceInfo process_info; 138 platform_sp->GetProcessInfo (pid, process_info); 139 140 // Resolve the executable module 141 ModuleSP exe_module_sp; 142 FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); 143 error = platform_sp->ResolveExecutable(process_info.GetExecutableFile(), 144 m_target.GetArchitecture(), 145 exe_module_sp, 146 executable_search_paths.GetSize() ? &executable_search_paths : NULL); 147 if (!error.Success()) 148 return error; 149 150 // Fix the target architecture if necessary 151 const ArchSpec &module_arch = exe_module_sp->GetArchitecture(); 152 if (module_arch.IsValid() && !m_target.GetArchitecture().IsExactMatch(module_arch)) 153 m_target.SetArchitecture(module_arch); 154 155 // Initialize the target module list 156 m_target.SetExecutableModule (exe_module_sp, true); 157 158 SetSTDIOFileDescriptor(m_monitor->GetTerminalFD()); 159 160 SetID(pid); 161 162 return error; 163} 164 165Error 166ProcessPOSIX::DoAttachToProcessWithID (lldb::pid_t pid, const ProcessAttachInfo &attach_info) 167{ 168 return DoAttachToProcessWithID(pid); 169} 170 171Error 172ProcessPOSIX::WillLaunch(Module* module) 173{ 174 Error error; 175 return error; 176} 177 178const char * 179ProcessPOSIX::GetFilePath( 180 const lldb_private::ProcessLaunchInfo::FileAction *file_action, 181 const char *default_path) 182{ 183 const char *pts_name = "/dev/pts/"; 184 const char *path = NULL; 185 186 if (file_action) 187 { 188 if (file_action->GetAction () == ProcessLaunchInfo::FileAction::eFileActionOpen) 189 path = file_action->GetPath(); 190 // By default the stdio paths passed in will be pseudo-terminal 191 // (/dev/pts). If so, convert to using a different default path 192 // instead to redirect I/O to the debugger console. This should 193 // also handle user overrides to /dev/null or a different file. 194 if (::strncmp(path, pts_name, ::strlen(pts_name)) == 0) 195 path = default_path; 196 } 197 198 return path; 199} 200 201Error 202ProcessPOSIX::DoLaunch (Module *module, 203 ProcessLaunchInfo &launch_info) 204{ 205 Error error; 206 assert(m_monitor == NULL); 207 208 const char* working_dir = launch_info.GetWorkingDirectory(); 209 if (working_dir) { 210 FileSpec WorkingDir(working_dir, true); 211 if (!WorkingDir || WorkingDir.GetFileType() != FileSpec::eFileTypeDirectory) 212 { 213 error.SetErrorStringWithFormat("No such file or directory: %s", working_dir); 214 return error; 215 } 216 } 217 218 SetPrivateState(eStateLaunching); 219 220 const lldb_private::ProcessLaunchInfo::FileAction *file_action; 221 222 // Default of NULL will mean to use existing open file descriptors 223 const char *stdin_path = NULL; 224 const char *stdout_path = NULL; 225 const char *stderr_path = NULL; 226 227 file_action = launch_info.GetFileActionForFD (STDIN_FILENO); 228 stdin_path = GetFilePath(file_action, stdin_path); 229 230 file_action = launch_info.GetFileActionForFD (STDOUT_FILENO); 231 stdout_path = GetFilePath(file_action, stdout_path); 232 233 file_action = launch_info.GetFileActionForFD (STDERR_FILENO); 234 stderr_path = GetFilePath(file_action, stderr_path); 235 236 m_monitor = new ProcessMonitor (this, 237 module, 238 launch_info.GetArguments().GetConstArgumentVector(), 239 launch_info.GetEnvironmentEntries().GetConstArgumentVector(), 240 stdin_path, 241 stdout_path, 242 stderr_path, 243 working_dir, 244 error); 245 246 m_module = module; 247 248 if (!error.Success()) 249 return error; 250 251 SetSTDIOFileDescriptor(m_monitor->GetTerminalFD()); 252 253 SetID(m_monitor->GetPID()); 254 return error; 255} 256 257void 258ProcessPOSIX::DidLaunch() 259{ 260} 261 262Error 263ProcessPOSIX::DoResume() 264{ 265 StateType state = GetPrivateState(); 266 267 assert(state == eStateStopped); 268 269 SetPrivateState(eStateRunning); 270 271 bool did_resume = false; 272 273 Mutex::Locker lock(m_thread_list.GetMutex()); 274 275 uint32_t thread_count = m_thread_list.GetSize(false); 276 for (uint32_t i = 0; i < thread_count; ++i) 277 { 278 POSIXThread *thread = static_cast<POSIXThread*>( 279 m_thread_list.GetThreadAtIndex(i, false).get()); 280 did_resume = thread->Resume() || did_resume; 281 } 282 assert(did_resume && "Process resume failed!"); 283 284 return Error(); 285} 286 287addr_t 288ProcessPOSIX::GetImageInfoAddress() 289{ 290 Target *target = &GetTarget(); 291 ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile(); 292 Address addr = obj_file->GetImageInfoAddress(target); 293 294 if (addr.IsValid()) 295 return addr.GetLoadAddress(target); 296 return LLDB_INVALID_ADDRESS; 297} 298 299Error 300ProcessPOSIX::DoHalt(bool &caused_stop) 301{ 302 Error error; 303 304 if (IsStopped()) 305 { 306 caused_stop = false; 307 } 308 else if (kill(GetID(), SIGSTOP)) 309 { 310 caused_stop = false; 311 error.SetErrorToErrno(); 312 } 313 else 314 { 315 caused_stop = true; 316 } 317 return error; 318} 319 320Error 321ProcessPOSIX::DoSignal(int signal) 322{ 323 Error error; 324 325 if (kill(GetID(), signal)) 326 error.SetErrorToErrno(); 327 328 return error; 329} 330 331Error 332ProcessPOSIX::DoDestroy() 333{ 334 Error error; 335 336 if (!HasExited()) 337 { 338 assert (m_monitor); 339 m_exit_now = true; 340 if (m_monitor->BringProcessIntoLimbo()) 341 { 342 error.SetErrorToErrno(); 343 return error; 344 } 345 346 SetPrivateState(eStateExited); 347 } 348 349 return error; 350} 351 352void 353ProcessPOSIX::DoDidExec() 354{ 355 Target *target = &GetTarget(); 356 if (target) 357 { 358 PlatformSP platform_sp (target->GetPlatform()); 359 assert (platform_sp.get()); 360 if (platform_sp) 361 { 362 ProcessInstanceInfo process_info; 363 platform_sp->GetProcessInfo(GetID(), process_info); 364 ModuleSP exe_module_sp; 365 FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); 366 Error error = platform_sp->ResolveExecutable(process_info.GetExecutableFile(), 367 target->GetArchitecture(), 368 exe_module_sp, 369 executable_search_paths.GetSize() ? &executable_search_paths : NULL); 370 if (!error.Success()) 371 return; 372 target->SetExecutableModule(exe_module_sp, true); 373 } 374 } 375} 376 377void 378ProcessPOSIX::SendMessage(const ProcessMessage &message) 379{ 380 Mutex::Locker lock(m_message_mutex); 381 382 Mutex::Locker thread_lock(m_thread_list.GetMutex()); 383 384 POSIXThread *thread = static_cast<POSIXThread*>( 385 m_thread_list.FindThreadByID(message.GetTID(), false).get()); 386 387 switch (message.GetKind()) 388 { 389 case ProcessMessage::eInvalidMessage: 390 return; 391 392 case ProcessMessage::eAttachMessage: 393 SetPrivateState(eStateStopped); 394 return; 395 396 case ProcessMessage::eLimboMessage: 397 assert(thread); 398 thread->SetState(eStateStopped); 399 if (message.GetTID() == GetID()) 400 { 401 m_exit_status = message.GetExitStatus(); 402 if (m_exit_now) 403 { 404 SetPrivateState(eStateExited); 405 m_monitor->Detach(GetID()); 406 } 407 else 408 { 409 StopAllThreads(message.GetTID()); 410 SetPrivateState(eStateStopped); 411 } 412 } 413 else 414 { 415 StopAllThreads(message.GetTID()); 416 SetPrivateState(eStateStopped); 417 } 418 break; 419 420 case ProcessMessage::eExitMessage: 421 assert(thread); 422 thread->SetState(eStateExited); 423 // FIXME: I'm not sure we need to do this. 424 if (message.GetTID() == GetID()) 425 { 426 m_exit_status = message.GetExitStatus(); 427 SetExitStatus(m_exit_status, NULL); 428 } 429 else if (!IsAThreadRunning()) 430 SetPrivateState(eStateStopped); 431 break; 432 433 case ProcessMessage::eSignalMessage: 434 case ProcessMessage::eSignalDeliveredMessage: 435 if (message.GetSignal() == SIGSTOP && 436 AddThreadForInitialStopIfNeeded(message.GetTID())) 437 return; 438 // Intentional fall-through 439 440 case ProcessMessage::eBreakpointMessage: 441 case ProcessMessage::eTraceMessage: 442 case ProcessMessage::eWatchpointMessage: 443 case ProcessMessage::eCrashMessage: 444 assert(thread); 445 thread->SetState(eStateStopped); 446 StopAllThreads(message.GetTID()); 447 SetPrivateState(eStateStopped); 448 break; 449 450 case ProcessMessage::eNewThreadMessage: 451 { 452 lldb::tid_t new_tid = message.GetChildTID(); 453 if (WaitingForInitialStop(new_tid)) 454 { 455 m_monitor->WaitForInitialTIDStop(new_tid); 456 } 457 assert(thread); 458 thread->SetState(eStateStopped); 459 StopAllThreads(message.GetTID()); 460 SetPrivateState(eStateStopped); 461 break; 462 } 463 464 case ProcessMessage::eExecMessage: 465 { 466 assert(thread); 467 thread->SetState(eStateStopped); 468 StopAllThreads(message.GetTID()); 469 SetPrivateState(eStateStopped); 470 break; 471 } 472 } 473 474 475 m_message_queue.push(message); 476} 477 478void 479ProcessPOSIX::StopAllThreads(lldb::tid_t stop_tid) 480{ 481 // FIXME: Will this work the same way on FreeBSD and Linux? 482} 483 484bool 485ProcessPOSIX::AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid) 486{ 487 bool added_to_set = false; 488 ThreadStopSet::iterator it = m_seen_initial_stop.find(stop_tid); 489 if (it == m_seen_initial_stop.end()) 490 { 491 m_seen_initial_stop.insert(stop_tid); 492 added_to_set = true; 493 } 494 return added_to_set; 495} 496 497bool 498ProcessPOSIX::WaitingForInitialStop(lldb::tid_t stop_tid) 499{ 500 return (m_seen_initial_stop.find(stop_tid) == m_seen_initial_stop.end()); 501} 502 503POSIXThread * 504ProcessPOSIX::CreateNewPOSIXThread(lldb_private::Process &process, lldb::tid_t tid) 505{ 506 return new POSIXThread(process, tid); 507} 508 509void 510ProcessPOSIX::RefreshStateAfterStop() 511{ 512 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); 513 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) 514 log->Printf ("ProcessPOSIX::%s(), message_queue size = %d", __FUNCTION__, (int)m_message_queue.size()); 515 516 Mutex::Locker lock(m_message_mutex); 517 518 // This method used to only handle one message. Changing it to loop allows 519 // it to handle the case where we hit a breakpoint while handling a different 520 // breakpoint. 521 while (!m_message_queue.empty()) 522 { 523 ProcessMessage &message = m_message_queue.front(); 524 525 // Resolve the thread this message corresponds to and pass it along. 526 lldb::tid_t tid = message.GetTID(); 527 if (log) 528 log->Printf ("ProcessPOSIX::%s(), message_queue size = %d, pid = %" PRIi64, __FUNCTION__, (int)m_message_queue.size(), tid); 529 530 if (message.GetKind() == ProcessMessage::eNewThreadMessage) 531 { 532 if (log) 533 log->Printf ("ProcessPOSIX::%s() adding thread, tid = %" PRIi64, __FUNCTION__, message.GetChildTID()); 534 lldb::tid_t child_tid = message.GetChildTID(); 535 ThreadSP thread_sp; 536 thread_sp.reset(CreateNewPOSIXThread(*this, child_tid)); 537 538 Mutex::Locker lock(m_thread_list.GetMutex()); 539 540 m_thread_list.AddThread(thread_sp); 541 } 542 543 m_thread_list.RefreshStateAfterStop(); 544 545 POSIXThread *thread = static_cast<POSIXThread*>( 546 GetThreadList().FindThreadByID(tid, false).get()); 547 if (thread) 548 thread->Notify(message); 549 550 if (message.GetKind() == ProcessMessage::eExitMessage) 551 { 552 // FIXME: We should tell the user about this, but the limbo message is probably better for that. 553 if (log) 554 log->Printf ("ProcessPOSIX::%s() removing thread, tid = %" PRIi64, __FUNCTION__, tid); 555 556 Mutex::Locker lock(m_thread_list.GetMutex()); 557 558 ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false); 559 thread_sp.reset(); 560 m_seen_initial_stop.erase(tid); 561 } 562 563 m_message_queue.pop(); 564 } 565} 566 567bool 568ProcessPOSIX::IsAlive() 569{ 570 StateType state = GetPrivateState(); 571 return state != eStateDetached 572 && state != eStateExited 573 && state != eStateInvalid 574 && state != eStateUnloaded; 575} 576 577size_t 578ProcessPOSIX::DoReadMemory(addr_t vm_addr, 579 void *buf, size_t size, Error &error) 580{ 581 assert(m_monitor); 582 return m_monitor->ReadMemory(vm_addr, buf, size, error); 583} 584 585size_t 586ProcessPOSIX::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size, 587 Error &error) 588{ 589 assert(m_monitor); 590 return m_monitor->WriteMemory(vm_addr, buf, size, error); 591} 592 593addr_t 594ProcessPOSIX::DoAllocateMemory(size_t size, uint32_t permissions, 595 Error &error) 596{ 597 addr_t allocated_addr = LLDB_INVALID_ADDRESS; 598 599 unsigned prot = 0; 600 if (permissions & lldb::ePermissionsReadable) 601 prot |= eMmapProtRead; 602 if (permissions & lldb::ePermissionsWritable) 603 prot |= eMmapProtWrite; 604 if (permissions & lldb::ePermissionsExecutable) 605 prot |= eMmapProtExec; 606 607 if (InferiorCallMmap(this, allocated_addr, 0, size, prot, 608 eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) { 609 m_addr_to_mmap_size[allocated_addr] = size; 610 error.Clear(); 611 } else { 612 allocated_addr = LLDB_INVALID_ADDRESS; 613 error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions)); 614 } 615 616 return allocated_addr; 617} 618 619Error 620ProcessPOSIX::DoDeallocateMemory(lldb::addr_t addr) 621{ 622 Error error; 623 MMapMap::iterator pos = m_addr_to_mmap_size.find(addr); 624 if (pos != m_addr_to_mmap_size.end() && 625 InferiorCallMunmap(this, addr, pos->second)) 626 m_addr_to_mmap_size.erase (pos); 627 else 628 error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr); 629 630 return error; 631} 632 633size_t 634ProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site) 635{ 636 static const uint8_t g_i386_opcode[] = { 0xCC }; 637 638 ArchSpec arch = GetTarget().GetArchitecture(); 639 const uint8_t *opcode = NULL; 640 size_t opcode_size = 0; 641 642 switch (arch.GetCore()) 643 { 644 default: 645 assert(false && "CPU type not supported!"); 646 break; 647 648 case ArchSpec::eCore_x86_32_i386: 649 case ArchSpec::eCore_x86_64_x86_64: 650 opcode = g_i386_opcode; 651 opcode_size = sizeof(g_i386_opcode); 652 break; 653 } 654 655 bp_site->SetTrapOpcode(opcode, opcode_size); 656 return opcode_size; 657} 658 659Error 660ProcessPOSIX::EnableBreakpointSite(BreakpointSite *bp_site) 661{ 662 return EnableSoftwareBreakpoint(bp_site); 663} 664 665Error 666ProcessPOSIX::DisableBreakpointSite(BreakpointSite *bp_site) 667{ 668 return DisableSoftwareBreakpoint(bp_site); 669} 670 671Error 672ProcessPOSIX::EnableWatchpoint(Watchpoint *wp, bool notify) 673{ 674 Error error; 675 if (wp) 676 { 677 user_id_t watchID = wp->GetID(); 678 addr_t addr = wp->GetLoadAddress(); 679 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS)); 680 if (log) 681 log->Printf ("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64 ")", 682 watchID); 683 if (wp->IsEnabled()) 684 { 685 if (log) 686 log->Printf("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64 687 ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.", 688 watchID, (uint64_t)addr); 689 return error; 690 } 691 692 // Try to find a vacant watchpoint slot in the inferiors' main thread 693 uint32_t wp_hw_index = LLDB_INVALID_INDEX32; 694 Mutex::Locker lock(m_thread_list.GetMutex()); 695 POSIXThread *thread = static_cast<POSIXThread*>( 696 m_thread_list.GetThreadAtIndex(0, false).get()); 697 698 if (thread) 699 wp_hw_index = thread->FindVacantWatchpointIndex(); 700 701 if (wp_hw_index == LLDB_INVALID_INDEX32) 702 { 703 error.SetErrorString("Setting hardware watchpoint failed."); 704 } 705 else 706 { 707 wp->SetHardwareIndex(wp_hw_index); 708 bool wp_enabled = true; 709 uint32_t thread_count = m_thread_list.GetSize(false); 710 for (uint32_t i = 0; i < thread_count; ++i) 711 { 712 thread = static_cast<POSIXThread*>( 713 m_thread_list.GetThreadAtIndex(i, false).get()); 714 if (thread) 715 wp_enabled &= thread->EnableHardwareWatchpoint(wp); 716 else 717 wp_enabled = false; 718 } 719 if (wp_enabled) 720 { 721 wp->SetEnabled(true, notify); 722 return error; 723 } 724 else 725 { 726 // Watchpoint enabling failed on at least one 727 // of the threads so roll back all of them 728 DisableWatchpoint(wp, false); 729 error.SetErrorString("Setting hardware watchpoint failed"); 730 } 731 } 732 } 733 else 734 error.SetErrorString("Watchpoint argument was NULL."); 735 return error; 736} 737 738Error 739ProcessPOSIX::DisableWatchpoint(Watchpoint *wp, bool notify) 740{ 741 Error error; 742 if (wp) 743 { 744 user_id_t watchID = wp->GetID(); 745 addr_t addr = wp->GetLoadAddress(); 746 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS)); 747 if (log) 748 log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64 ")", 749 watchID); 750 if (!wp->IsEnabled()) 751 { 752 if (log) 753 log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64 754 ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.", 755 watchID, (uint64_t)addr); 756 // This is needed (for now) to keep watchpoints disabled correctly 757 wp->SetEnabled(false, notify); 758 return error; 759 } 760 761 if (wp->IsHardware()) 762 { 763 bool wp_disabled = true; 764 Mutex::Locker lock(m_thread_list.GetMutex()); 765 uint32_t thread_count = m_thread_list.GetSize(false); 766 for (uint32_t i = 0; i < thread_count; ++i) 767 { 768 POSIXThread *thread = static_cast<POSIXThread*>( 769 m_thread_list.GetThreadAtIndex(i, false).get()); 770 if (thread) 771 wp_disabled &= thread->DisableHardwareWatchpoint(wp); 772 else 773 wp_disabled = false; 774 } 775 if (wp_disabled) 776 { 777 wp->SetHardwareIndex(LLDB_INVALID_INDEX32); 778 wp->SetEnabled(false, notify); 779 return error; 780 } 781 else 782 error.SetErrorString("Disabling hardware watchpoint failed"); 783 } 784 } 785 else 786 error.SetErrorString("Watchpoint argument was NULL."); 787 return error; 788} 789 790Error 791ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num) 792{ 793 Error error; 794 Mutex::Locker lock(m_thread_list.GetMutex()); 795 POSIXThread *thread = static_cast<POSIXThread*>( 796 m_thread_list.GetThreadAtIndex(0, false).get()); 797 if (thread) 798 num = thread->NumSupportedHardwareWatchpoints(); 799 else 800 error.SetErrorString("Process does not exist."); 801 return error; 802} 803 804Error 805ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num, bool &after) 806{ 807 Error error = GetWatchpointSupportInfo(num); 808 // Watchpoints trigger and halt the inferior after 809 // the corresponding instruction has been executed. 810 after = true; 811 return error; 812} 813 814uint32_t 815ProcessPOSIX::UpdateThreadListIfNeeded() 816{ 817 Mutex::Locker lock(m_thread_list.GetMutex()); 818 // Do not allow recursive updates. 819 return m_thread_list.GetSize(false); 820} 821 822bool 823ProcessPOSIX::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) 824{ 825 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); 826 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) 827 log->Printf ("ProcessPOSIX::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID()); 828 829 bool has_updated = false; 830 // Update the process thread list with this new thread. 831 // FIXME: We should be using tid, not pid. 832 assert(m_monitor); 833 ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false)); 834 if (!thread_sp) { 835 thread_sp.reset(CreateNewPOSIXThread(*this, GetID())); 836 has_updated = true; 837 } 838 839 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) 840 log->Printf ("ProcessPOSIX::%s() updated pid = %" PRIi64, __FUNCTION__, GetID()); 841 new_thread_list.AddThread(thread_sp); 842 843 return has_updated; // the list has been updated 844} 845 846ByteOrder 847ProcessPOSIX::GetByteOrder() const 848{ 849 // FIXME: We should be able to extract this value directly. See comment in 850 // ProcessPOSIX(). 851 return m_byte_order; 852} 853 854size_t 855ProcessPOSIX::PutSTDIN(const char *buf, size_t len, Error &error) 856{ 857 ssize_t status; 858 if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0) 859 { 860 error.SetErrorToErrno(); 861 return 0; 862 } 863 return status; 864} 865 866UnixSignals & 867ProcessPOSIX::GetUnixSignals() 868{ 869 return m_signals; 870} 871 872//------------------------------------------------------------------------------ 873// Utility functions. 874 875bool 876ProcessPOSIX::HasExited() 877{ 878 switch (GetPrivateState()) 879 { 880 default: 881 break; 882 883 case eStateDetached: 884 case eStateExited: 885 return true; 886 } 887 888 return false; 889} 890 891bool 892ProcessPOSIX::IsStopped() 893{ 894 switch (GetPrivateState()) 895 { 896 default: 897 break; 898 899 case eStateStopped: 900 case eStateCrashed: 901 case eStateSuspended: 902 return true; 903 } 904 905 return false; 906} 907 908bool 909ProcessPOSIX::IsAThreadRunning() 910{ 911 bool is_running = false; 912 Mutex::Locker lock(m_thread_list.GetMutex()); 913 uint32_t thread_count = m_thread_list.GetSize(false); 914 for (uint32_t i = 0; i < thread_count; ++i) 915 { 916 POSIXThread *thread = static_cast<POSIXThread*>( 917 m_thread_list.GetThreadAtIndex(i, false).get()); 918 StateType thread_state = thread->GetState(); 919 if (thread_state == eStateRunning || thread_state == eStateStepping) 920 { 921 is_running = true; 922 break; 923 } 924 } 925 return is_running; 926} 927