1af245d11STodd Fiala //===-- NativeProcessProtocol.cpp -------------------------------*- C++ -*-===// 2af245d11STodd Fiala // 3af245d11STodd Fiala // The LLVM Compiler Infrastructure 4af245d11STodd Fiala // 5af245d11STodd Fiala // This file is distributed under the University of Illinois Open Source 6af245d11STodd Fiala // License. See LICENSE.TXT for details. 7af245d11STodd Fiala // 8af245d11STodd Fiala //===----------------------------------------------------------------------===// 9af245d11STodd Fiala 102fe1d0abSChaoren Lin #include "lldb/Host/common/NativeProcessProtocol.h" 11af245d11STodd Fiala 12af245d11STodd Fiala #include "lldb/lldb-enumerations.h" 13af245d11STodd Fiala #include "lldb/Core/ArchSpec.h" 14af245d11STodd Fiala #include "lldb/Core/Log.h" 15af245d11STodd Fiala #include "lldb/Core/State.h" 16511e5cdcSTodd Fiala #include "lldb/Host/Host.h" 172fe1d0abSChaoren Lin #include "lldb/Host/common/NativeRegisterContext.h" 18af245d11STodd Fiala 192fe1d0abSChaoren Lin #include "lldb/Host/common/NativeThreadProtocol.h" 202fe1d0abSChaoren Lin #include "lldb/Host/common/SoftwareBreakpoint.h" 21af245d11STodd Fiala 22af245d11STodd Fiala using namespace lldb; 23af245d11STodd Fiala using namespace lldb_private; 24af245d11STodd Fiala 25af245d11STodd Fiala // ----------------------------------------------------------------------------- 26af245d11STodd Fiala // NativeProcessProtocol Members 27af245d11STodd Fiala // ----------------------------------------------------------------------------- 28af245d11STodd Fiala 29af245d11STodd Fiala NativeProcessProtocol::NativeProcessProtocol (lldb::pid_t pid) : 30af245d11STodd Fiala m_pid (pid), 31af245d11STodd Fiala m_threads (), 32af245d11STodd Fiala m_current_thread_id (LLDB_INVALID_THREAD_ID), 33af245d11STodd Fiala m_threads_mutex (Mutex::eMutexTypeRecursive), 34af245d11STodd Fiala m_state (lldb::eStateInvalid), 35af245d11STodd Fiala m_state_mutex (Mutex::eMutexTypeRecursive), 36af245d11STodd Fiala m_exit_type (eExitTypeInvalid), 37af245d11STodd Fiala m_exit_status (0), 38af245d11STodd Fiala m_exit_description (), 39af245d11STodd Fiala m_delegates_mutex (Mutex::eMutexTypeRecursive), 40af245d11STodd Fiala m_delegates (), 41af245d11STodd Fiala m_breakpoint_list (), 4218fe6404SChaoren Lin m_watchpoint_list (), 43af245d11STodd Fiala m_terminal_fd (-1), 44af245d11STodd Fiala m_stop_id (0) 45af245d11STodd Fiala { 46af245d11STodd Fiala } 47af245d11STodd Fiala 48af245d11STodd Fiala lldb_private::Error 49511e5cdcSTodd Fiala NativeProcessProtocol::Interrupt () 50511e5cdcSTodd Fiala { 51511e5cdcSTodd Fiala Error error; 52511e5cdcSTodd Fiala #if !defined (SIGSTOP) 53511e5cdcSTodd Fiala error.SetErrorString ("local host does not support signaling"); 54511e5cdcSTodd Fiala return error; 55511e5cdcSTodd Fiala #else 56511e5cdcSTodd Fiala return Signal (SIGSTOP); 57511e5cdcSTodd Fiala #endif 58511e5cdcSTodd Fiala } 59511e5cdcSTodd Fiala 60511e5cdcSTodd Fiala lldb_private::Error 61af245d11STodd Fiala NativeProcessProtocol::GetMemoryRegionInfo (lldb::addr_t load_addr, MemoryRegionInfo &range_info) 62af245d11STodd Fiala { 63af245d11STodd Fiala // Default: not implemented. 64af245d11STodd Fiala return Error ("not implemented"); 65af245d11STodd Fiala } 66af245d11STodd Fiala 67af245d11STodd Fiala bool 68af245d11STodd Fiala NativeProcessProtocol::GetExitStatus (ExitType *exit_type, int *status, std::string &exit_description) 69af245d11STodd Fiala { 70af245d11STodd Fiala if (m_state == lldb::eStateExited) 71af245d11STodd Fiala { 72af245d11STodd Fiala *exit_type = m_exit_type; 73af245d11STodd Fiala *status = m_exit_status; 74af245d11STodd Fiala exit_description = m_exit_description; 75af245d11STodd Fiala return true; 76af245d11STodd Fiala } 77af245d11STodd Fiala 78af245d11STodd Fiala *status = 0; 79af245d11STodd Fiala return false; 80af245d11STodd Fiala } 81af245d11STodd Fiala 82af245d11STodd Fiala bool 83af245d11STodd Fiala NativeProcessProtocol::SetExitStatus (ExitType exit_type, int status, const char *exit_description, bool bNotifyStateChange) 84af245d11STodd Fiala { 85af245d11STodd Fiala Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 86af245d11STodd Fiala if (log) 87af245d11STodd Fiala log->Printf ("NativeProcessProtocol::%s(%d, %d, %s, %s) called", 88af245d11STodd Fiala __FUNCTION__, 89af245d11STodd Fiala exit_type, 90af245d11STodd Fiala status, 91af245d11STodd Fiala exit_description ? exit_description : "nullptr", 92af245d11STodd Fiala bNotifyStateChange ? "true" : "false"); 93af245d11STodd Fiala 94af245d11STodd Fiala // Exit status already set 95af245d11STodd Fiala if (m_state == lldb::eStateExited) 96af245d11STodd Fiala { 97af245d11STodd Fiala if (log) 98af245d11STodd Fiala log->Printf ("NativeProcessProtocol::%s exit status already set to %d, ignoring new set to %d", __FUNCTION__, m_exit_status, status); 99af245d11STodd Fiala return false; 100af245d11STodd Fiala } 101af245d11STodd Fiala 102af245d11STodd Fiala m_state = lldb::eStateExited; 103af245d11STodd Fiala 104af245d11STodd Fiala m_exit_type = exit_type; 105af245d11STodd Fiala m_exit_status = status; 106af245d11STodd Fiala if (exit_description && exit_description[0]) 107af245d11STodd Fiala m_exit_description = exit_description; 108af245d11STodd Fiala else 109af245d11STodd Fiala m_exit_description.clear(); 110af245d11STodd Fiala 111af245d11STodd Fiala if (bNotifyStateChange) 112af245d11STodd Fiala SynchronouslyNotifyProcessStateChanged (lldb::eStateExited); 113af245d11STodd Fiala 114af245d11STodd Fiala return true; 115af245d11STodd Fiala } 116af245d11STodd Fiala 117af245d11STodd Fiala NativeThreadProtocolSP 118af245d11STodd Fiala NativeProcessProtocol::GetThreadAtIndex (uint32_t idx) 119af245d11STodd Fiala { 120af245d11STodd Fiala Mutex::Locker locker (m_threads_mutex); 121af245d11STodd Fiala if (idx < m_threads.size ()) 122af245d11STodd Fiala return m_threads[idx]; 123af245d11STodd Fiala return NativeThreadProtocolSP (); 124af245d11STodd Fiala } 125af245d11STodd Fiala 126af245d11STodd Fiala NativeThreadProtocolSP 127511e5cdcSTodd Fiala NativeProcessProtocol::GetThreadByIDUnlocked (lldb::tid_t tid) 128af245d11STodd Fiala { 129af245d11STodd Fiala for (auto thread_sp : m_threads) 130af245d11STodd Fiala { 131af245d11STodd Fiala if (thread_sp->GetID() == tid) 132af245d11STodd Fiala return thread_sp; 133af245d11STodd Fiala } 134af245d11STodd Fiala return NativeThreadProtocolSP (); 135af245d11STodd Fiala } 136af245d11STodd Fiala 137511e5cdcSTodd Fiala NativeThreadProtocolSP 138511e5cdcSTodd Fiala NativeProcessProtocol::GetThreadByID (lldb::tid_t tid) 139511e5cdcSTodd Fiala { 140511e5cdcSTodd Fiala Mutex::Locker locker (m_threads_mutex); 141511e5cdcSTodd Fiala return GetThreadByIDUnlocked (tid); 142511e5cdcSTodd Fiala } 143511e5cdcSTodd Fiala 144af245d11STodd Fiala bool 145af245d11STodd Fiala NativeProcessProtocol::IsAlive () const 146af245d11STodd Fiala { 147af245d11STodd Fiala return m_state != eStateDetached 148af245d11STodd Fiala && m_state != eStateExited 149af245d11STodd Fiala && m_state != eStateInvalid 150af245d11STodd Fiala && m_state != eStateUnloaded; 151af245d11STodd Fiala } 152af245d11STodd Fiala 153af245d11STodd Fiala bool 154af245d11STodd Fiala NativeProcessProtocol::GetByteOrder (lldb::ByteOrder &byte_order) const 155af245d11STodd Fiala { 156af245d11STodd Fiala ArchSpec process_arch; 157af245d11STodd Fiala if (!GetArchitecture (process_arch)) 158af245d11STodd Fiala return false; 159af245d11STodd Fiala byte_order = process_arch.GetByteOrder (); 160af245d11STodd Fiala return true; 161af245d11STodd Fiala } 162af245d11STodd Fiala 16318fe6404SChaoren Lin const NativeWatchpointList::WatchpointMap& 16418fe6404SChaoren Lin NativeProcessProtocol::GetWatchpointMap () const 16518fe6404SChaoren Lin { 16618fe6404SChaoren Lin return m_watchpoint_list.GetWatchpointMap(); 16718fe6404SChaoren Lin } 16818fe6404SChaoren Lin 169af245d11STodd Fiala uint32_t 170af245d11STodd Fiala NativeProcessProtocol::GetMaxWatchpoints () const 171af245d11STodd Fiala { 172af245d11STodd Fiala // This default implementation will return the number of 173af245d11STodd Fiala // *hardware* breakpoints available. MacOSX and other OS 174af245d11STodd Fiala // implementations that support software breakpoints will want to 175af245d11STodd Fiala // override this correctly for their implementation. 176af245d11STodd Fiala Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 177af245d11STodd Fiala 178af245d11STodd Fiala // get any thread 179af245d11STodd Fiala NativeThreadProtocolSP thread_sp (const_cast<NativeProcessProtocol*> (this)->GetThreadAtIndex (0)); 180af245d11STodd Fiala if (!thread_sp) 181af245d11STodd Fiala { 182af245d11STodd Fiala if (log) 183af245d11STodd Fiala log->Warning ("NativeProcessProtocol::%s (): failed to find a thread to grab a NativeRegisterContext!", __FUNCTION__); 184af245d11STodd Fiala return 0; 185af245d11STodd Fiala } 186af245d11STodd Fiala 187af245d11STodd Fiala NativeRegisterContextSP reg_ctx_sp (thread_sp->GetRegisterContext ()); 188af245d11STodd Fiala if (!reg_ctx_sp) 189af245d11STodd Fiala { 190af245d11STodd Fiala if (log) 191af245d11STodd Fiala log->Warning ("NativeProcessProtocol::%s (): failed to get a RegisterContextNativeProcess from the first thread!", __FUNCTION__); 192af245d11STodd Fiala return 0; 193af245d11STodd Fiala } 194af245d11STodd Fiala 195af245d11STodd Fiala return reg_ctx_sp->NumSupportedHardwareWatchpoints (); 196af245d11STodd Fiala } 197af245d11STodd Fiala 198af245d11STodd Fiala Error 199af245d11STodd Fiala NativeProcessProtocol::SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware) 200af245d11STodd Fiala { 201af245d11STodd Fiala // This default implementation assumes setting the watchpoint for 202af245d11STodd Fiala // the process will require setting the watchpoint for each of the 203af245d11STodd Fiala // threads. Furthermore, it will track watchpoints set for the 204af245d11STodd Fiala // process and will add them to each thread that is attached to 205af245d11STodd Fiala // via the (FIXME implement) OnThreadAttached () method. 206af245d11STodd Fiala 207af245d11STodd Fiala Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 208af245d11STodd Fiala 209af245d11STodd Fiala // Update the thread list 210af245d11STodd Fiala UpdateThreads (); 211af245d11STodd Fiala 212af245d11STodd Fiala // Keep track of the threads we successfully set the watchpoint 213af245d11STodd Fiala // for. If one of the thread watchpoint setting operations fails, 214af245d11STodd Fiala // back off and remove the watchpoint for all the threads that 215af245d11STodd Fiala // were successfully set so we get back to a consistent state. 216af245d11STodd Fiala std::vector<NativeThreadProtocolSP> watchpoint_established_threads; 217af245d11STodd Fiala 218af245d11STodd Fiala // Tell each thread to set a watchpoint. In the event that 219af245d11STodd Fiala // hardware watchpoints are requested but the SetWatchpoint fails, 220af245d11STodd Fiala // try to set a software watchpoint as a fallback. It's 221af245d11STodd Fiala // conceivable that if there are more threads than hardware 222af245d11STodd Fiala // watchpoints available, some of the threads will fail to set 223af245d11STodd Fiala // hardware watchpoints while software ones may be available. 224af245d11STodd Fiala Mutex::Locker locker (m_threads_mutex); 225af245d11STodd Fiala for (auto thread_sp : m_threads) 226af245d11STodd Fiala { 227af245d11STodd Fiala assert (thread_sp && "thread list should not have a NULL thread!"); 228af245d11STodd Fiala if (!thread_sp) 229af245d11STodd Fiala continue; 230af245d11STodd Fiala 231af245d11STodd Fiala Error thread_error = thread_sp->SetWatchpoint (addr, size, watch_flags, hardware); 232af245d11STodd Fiala if (thread_error.Fail () && hardware) 233af245d11STodd Fiala { 234af245d11STodd Fiala // Try software watchpoints since we failed on hardware watchpoint setting 235af245d11STodd Fiala // and we may have just run out of hardware watchpoints. 236af245d11STodd Fiala thread_error = thread_sp->SetWatchpoint (addr, size, watch_flags, false); 237af245d11STodd Fiala if (thread_error.Success ()) 238af245d11STodd Fiala { 239af245d11STodd Fiala if (log) 240af245d11STodd Fiala log->Warning ("hardware watchpoint requested but software watchpoint set"); 241af245d11STodd Fiala } 242af245d11STodd Fiala } 243af245d11STodd Fiala 244af245d11STodd Fiala if (thread_error.Success ()) 245af245d11STodd Fiala { 246af245d11STodd Fiala // Remember that we set this watchpoint successfully in 247af245d11STodd Fiala // case we need to clear it later. 248af245d11STodd Fiala watchpoint_established_threads.push_back (thread_sp); 249af245d11STodd Fiala } 250af245d11STodd Fiala else 251af245d11STodd Fiala { 252af245d11STodd Fiala // Unset the watchpoint for each thread we successfully 253af245d11STodd Fiala // set so that we get back to a consistent state of "not 254af245d11STodd Fiala // set" for the watchpoint. 255af245d11STodd Fiala for (auto unwatch_thread_sp : watchpoint_established_threads) 256af245d11STodd Fiala { 257af245d11STodd Fiala Error remove_error = unwatch_thread_sp->RemoveWatchpoint (addr); 258af245d11STodd Fiala if (remove_error.Fail () && log) 259af245d11STodd Fiala { 260af245d11STodd Fiala log->Warning ("NativeProcessProtocol::%s (): RemoveWatchpoint failed for pid=%" PRIu64 ", tid=%" PRIu64 ": %s", 261af245d11STodd Fiala __FUNCTION__, GetID (), unwatch_thread_sp->GetID (), remove_error.AsCString ()); 262af245d11STodd Fiala } 263af245d11STodd Fiala } 264af245d11STodd Fiala 265af245d11STodd Fiala return thread_error; 266af245d11STodd Fiala } 267af245d11STodd Fiala } 26818fe6404SChaoren Lin return m_watchpoint_list.Add (addr, size, watch_flags, hardware); 269af245d11STodd Fiala } 270af245d11STodd Fiala 271af245d11STodd Fiala Error 272af245d11STodd Fiala NativeProcessProtocol::RemoveWatchpoint (lldb::addr_t addr) 273af245d11STodd Fiala { 274af245d11STodd Fiala // Update the thread list 275af245d11STodd Fiala UpdateThreads (); 276af245d11STodd Fiala 277af245d11STodd Fiala Error overall_error; 278af245d11STodd Fiala 279af245d11STodd Fiala Mutex::Locker locker (m_threads_mutex); 280af245d11STodd Fiala for (auto thread_sp : m_threads) 281af245d11STodd Fiala { 282af245d11STodd Fiala assert (thread_sp && "thread list should not have a NULL thread!"); 283af245d11STodd Fiala if (!thread_sp) 284af245d11STodd Fiala continue; 285af245d11STodd Fiala 286af245d11STodd Fiala const Error thread_error = thread_sp->RemoveWatchpoint (addr); 287af245d11STodd Fiala if (thread_error.Fail ()) 288af245d11STodd Fiala { 289af245d11STodd Fiala // Keep track of the first thread error if any threads 290af245d11STodd Fiala // fail. We want to try to remove the watchpoint from 291af245d11STodd Fiala // every thread, though, even if one or more have errors. 292af245d11STodd Fiala if (!overall_error.Fail ()) 293af245d11STodd Fiala overall_error = thread_error; 294af245d11STodd Fiala } 295af245d11STodd Fiala } 29618fe6404SChaoren Lin const Error error = m_watchpoint_list.Remove(addr); 29718fe6404SChaoren Lin return overall_error.Fail() ? overall_error : error; 298af245d11STodd Fiala } 299af245d11STodd Fiala 300af245d11STodd Fiala bool 301af245d11STodd Fiala NativeProcessProtocol::RegisterNativeDelegate (NativeDelegate &native_delegate) 302af245d11STodd Fiala { 303af245d11STodd Fiala Mutex::Locker locker (m_delegates_mutex); 304af245d11STodd Fiala if (std::find (m_delegates.begin (), m_delegates.end (), &native_delegate) != m_delegates.end ()) 305af245d11STodd Fiala return false; 306af245d11STodd Fiala 307af245d11STodd Fiala m_delegates.push_back (&native_delegate); 308af245d11STodd Fiala native_delegate.InitializeDelegate (this); 309af245d11STodd Fiala return true; 310af245d11STodd Fiala } 311af245d11STodd Fiala 312af245d11STodd Fiala bool 313af245d11STodd Fiala NativeProcessProtocol::UnregisterNativeDelegate (NativeDelegate &native_delegate) 314af245d11STodd Fiala { 315af245d11STodd Fiala Mutex::Locker locker (m_delegates_mutex); 316af245d11STodd Fiala 317af245d11STodd Fiala const auto initial_size = m_delegates.size (); 318af245d11STodd Fiala m_delegates.erase (remove (m_delegates.begin (), m_delegates.end (), &native_delegate), m_delegates.end ()); 319af245d11STodd Fiala 320af245d11STodd Fiala // We removed the delegate if the count of delegates shrank after 321af245d11STodd Fiala // removing all copies of the given native_delegate from the vector. 322af245d11STodd Fiala return m_delegates.size () < initial_size; 323af245d11STodd Fiala } 324af245d11STodd Fiala 325af245d11STodd Fiala void 326af245d11STodd Fiala NativeProcessProtocol::SynchronouslyNotifyProcessStateChanged (lldb::StateType state) 327af245d11STodd Fiala { 328af245d11STodd Fiala Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 329af245d11STodd Fiala 330af245d11STodd Fiala Mutex::Locker locker (m_delegates_mutex); 331af245d11STodd Fiala for (auto native_delegate: m_delegates) 332af245d11STodd Fiala native_delegate->ProcessStateChanged (this, state); 333af245d11STodd Fiala 334af245d11STodd Fiala if (log) 335af245d11STodd Fiala { 336af245d11STodd Fiala if (!m_delegates.empty ()) 337af245d11STodd Fiala { 338af245d11STodd Fiala log->Printf ("NativeProcessProtocol::%s: sent state notification [%s] from process %" PRIu64, 339af245d11STodd Fiala __FUNCTION__, lldb_private::StateAsCString (state), GetID ()); 340af245d11STodd Fiala } 341af245d11STodd Fiala else 342af245d11STodd Fiala { 343af245d11STodd Fiala log->Printf ("NativeProcessProtocol::%s: would send state notification [%s] from process %" PRIu64 ", but no delegates", 344af245d11STodd Fiala __FUNCTION__, lldb_private::StateAsCString (state), GetID ()); 345af245d11STodd Fiala } 346af245d11STodd Fiala } 347af245d11STodd Fiala } 348af245d11STodd Fiala 349a9882ceeSTodd Fiala void 350a9882ceeSTodd Fiala NativeProcessProtocol::NotifyDidExec () 351a9882ceeSTodd Fiala { 352a9882ceeSTodd Fiala Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); 353a9882ceeSTodd Fiala if (log) 354a9882ceeSTodd Fiala log->Printf ("NativeProcessProtocol::%s - preparing to call delegates", __FUNCTION__); 355a9882ceeSTodd Fiala 356a9882ceeSTodd Fiala { 357a9882ceeSTodd Fiala Mutex::Locker locker (m_delegates_mutex); 358a9882ceeSTodd Fiala for (auto native_delegate: m_delegates) 359a9882ceeSTodd Fiala native_delegate->DidExec (this); 360a9882ceeSTodd Fiala } 361a9882ceeSTodd Fiala } 362a9882ceeSTodd Fiala 363a9882ceeSTodd Fiala 364af245d11STodd Fiala Error 365af245d11STodd Fiala NativeProcessProtocol::SetSoftwareBreakpoint (lldb::addr_t addr, uint32_t size_hint) 366af245d11STodd Fiala { 367af245d11STodd Fiala Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS)); 368af245d11STodd Fiala if (log) 369af245d11STodd Fiala log->Printf ("NativeProcessProtocol::%s addr = 0x%" PRIx64, __FUNCTION__, addr); 370af245d11STodd Fiala 371af245d11STodd Fiala return m_breakpoint_list.AddRef (addr, size_hint, false, 372af245d11STodd Fiala [this] (lldb::addr_t addr, size_t size_hint, bool /* hardware */, NativeBreakpointSP &breakpoint_sp)->Error 373af245d11STodd Fiala { return SoftwareBreakpoint::CreateSoftwareBreakpoint (*this, addr, size_hint, breakpoint_sp); }); 374af245d11STodd Fiala } 375af245d11STodd Fiala 376af245d11STodd Fiala Error 377af245d11STodd Fiala NativeProcessProtocol::RemoveBreakpoint (lldb::addr_t addr) 378af245d11STodd Fiala { 379af245d11STodd Fiala return m_breakpoint_list.DecRef (addr); 380af245d11STodd Fiala } 381af245d11STodd Fiala 382af245d11STodd Fiala Error 383af245d11STodd Fiala NativeProcessProtocol::EnableBreakpoint (lldb::addr_t addr) 384af245d11STodd Fiala { 385af245d11STodd Fiala return m_breakpoint_list.EnableBreakpoint (addr); 386af245d11STodd Fiala } 387af245d11STodd Fiala 388af245d11STodd Fiala Error 389af245d11STodd Fiala NativeProcessProtocol::DisableBreakpoint (lldb::addr_t addr) 390af245d11STodd Fiala { 391af245d11STodd Fiala return m_breakpoint_list.DisableBreakpoint (addr); 392af245d11STodd Fiala } 393af245d11STodd Fiala 394af245d11STodd Fiala lldb::StateType 395af245d11STodd Fiala NativeProcessProtocol::GetState () const 396af245d11STodd Fiala { 397af245d11STodd Fiala Mutex::Locker locker (m_state_mutex); 398af245d11STodd Fiala return m_state; 399af245d11STodd Fiala } 400af245d11STodd Fiala 401af245d11STodd Fiala void 402af245d11STodd Fiala NativeProcessProtocol::SetState (lldb::StateType state, bool notify_delegates) 403af245d11STodd Fiala { 404af245d11STodd Fiala Mutex::Locker locker (m_state_mutex); 4055830aa75STamas Berghammer 4065830aa75STamas Berghammer if (state == m_state) 4075830aa75STamas Berghammer return; 4085830aa75STamas Berghammer 409af245d11STodd Fiala m_state = state; 410af245d11STodd Fiala 411af245d11STodd Fiala if (StateIsStoppedState (state, false)) 412af245d11STodd Fiala { 413af245d11STodd Fiala ++m_stop_id; 414af245d11STodd Fiala 415af245d11STodd Fiala // Give process a chance to do any stop id bump processing, such as 416af245d11STodd Fiala // clearing cached data that is invalidated each time the process runs. 417af245d11STodd Fiala // Note if/when we support some threads running, we'll end up needing 418af245d11STodd Fiala // to manage this per thread and per process. 419af245d11STodd Fiala DoStopIDBumped (m_stop_id); 420af245d11STodd Fiala } 421af245d11STodd Fiala 422af245d11STodd Fiala // Optionally notify delegates of the state change. 423af245d11STodd Fiala if (notify_delegates) 424af245d11STodd Fiala SynchronouslyNotifyProcessStateChanged (state); 425af245d11STodd Fiala } 426af245d11STodd Fiala 427af245d11STodd Fiala uint32_t NativeProcessProtocol::GetStopID () const 428af245d11STodd Fiala { 429af245d11STodd Fiala Mutex::Locker locker (m_state_mutex); 430af245d11STodd Fiala return m_stop_id; 431af245d11STodd Fiala } 432af245d11STodd Fiala 433af245d11STodd Fiala void 434af245d11STodd Fiala NativeProcessProtocol::DoStopIDBumped (uint32_t /* newBumpId */) 435af245d11STodd Fiala { 436af245d11STodd Fiala // Default implementation does nothing. 437af245d11STodd Fiala } 4388bc34f4dSOleksiy Vyalov 4398bc34f4dSOleksiy Vyalov void 4408bc34f4dSOleksiy Vyalov NativeProcessProtocol::Terminate () 4418bc34f4dSOleksiy Vyalov { 4428bc34f4dSOleksiy Vyalov // Default implementation does nothing. 4438bc34f4dSOleksiy Vyalov } 444*d5b310f2SPavel Labath 445*d5b310f2SPavel Labath #ifndef __linux__ 446*d5b310f2SPavel Labath // These need to be implemented to support lldb-gdb-server on a given platform. Stubs are 447*d5b310f2SPavel Labath // provided to make the rest of the code link on non-supported platforms. 448*d5b310f2SPavel Labath 449*d5b310f2SPavel Labath Error 450*d5b310f2SPavel Labath NativeProcessProtocol::Launch (ProcessLaunchInfo &launch_info, 451*d5b310f2SPavel Labath NativeDelegate &native_delegate, 452*d5b310f2SPavel Labath NativeProcessProtocolSP &process_sp) 453*d5b310f2SPavel Labath { 454*d5b310f2SPavel Labath llvm_unreachable("Platform has no NativeProcessProtocol support"); 455*d5b310f2SPavel Labath } 456*d5b310f2SPavel Labath 457*d5b310f2SPavel Labath Error 458*d5b310f2SPavel Labath NativeProcessProtocol::Attach (lldb::pid_t pid, 459*d5b310f2SPavel Labath NativeDelegate &native_delegate, 460*d5b310f2SPavel Labath NativeProcessProtocolSP &process_sp) 461*d5b310f2SPavel Labath { 462*d5b310f2SPavel Labath llvm_unreachable("Platform has no NativeProcessProtocol support"); 463*d5b310f2SPavel Labath } 464*d5b310f2SPavel Labath 465*d5b310f2SPavel Labath #endif 466