1254721Semaste//===-- ProcessPOSIX.cpp ----------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/lldb-python.h" 11254721Semaste 12254721Semaste// C Includes 13254721Semaste#include <errno.h> 14254721Semaste 15254721Semaste// C++ Includes 16254721Semaste// Other libraries and framework includes 17254721Semaste#include "lldb/Breakpoint/Watchpoint.h" 18254721Semaste#include "lldb/Core/Module.h" 19254721Semaste#include "lldb/Core/PluginManager.h" 20254721Semaste#include "lldb/Core/State.h" 21254721Semaste#include "lldb/Host/FileSpec.h" 22254721Semaste#include "lldb/Host/Host.h" 23254721Semaste#include "lldb/Symbol/ObjectFile.h" 24254721Semaste#include "lldb/Target/DynamicLoader.h" 25254721Semaste#include "lldb/Target/Platform.h" 26254721Semaste#include "lldb/Target/Target.h" 27254721Semaste 28254721Semaste#include "ProcessPOSIX.h" 29254721Semaste#include "ProcessPOSIXLog.h" 30254721Semaste#include "Plugins/Process/Utility/InferiorCallPOSIX.h" 31254721Semaste#include "ProcessMonitor.h" 32254721Semaste#include "POSIXThread.h" 33254721Semaste 34254721Semasteusing namespace lldb; 35254721Semasteusing namespace lldb_private; 36254721Semaste 37254721Semaste//------------------------------------------------------------------------------ 38254721Semaste// Static functions. 39254721Semaste#if 0 40254721SemasteProcess* 41254721SemasteProcessPOSIX::CreateInstance(Target& target, Listener &listener) 42254721Semaste{ 43254721Semaste return new ProcessPOSIX(target, listener); 44254721Semaste} 45254721Semaste 46254721Semaste 47254721Semastevoid 48254721SemasteProcessPOSIX::Initialize() 49254721Semaste{ 50254721Semaste static bool g_initialized = false; 51254721Semaste 52254721Semaste if (!g_initialized) 53254721Semaste { 54254721Semaste g_initialized = true; 55254721Semaste PluginManager::RegisterPlugin(GetPluginNameStatic(), 56254721Semaste GetPluginDescriptionStatic(), 57254721Semaste CreateInstance); 58254721Semaste 59254721Semaste Log::Callbacks log_callbacks = { 60254721Semaste ProcessPOSIXLog::DisableLog, 61254721Semaste ProcessPOSIXLog::EnableLog, 62254721Semaste ProcessPOSIXLog::ListLogCategories 63254721Semaste }; 64254721Semaste 65254721Semaste Log::RegisterLogChannel (ProcessPOSIX::GetPluginNameStatic(), log_callbacks); 66254721Semaste } 67254721Semaste} 68254721Semaste#endif 69254721Semaste 70254721Semaste//------------------------------------------------------------------------------ 71254721Semaste// Constructors and destructors. 72254721Semaste 73254721SemasteProcessPOSIX::ProcessPOSIX(Target& target, Listener &listener) 74254721Semaste : Process(target, listener), 75254721Semaste m_byte_order(lldb::endian::InlHostByteOrder()), 76254721Semaste m_monitor(NULL), 77254721Semaste m_module(NULL), 78254721Semaste m_message_mutex (Mutex::eMutexTypeRecursive), 79254721Semaste m_exit_now(false), 80254721Semaste m_seen_initial_stop() 81254721Semaste{ 82254721Semaste // FIXME: Putting this code in the ctor and saving the byte order in a 83254721Semaste // member variable is a hack to avoid const qual issues in GetByteOrder. 84254721Semaste lldb::ModuleSP module = GetTarget().GetExecutableModule(); 85254721Semaste if (module && module->GetObjectFile()) 86254721Semaste m_byte_order = module->GetObjectFile()->GetByteOrder(); 87254721Semaste} 88254721Semaste 89254721SemasteProcessPOSIX::~ProcessPOSIX() 90254721Semaste{ 91254721Semaste delete m_monitor; 92254721Semaste} 93254721Semaste 94254721Semaste//------------------------------------------------------------------------------ 95254721Semaste// Process protocol. 96254721Semastevoid 97254721SemasteProcessPOSIX::Finalize() 98254721Semaste{ 99254721Semaste Process::Finalize(); 100254721Semaste 101254721Semaste if (m_monitor) 102254721Semaste m_monitor->StopMonitor(); 103254721Semaste} 104254721Semaste 105254721Semastebool 106254721SemasteProcessPOSIX::CanDebug(Target &target, bool plugin_specified_by_name) 107254721Semaste{ 108254721Semaste // For now we are just making sure the file exists for a given module 109254721Semaste ModuleSP exe_module_sp(target.GetExecutableModule()); 110254721Semaste if (exe_module_sp.get()) 111254721Semaste return exe_module_sp->GetFileSpec().Exists(); 112254721Semaste // If there is no executable module, we return true since we might be preparing to attach. 113254721Semaste return true; 114254721Semaste} 115254721Semaste 116254721SemasteError 117254721SemasteProcessPOSIX::DoAttachToProcessWithID(lldb::pid_t pid) 118254721Semaste{ 119254721Semaste Error error; 120254721Semaste assert(m_monitor == NULL); 121254721Semaste 122254721Semaste Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); 123254721Semaste if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) 124254721Semaste log->Printf ("ProcessPOSIX::%s(pid = %" PRIi64 ")", __FUNCTION__, GetID()); 125254721Semaste 126254721Semaste m_monitor = new ProcessMonitor(this, pid, error); 127254721Semaste 128254721Semaste if (!error.Success()) 129254721Semaste return error; 130254721Semaste 131254721Semaste PlatformSP platform_sp (m_target.GetPlatform ()); 132254721Semaste assert (platform_sp.get()); 133254721Semaste if (!platform_sp) 134254721Semaste return error; // FIXME: Detatch? 135254721Semaste 136254721Semaste // Find out what we can about this process 137254721Semaste ProcessInstanceInfo process_info; 138254721Semaste platform_sp->GetProcessInfo (pid, process_info); 139254721Semaste 140254721Semaste // Resolve the executable module 141254721Semaste ModuleSP exe_module_sp; 142254721Semaste FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); 143254721Semaste error = platform_sp->ResolveExecutable(process_info.GetExecutableFile(), 144254721Semaste m_target.GetArchitecture(), 145254721Semaste exe_module_sp, 146254721Semaste executable_search_paths.GetSize() ? &executable_search_paths : NULL); 147254721Semaste if (!error.Success()) 148254721Semaste return error; 149254721Semaste 150254721Semaste // Fix the target architecture if necessary 151254721Semaste const ArchSpec &module_arch = exe_module_sp->GetArchitecture(); 152254721Semaste if (module_arch.IsValid() && !m_target.GetArchitecture().IsExactMatch(module_arch)) 153254721Semaste m_target.SetArchitecture(module_arch); 154254721Semaste 155254721Semaste // Initialize the target module list 156254721Semaste m_target.SetExecutableModule (exe_module_sp, true); 157254721Semaste 158254721Semaste SetSTDIOFileDescriptor(m_monitor->GetTerminalFD()); 159254721Semaste 160254721Semaste SetID(pid); 161254721Semaste 162254721Semaste return error; 163254721Semaste} 164254721Semaste 165254721SemasteError 166254721SemasteProcessPOSIX::DoAttachToProcessWithID (lldb::pid_t pid, const ProcessAttachInfo &attach_info) 167254721Semaste{ 168254721Semaste return DoAttachToProcessWithID(pid); 169254721Semaste} 170254721Semaste 171254721SemasteError 172254721SemasteProcessPOSIX::WillLaunch(Module* module) 173254721Semaste{ 174254721Semaste Error error; 175254721Semaste return error; 176254721Semaste} 177254721Semaste 178254721Semasteconst char * 179254721SemasteProcessPOSIX::GetFilePath( 180254721Semaste const lldb_private::ProcessLaunchInfo::FileAction *file_action, 181254721Semaste const char *default_path) 182254721Semaste{ 183254721Semaste const char *pts_name = "/dev/pts/"; 184254721Semaste const char *path = NULL; 185254721Semaste 186254721Semaste if (file_action) 187254721Semaste { 188254721Semaste if (file_action->GetAction () == ProcessLaunchInfo::FileAction::eFileActionOpen) 189254721Semaste path = file_action->GetPath(); 190254721Semaste // By default the stdio paths passed in will be pseudo-terminal 191254721Semaste // (/dev/pts). If so, convert to using a different default path 192254721Semaste // instead to redirect I/O to the debugger console. This should 193254721Semaste // also handle user overrides to /dev/null or a different file. 194254721Semaste if (::strncmp(path, pts_name, ::strlen(pts_name)) == 0) 195254721Semaste path = default_path; 196254721Semaste } 197254721Semaste 198254721Semaste return path; 199254721Semaste} 200254721Semaste 201254721SemasteError 202254721SemasteProcessPOSIX::DoLaunch (Module *module, 203269024Semaste ProcessLaunchInfo &launch_info) 204254721Semaste{ 205254721Semaste Error error; 206254721Semaste assert(m_monitor == NULL); 207254721Semaste 208254721Semaste const char* working_dir = launch_info.GetWorkingDirectory(); 209254721Semaste if (working_dir) { 210254721Semaste FileSpec WorkingDir(working_dir, true); 211254721Semaste if (!WorkingDir || WorkingDir.GetFileType() != FileSpec::eFileTypeDirectory) 212254721Semaste { 213254721Semaste error.SetErrorStringWithFormat("No such file or directory: %s", working_dir); 214254721Semaste return error; 215254721Semaste } 216254721Semaste } 217254721Semaste 218254721Semaste SetPrivateState(eStateLaunching); 219254721Semaste 220254721Semaste const lldb_private::ProcessLaunchInfo::FileAction *file_action; 221254721Semaste 222254721Semaste // Default of NULL will mean to use existing open file descriptors 223254721Semaste const char *stdin_path = NULL; 224254721Semaste const char *stdout_path = NULL; 225254721Semaste const char *stderr_path = NULL; 226254721Semaste 227254721Semaste file_action = launch_info.GetFileActionForFD (STDIN_FILENO); 228254721Semaste stdin_path = GetFilePath(file_action, stdin_path); 229254721Semaste 230254721Semaste file_action = launch_info.GetFileActionForFD (STDOUT_FILENO); 231254721Semaste stdout_path = GetFilePath(file_action, stdout_path); 232254721Semaste 233254721Semaste file_action = launch_info.GetFileActionForFD (STDERR_FILENO); 234254721Semaste stderr_path = GetFilePath(file_action, stderr_path); 235254721Semaste 236254721Semaste m_monitor = new ProcessMonitor (this, 237254721Semaste module, 238254721Semaste launch_info.GetArguments().GetConstArgumentVector(), 239254721Semaste launch_info.GetEnvironmentEntries().GetConstArgumentVector(), 240254721Semaste stdin_path, 241254721Semaste stdout_path, 242254721Semaste stderr_path, 243254721Semaste working_dir, 244254721Semaste error); 245254721Semaste 246254721Semaste m_module = module; 247254721Semaste 248254721Semaste if (!error.Success()) 249254721Semaste return error; 250254721Semaste 251254721Semaste SetSTDIOFileDescriptor(m_monitor->GetTerminalFD()); 252254721Semaste 253254721Semaste SetID(m_monitor->GetPID()); 254254721Semaste return error; 255254721Semaste} 256254721Semaste 257254721Semastevoid 258254721SemasteProcessPOSIX::DidLaunch() 259254721Semaste{ 260254721Semaste} 261254721Semaste 262269024SemasteError 263269024SemasteProcessPOSIX::DoResume() 264269024Semaste{ 265269024Semaste StateType state = GetPrivateState(); 266269024Semaste 267269024Semaste assert(state == eStateStopped); 268269024Semaste 269269024Semaste SetPrivateState(eStateRunning); 270269024Semaste 271269024Semaste bool did_resume = false; 272269024Semaste 273269024Semaste Mutex::Locker lock(m_thread_list.GetMutex()); 274269024Semaste 275269024Semaste uint32_t thread_count = m_thread_list.GetSize(false); 276269024Semaste for (uint32_t i = 0; i < thread_count; ++i) 277269024Semaste { 278269024Semaste POSIXThread *thread = static_cast<POSIXThread*>( 279269024Semaste m_thread_list.GetThreadAtIndex(i, false).get()); 280269024Semaste did_resume = thread->Resume() || did_resume; 281269024Semaste } 282269024Semaste assert(did_resume && "Process resume failed!"); 283269024Semaste 284269024Semaste return Error(); 285269024Semaste} 286269024Semaste 287254721Semasteaddr_t 288254721SemasteProcessPOSIX::GetImageInfoAddress() 289254721Semaste{ 290254721Semaste Target *target = &GetTarget(); 291254721Semaste ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile(); 292263363Semaste Address addr = obj_file->GetImageInfoAddress(target); 293254721Semaste 294263363Semaste if (addr.IsValid()) 295254721Semaste return addr.GetLoadAddress(target); 296263363Semaste return LLDB_INVALID_ADDRESS; 297254721Semaste} 298254721Semaste 299254721SemasteError 300254721SemasteProcessPOSIX::DoHalt(bool &caused_stop) 301254721Semaste{ 302254721Semaste Error error; 303254721Semaste 304254721Semaste if (IsStopped()) 305254721Semaste { 306254721Semaste caused_stop = false; 307254721Semaste } 308254721Semaste else if (kill(GetID(), SIGSTOP)) 309254721Semaste { 310254721Semaste caused_stop = false; 311254721Semaste error.SetErrorToErrno(); 312254721Semaste } 313254721Semaste else 314254721Semaste { 315254721Semaste caused_stop = true; 316254721Semaste } 317254721Semaste return error; 318254721Semaste} 319254721Semaste 320254721SemasteError 321254721SemasteProcessPOSIX::DoSignal(int signal) 322254721Semaste{ 323254721Semaste Error error; 324254721Semaste 325254721Semaste if (kill(GetID(), signal)) 326254721Semaste error.SetErrorToErrno(); 327254721Semaste 328254721Semaste return error; 329254721Semaste} 330254721Semaste 331254721SemasteError 332254721SemasteProcessPOSIX::DoDestroy() 333254721Semaste{ 334254721Semaste Error error; 335254721Semaste 336254721Semaste if (!HasExited()) 337254721Semaste { 338269025Semaste assert (m_monitor); 339254721Semaste m_exit_now = true; 340269025Semaste if (m_monitor->BringProcessIntoLimbo()) 341254721Semaste { 342254721Semaste error.SetErrorToErrno(); 343254721Semaste return error; 344254721Semaste } 345254721Semaste 346254721Semaste SetPrivateState(eStateExited); 347254721Semaste } 348254721Semaste 349254721Semaste return error; 350254721Semaste} 351254721Semaste 352254721Semastevoid 353263363SemasteProcessPOSIX::DoDidExec() 354263363Semaste{ 355263363Semaste Target *target = &GetTarget(); 356263363Semaste if (target) 357263363Semaste { 358263363Semaste PlatformSP platform_sp (target->GetPlatform()); 359263363Semaste assert (platform_sp.get()); 360263363Semaste if (platform_sp) 361263363Semaste { 362263363Semaste ProcessInstanceInfo process_info; 363263363Semaste platform_sp->GetProcessInfo(GetID(), process_info); 364263363Semaste ModuleSP exe_module_sp; 365263363Semaste FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); 366263363Semaste Error error = platform_sp->ResolveExecutable(process_info.GetExecutableFile(), 367263363Semaste target->GetArchitecture(), 368263363Semaste exe_module_sp, 369263363Semaste executable_search_paths.GetSize() ? &executable_search_paths : NULL); 370263363Semaste if (!error.Success()) 371263363Semaste return; 372263363Semaste target->SetExecutableModule(exe_module_sp, true); 373263363Semaste } 374263363Semaste } 375263363Semaste} 376263363Semaste 377269024Semastevoid 378269024SemasteProcessPOSIX::SendMessage(const ProcessMessage &message) 379269024Semaste{ 380269024Semaste Mutex::Locker lock(m_message_mutex); 381269024Semaste 382269024Semaste Mutex::Locker thread_lock(m_thread_list.GetMutex()); 383269024Semaste 384269024Semaste POSIXThread *thread = static_cast<POSIXThread*>( 385269024Semaste m_thread_list.FindThreadByID(message.GetTID(), false).get()); 386269024Semaste 387269024Semaste switch (message.GetKind()) 388269024Semaste { 389269024Semaste case ProcessMessage::eInvalidMessage: 390269024Semaste return; 391269024Semaste 392269024Semaste case ProcessMessage::eAttachMessage: 393269024Semaste SetPrivateState(eStateStopped); 394269024Semaste return; 395269024Semaste 396269024Semaste case ProcessMessage::eLimboMessage: 397269024Semaste assert(thread); 398269024Semaste thread->SetState(eStateStopped); 399269024Semaste if (message.GetTID() == GetID()) 400269024Semaste { 401269024Semaste m_exit_status = message.GetExitStatus(); 402269024Semaste if (m_exit_now) 403269024Semaste { 404269024Semaste SetPrivateState(eStateExited); 405269024Semaste m_monitor->Detach(GetID()); 406269024Semaste } 407269024Semaste else 408269024Semaste { 409269024Semaste StopAllThreads(message.GetTID()); 410269024Semaste SetPrivateState(eStateStopped); 411269024Semaste } 412269024Semaste } 413269024Semaste else 414269024Semaste { 415269024Semaste StopAllThreads(message.GetTID()); 416269024Semaste SetPrivateState(eStateStopped); 417269024Semaste } 418269024Semaste break; 419269024Semaste 420269024Semaste case ProcessMessage::eExitMessage: 421269024Semaste assert(thread); 422269024Semaste thread->SetState(eStateExited); 423269024Semaste // FIXME: I'm not sure we need to do this. 424269024Semaste if (message.GetTID() == GetID()) 425269024Semaste { 426269024Semaste m_exit_status = message.GetExitStatus(); 427269024Semaste SetExitStatus(m_exit_status, NULL); 428269024Semaste } 429269024Semaste else if (!IsAThreadRunning()) 430269024Semaste SetPrivateState(eStateStopped); 431269024Semaste break; 432269024Semaste 433269024Semaste case ProcessMessage::eSignalMessage: 434269024Semaste case ProcessMessage::eSignalDeliveredMessage: 435269024Semaste if (message.GetSignal() == SIGSTOP && 436269024Semaste AddThreadForInitialStopIfNeeded(message.GetTID())) 437269024Semaste return; 438269024Semaste // Intentional fall-through 439269024Semaste 440269024Semaste case ProcessMessage::eBreakpointMessage: 441269024Semaste case ProcessMessage::eTraceMessage: 442269024Semaste case ProcessMessage::eWatchpointMessage: 443269024Semaste case ProcessMessage::eCrashMessage: 444269024Semaste assert(thread); 445269024Semaste thread->SetState(eStateStopped); 446269024Semaste StopAllThreads(message.GetTID()); 447269024Semaste SetPrivateState(eStateStopped); 448269024Semaste break; 449269024Semaste 450269024Semaste case ProcessMessage::eNewThreadMessage: 451269024Semaste { 452269024Semaste lldb::tid_t new_tid = message.GetChildTID(); 453269024Semaste if (WaitingForInitialStop(new_tid)) 454269024Semaste { 455269024Semaste m_monitor->WaitForInitialTIDStop(new_tid); 456269024Semaste } 457269024Semaste assert(thread); 458269024Semaste thread->SetState(eStateStopped); 459269024Semaste StopAllThreads(message.GetTID()); 460269024Semaste SetPrivateState(eStateStopped); 461269024Semaste break; 462269024Semaste } 463269024Semaste 464269024Semaste case ProcessMessage::eExecMessage: 465269024Semaste { 466269024Semaste assert(thread); 467269024Semaste thread->SetState(eStateStopped); 468269024Semaste StopAllThreads(message.GetTID()); 469269024Semaste SetPrivateState(eStateStopped); 470269024Semaste break; 471269024Semaste } 472269024Semaste } 473269024Semaste 474269024Semaste 475269024Semaste m_message_queue.push(message); 476269024Semaste} 477269024Semaste 478254721Semastevoid 479254721SemasteProcessPOSIX::StopAllThreads(lldb::tid_t stop_tid) 480254721Semaste{ 481254721Semaste // FIXME: Will this work the same way on FreeBSD and Linux? 482254721Semaste} 483254721Semaste 484254721Semastebool 485254721SemasteProcessPOSIX::AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid) 486254721Semaste{ 487254721Semaste bool added_to_set = false; 488254721Semaste ThreadStopSet::iterator it = m_seen_initial_stop.find(stop_tid); 489254721Semaste if (it == m_seen_initial_stop.end()) 490254721Semaste { 491254721Semaste m_seen_initial_stop.insert(stop_tid); 492254721Semaste added_to_set = true; 493254721Semaste } 494254721Semaste return added_to_set; 495254721Semaste} 496254721Semaste 497263363Semastebool 498263363SemasteProcessPOSIX::WaitingForInitialStop(lldb::tid_t stop_tid) 499263363Semaste{ 500263363Semaste return (m_seen_initial_stop.find(stop_tid) == m_seen_initial_stop.end()); 501263363Semaste} 502263363Semaste 503254721SemastePOSIXThread * 504254721SemasteProcessPOSIX::CreateNewPOSIXThread(lldb_private::Process &process, lldb::tid_t tid) 505254721Semaste{ 506254721Semaste return new POSIXThread(process, tid); 507254721Semaste} 508254721Semaste 509254721Semastevoid 510254721SemasteProcessPOSIX::RefreshStateAfterStop() 511254721Semaste{ 512254721Semaste Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); 513254721Semaste if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) 514254721Semaste log->Printf ("ProcessPOSIX::%s(), message_queue size = %d", __FUNCTION__, (int)m_message_queue.size()); 515254721Semaste 516254721Semaste Mutex::Locker lock(m_message_mutex); 517254721Semaste 518254721Semaste // This method used to only handle one message. Changing it to loop allows 519254721Semaste // it to handle the case where we hit a breakpoint while handling a different 520254721Semaste // breakpoint. 521254721Semaste while (!m_message_queue.empty()) 522254721Semaste { 523254721Semaste ProcessMessage &message = m_message_queue.front(); 524254721Semaste 525254721Semaste // Resolve the thread this message corresponds to and pass it along. 526254721Semaste lldb::tid_t tid = message.GetTID(); 527254721Semaste if (log) 528254721Semaste log->Printf ("ProcessPOSIX::%s(), message_queue size = %d, pid = %" PRIi64, __FUNCTION__, (int)m_message_queue.size(), tid); 529254721Semaste 530254721Semaste if (message.GetKind() == ProcessMessage::eNewThreadMessage) 531254721Semaste { 532254721Semaste if (log) 533254721Semaste log->Printf ("ProcessPOSIX::%s() adding thread, tid = %" PRIi64, __FUNCTION__, message.GetChildTID()); 534254721Semaste lldb::tid_t child_tid = message.GetChildTID(); 535254721Semaste ThreadSP thread_sp; 536254721Semaste thread_sp.reset(CreateNewPOSIXThread(*this, child_tid)); 537254721Semaste 538254721Semaste Mutex::Locker lock(m_thread_list.GetMutex()); 539254721Semaste 540254721Semaste m_thread_list.AddThread(thread_sp); 541254721Semaste } 542254721Semaste 543254721Semaste m_thread_list.RefreshStateAfterStop(); 544254721Semaste 545263363Semaste POSIXThread *thread = static_cast<POSIXThread*>( 546263363Semaste GetThreadList().FindThreadByID(tid, false).get()); 547254721Semaste if (thread) 548254721Semaste thread->Notify(message); 549254721Semaste 550254721Semaste if (message.GetKind() == ProcessMessage::eExitMessage) 551254721Semaste { 552254721Semaste // FIXME: We should tell the user about this, but the limbo message is probably better for that. 553254721Semaste if (log) 554254721Semaste log->Printf ("ProcessPOSIX::%s() removing thread, tid = %" PRIi64, __FUNCTION__, tid); 555254721Semaste 556254721Semaste Mutex::Locker lock(m_thread_list.GetMutex()); 557254721Semaste 558254721Semaste ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false); 559254721Semaste thread_sp.reset(); 560254721Semaste m_seen_initial_stop.erase(tid); 561254721Semaste } 562254721Semaste 563254721Semaste m_message_queue.pop(); 564254721Semaste } 565254721Semaste} 566254721Semaste 567254721Semastebool 568254721SemasteProcessPOSIX::IsAlive() 569254721Semaste{ 570254721Semaste StateType state = GetPrivateState(); 571254721Semaste return state != eStateDetached 572254721Semaste && state != eStateExited 573254721Semaste && state != eStateInvalid 574254721Semaste && state != eStateUnloaded; 575254721Semaste} 576254721Semaste 577254721Semastesize_t 578254721SemasteProcessPOSIX::DoReadMemory(addr_t vm_addr, 579254721Semaste void *buf, size_t size, Error &error) 580254721Semaste{ 581254721Semaste assert(m_monitor); 582254721Semaste return m_monitor->ReadMemory(vm_addr, buf, size, error); 583254721Semaste} 584254721Semaste 585254721Semastesize_t 586254721SemasteProcessPOSIX::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size, 587254721Semaste Error &error) 588254721Semaste{ 589254721Semaste assert(m_monitor); 590254721Semaste return m_monitor->WriteMemory(vm_addr, buf, size, error); 591254721Semaste} 592254721Semaste 593254721Semasteaddr_t 594254721SemasteProcessPOSIX::DoAllocateMemory(size_t size, uint32_t permissions, 595254721Semaste Error &error) 596254721Semaste{ 597254721Semaste addr_t allocated_addr = LLDB_INVALID_ADDRESS; 598254721Semaste 599254721Semaste unsigned prot = 0; 600254721Semaste if (permissions & lldb::ePermissionsReadable) 601254721Semaste prot |= eMmapProtRead; 602254721Semaste if (permissions & lldb::ePermissionsWritable) 603254721Semaste prot |= eMmapProtWrite; 604254721Semaste if (permissions & lldb::ePermissionsExecutable) 605254721Semaste prot |= eMmapProtExec; 606254721Semaste 607254721Semaste if (InferiorCallMmap(this, allocated_addr, 0, size, prot, 608254721Semaste eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) { 609254721Semaste m_addr_to_mmap_size[allocated_addr] = size; 610254721Semaste error.Clear(); 611254721Semaste } else { 612254721Semaste allocated_addr = LLDB_INVALID_ADDRESS; 613254721Semaste error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions)); 614254721Semaste } 615254721Semaste 616254721Semaste return allocated_addr; 617254721Semaste} 618254721Semaste 619254721SemasteError 620254721SemasteProcessPOSIX::DoDeallocateMemory(lldb::addr_t addr) 621254721Semaste{ 622254721Semaste Error error; 623254721Semaste MMapMap::iterator pos = m_addr_to_mmap_size.find(addr); 624254721Semaste if (pos != m_addr_to_mmap_size.end() && 625254721Semaste InferiorCallMunmap(this, addr, pos->second)) 626254721Semaste m_addr_to_mmap_size.erase (pos); 627254721Semaste else 628254721Semaste error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr); 629254721Semaste 630254721Semaste return error; 631254721Semaste} 632254721Semaste 633254721Semastesize_t 634254721SemasteProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site) 635254721Semaste{ 636254721Semaste static const uint8_t g_i386_opcode[] = { 0xCC }; 637254721Semaste 638254721Semaste ArchSpec arch = GetTarget().GetArchitecture(); 639254721Semaste const uint8_t *opcode = NULL; 640254721Semaste size_t opcode_size = 0; 641254721Semaste 642254721Semaste switch (arch.GetCore()) 643254721Semaste { 644254721Semaste default: 645254721Semaste assert(false && "CPU type not supported!"); 646254721Semaste break; 647254721Semaste 648254721Semaste case ArchSpec::eCore_x86_32_i386: 649254721Semaste case ArchSpec::eCore_x86_64_x86_64: 650254721Semaste opcode = g_i386_opcode; 651254721Semaste opcode_size = sizeof(g_i386_opcode); 652254721Semaste break; 653254721Semaste } 654254721Semaste 655254721Semaste bp_site->SetTrapOpcode(opcode, opcode_size); 656254721Semaste return opcode_size; 657254721Semaste} 658254721Semaste 659254721SemasteError 660254721SemasteProcessPOSIX::EnableBreakpointSite(BreakpointSite *bp_site) 661254721Semaste{ 662254721Semaste return EnableSoftwareBreakpoint(bp_site); 663254721Semaste} 664254721Semaste 665254721SemasteError 666254721SemasteProcessPOSIX::DisableBreakpointSite(BreakpointSite *bp_site) 667254721Semaste{ 668254721Semaste return DisableSoftwareBreakpoint(bp_site); 669254721Semaste} 670254721Semaste 671254721SemasteError 672254721SemasteProcessPOSIX::EnableWatchpoint(Watchpoint *wp, bool notify) 673254721Semaste{ 674254721Semaste Error error; 675254721Semaste if (wp) 676254721Semaste { 677254721Semaste user_id_t watchID = wp->GetID(); 678254721Semaste addr_t addr = wp->GetLoadAddress(); 679254721Semaste Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS)); 680254721Semaste if (log) 681254721Semaste log->Printf ("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64 ")", 682254721Semaste watchID); 683254721Semaste if (wp->IsEnabled()) 684254721Semaste { 685254721Semaste if (log) 686254721Semaste log->Printf("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64 687254721Semaste ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.", 688254721Semaste watchID, (uint64_t)addr); 689254721Semaste return error; 690254721Semaste } 691254721Semaste 692254721Semaste // Try to find a vacant watchpoint slot in the inferiors' main thread 693254721Semaste uint32_t wp_hw_index = LLDB_INVALID_INDEX32; 694254721Semaste Mutex::Locker lock(m_thread_list.GetMutex()); 695254721Semaste POSIXThread *thread = static_cast<POSIXThread*>( 696254721Semaste m_thread_list.GetThreadAtIndex(0, false).get()); 697254721Semaste 698254721Semaste if (thread) 699254721Semaste wp_hw_index = thread->FindVacantWatchpointIndex(); 700254721Semaste 701254721Semaste if (wp_hw_index == LLDB_INVALID_INDEX32) 702254721Semaste { 703254721Semaste error.SetErrorString("Setting hardware watchpoint failed."); 704254721Semaste } 705254721Semaste else 706254721Semaste { 707254721Semaste wp->SetHardwareIndex(wp_hw_index); 708254721Semaste bool wp_enabled = true; 709254721Semaste uint32_t thread_count = m_thread_list.GetSize(false); 710254721Semaste for (uint32_t i = 0; i < thread_count; ++i) 711254721Semaste { 712254721Semaste thread = static_cast<POSIXThread*>( 713254721Semaste m_thread_list.GetThreadAtIndex(i, false).get()); 714254721Semaste if (thread) 715254721Semaste wp_enabled &= thread->EnableHardwareWatchpoint(wp); 716254721Semaste else 717254721Semaste wp_enabled = false; 718254721Semaste } 719254721Semaste if (wp_enabled) 720254721Semaste { 721254721Semaste wp->SetEnabled(true, notify); 722254721Semaste return error; 723254721Semaste } 724254721Semaste else 725254721Semaste { 726254721Semaste // Watchpoint enabling failed on at least one 727254721Semaste // of the threads so roll back all of them 728254721Semaste DisableWatchpoint(wp, false); 729254721Semaste error.SetErrorString("Setting hardware watchpoint failed"); 730254721Semaste } 731254721Semaste } 732254721Semaste } 733254721Semaste else 734254721Semaste error.SetErrorString("Watchpoint argument was NULL."); 735254721Semaste return error; 736254721Semaste} 737254721Semaste 738254721SemasteError 739254721SemasteProcessPOSIX::DisableWatchpoint(Watchpoint *wp, bool notify) 740254721Semaste{ 741254721Semaste Error error; 742254721Semaste if (wp) 743254721Semaste { 744254721Semaste user_id_t watchID = wp->GetID(); 745254721Semaste addr_t addr = wp->GetLoadAddress(); 746254721Semaste Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS)); 747254721Semaste if (log) 748254721Semaste log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64 ")", 749254721Semaste watchID); 750254721Semaste if (!wp->IsEnabled()) 751254721Semaste { 752254721Semaste if (log) 753254721Semaste log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64 754254721Semaste ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.", 755254721Semaste watchID, (uint64_t)addr); 756254721Semaste // This is needed (for now) to keep watchpoints disabled correctly 757254721Semaste wp->SetEnabled(false, notify); 758254721Semaste return error; 759254721Semaste } 760254721Semaste 761254721Semaste if (wp->IsHardware()) 762254721Semaste { 763254721Semaste bool wp_disabled = true; 764254721Semaste Mutex::Locker lock(m_thread_list.GetMutex()); 765254721Semaste uint32_t thread_count = m_thread_list.GetSize(false); 766254721Semaste for (uint32_t i = 0; i < thread_count; ++i) 767254721Semaste { 768254721Semaste POSIXThread *thread = static_cast<POSIXThread*>( 769254721Semaste m_thread_list.GetThreadAtIndex(i, false).get()); 770254721Semaste if (thread) 771254721Semaste wp_disabled &= thread->DisableHardwareWatchpoint(wp); 772254721Semaste else 773254721Semaste wp_disabled = false; 774254721Semaste } 775254721Semaste if (wp_disabled) 776254721Semaste { 777254721Semaste wp->SetHardwareIndex(LLDB_INVALID_INDEX32); 778254721Semaste wp->SetEnabled(false, notify); 779254721Semaste return error; 780254721Semaste } 781254721Semaste else 782254721Semaste error.SetErrorString("Disabling hardware watchpoint failed"); 783254721Semaste } 784254721Semaste } 785254721Semaste else 786254721Semaste error.SetErrorString("Watchpoint argument was NULL."); 787254721Semaste return error; 788254721Semaste} 789254721Semaste 790254721SemasteError 791254721SemasteProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num) 792254721Semaste{ 793254721Semaste Error error; 794254721Semaste Mutex::Locker lock(m_thread_list.GetMutex()); 795254721Semaste POSIXThread *thread = static_cast<POSIXThread*>( 796254721Semaste m_thread_list.GetThreadAtIndex(0, false).get()); 797254721Semaste if (thread) 798254721Semaste num = thread->NumSupportedHardwareWatchpoints(); 799254721Semaste else 800254721Semaste error.SetErrorString("Process does not exist."); 801254721Semaste return error; 802254721Semaste} 803254721Semaste 804254721SemasteError 805254721SemasteProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num, bool &after) 806254721Semaste{ 807254721Semaste Error error = GetWatchpointSupportInfo(num); 808254721Semaste // Watchpoints trigger and halt the inferior after 809254721Semaste // the corresponding instruction has been executed. 810254721Semaste after = true; 811254721Semaste return error; 812254721Semaste} 813254721Semaste 814254721Semasteuint32_t 815254721SemasteProcessPOSIX::UpdateThreadListIfNeeded() 816254721Semaste{ 817254721Semaste Mutex::Locker lock(m_thread_list.GetMutex()); 818254721Semaste // Do not allow recursive updates. 819254721Semaste return m_thread_list.GetSize(false); 820254721Semaste} 821254721Semaste 822254721Semastebool 823254721SemasteProcessPOSIX::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) 824254721Semaste{ 825254721Semaste Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); 826254721Semaste if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) 827254721Semaste log->Printf ("ProcessPOSIX::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID()); 828254721Semaste 829263363Semaste bool has_updated = false; 830254721Semaste // Update the process thread list with this new thread. 831254721Semaste // FIXME: We should be using tid, not pid. 832254721Semaste assert(m_monitor); 833254721Semaste ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false)); 834254721Semaste if (!thread_sp) { 835254721Semaste thread_sp.reset(CreateNewPOSIXThread(*this, GetID())); 836263363Semaste has_updated = true; 837254721Semaste } 838254721Semaste 839254721Semaste if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) 840254721Semaste log->Printf ("ProcessPOSIX::%s() updated pid = %" PRIi64, __FUNCTION__, GetID()); 841254721Semaste new_thread_list.AddThread(thread_sp); 842254721Semaste 843263363Semaste return has_updated; // the list has been updated 844254721Semaste} 845254721Semaste 846254721SemasteByteOrder 847254721SemasteProcessPOSIX::GetByteOrder() const 848254721Semaste{ 849254721Semaste // FIXME: We should be able to extract this value directly. See comment in 850254721Semaste // ProcessPOSIX(). 851254721Semaste return m_byte_order; 852254721Semaste} 853254721Semaste 854254721Semastesize_t 855254721SemasteProcessPOSIX::PutSTDIN(const char *buf, size_t len, Error &error) 856254721Semaste{ 857254721Semaste ssize_t status; 858254721Semaste if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0) 859254721Semaste { 860254721Semaste error.SetErrorToErrno(); 861254721Semaste return 0; 862254721Semaste } 863254721Semaste return status; 864254721Semaste} 865254721Semaste 866254721SemasteUnixSignals & 867254721SemasteProcessPOSIX::GetUnixSignals() 868254721Semaste{ 869254721Semaste return m_signals; 870254721Semaste} 871254721Semaste 872254721Semaste//------------------------------------------------------------------------------ 873254721Semaste// Utility functions. 874254721Semaste 875254721Semastebool 876254721SemasteProcessPOSIX::HasExited() 877254721Semaste{ 878254721Semaste switch (GetPrivateState()) 879254721Semaste { 880254721Semaste default: 881254721Semaste break; 882254721Semaste 883254721Semaste case eStateDetached: 884254721Semaste case eStateExited: 885254721Semaste return true; 886254721Semaste } 887254721Semaste 888254721Semaste return false; 889254721Semaste} 890254721Semaste 891254721Semastebool 892254721SemasteProcessPOSIX::IsStopped() 893254721Semaste{ 894254721Semaste switch (GetPrivateState()) 895254721Semaste { 896254721Semaste default: 897254721Semaste break; 898254721Semaste 899254721Semaste case eStateStopped: 900254721Semaste case eStateCrashed: 901254721Semaste case eStateSuspended: 902254721Semaste return true; 903254721Semaste } 904254721Semaste 905254721Semaste return false; 906254721Semaste} 907254721Semaste 908254721Semastebool 909254721SemasteProcessPOSIX::IsAThreadRunning() 910254721Semaste{ 911254721Semaste bool is_running = false; 912254721Semaste Mutex::Locker lock(m_thread_list.GetMutex()); 913254721Semaste uint32_t thread_count = m_thread_list.GetSize(false); 914254721Semaste for (uint32_t i = 0; i < thread_count; ++i) 915254721Semaste { 916254721Semaste POSIXThread *thread = static_cast<POSIXThread*>( 917254721Semaste m_thread_list.GetThreadAtIndex(i, false).get()); 918254721Semaste StateType thread_state = thread->GetState(); 919254721Semaste if (thread_state == eStateRunning || thread_state == eStateStepping) 920254721Semaste { 921254721Semaste is_running = true; 922254721Semaste break; 923254721Semaste } 924254721Semaste } 925254721Semaste return is_running; 926254721Semaste} 927