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