blob: 9c29f32a6318b8ff0dc633cc641ef763a5cbbfe7 [file] [log] [blame]
Todd Fialaaf245d12014-06-30 21:05:18 +00001//===-- NativeProcessProtocol.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
Chaoren Lin2fe1d0a2015-02-03 01:51:38 +000010#include "lldb/Host/common/NativeProcessProtocol.h"
Todd Fialaaf245d12014-06-30 21:05:18 +000011
12#include "lldb/lldb-enumerations.h"
13#include "lldb/Core/ArchSpec.h"
14#include "lldb/Core/Log.h"
15#include "lldb/Core/State.h"
Todd Fiala511e5cd2014-09-11 23:29:14 +000016#include "lldb/Host/Host.h"
Chaoren Lin2fe1d0a2015-02-03 01:51:38 +000017#include "lldb/Host/common/NativeRegisterContext.h"
Todd Fialaaf245d12014-06-30 21:05:18 +000018
Chaoren Lin2fe1d0a2015-02-03 01:51:38 +000019#include "lldb/Host/common/NativeThreadProtocol.h"
20#include "lldb/Host/common/SoftwareBreakpoint.h"
Todd Fialaaf245d12014-06-30 21:05:18 +000021
22using namespace lldb;
23using namespace lldb_private;
24
25// -----------------------------------------------------------------------------
26// NativeProcessProtocol Members
27// -----------------------------------------------------------------------------
28
29NativeProcessProtocol::NativeProcessProtocol (lldb::pid_t pid) :
30 m_pid (pid),
31 m_threads (),
32 m_current_thread_id (LLDB_INVALID_THREAD_ID),
33 m_threads_mutex (Mutex::eMutexTypeRecursive),
34 m_state (lldb::eStateInvalid),
35 m_state_mutex (Mutex::eMutexTypeRecursive),
36 m_exit_type (eExitTypeInvalid),
37 m_exit_status (0),
38 m_exit_description (),
39 m_delegates_mutex (Mutex::eMutexTypeRecursive),
40 m_delegates (),
41 m_breakpoint_list (),
42 m_terminal_fd (-1),
43 m_stop_id (0)
44{
45}
46
47lldb_private::Error
Todd Fiala511e5cd2014-09-11 23:29:14 +000048NativeProcessProtocol::Interrupt ()
49{
50 Error error;
51#if !defined (SIGSTOP)
52 error.SetErrorString ("local host does not support signaling");
53 return error;
54#else
55 return Signal (SIGSTOP);
56#endif
57}
58
59lldb_private::Error
Todd Fialaaf245d12014-06-30 21:05:18 +000060NativeProcessProtocol::GetMemoryRegionInfo (lldb::addr_t load_addr, MemoryRegionInfo &range_info)
61{
62 // Default: not implemented.
63 return Error ("not implemented");
64}
65
66bool
67NativeProcessProtocol::GetExitStatus (ExitType *exit_type, int *status, std::string &exit_description)
68{
69 if (m_state == lldb::eStateExited)
70 {
71 *exit_type = m_exit_type;
72 *status = m_exit_status;
73 exit_description = m_exit_description;
74 return true;
75 }
76
77 *status = 0;
78 return false;
79}
80
81bool
82NativeProcessProtocol::SetExitStatus (ExitType exit_type, int status, const char *exit_description, bool bNotifyStateChange)
83{
84 Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
85 if (log)
86 log->Printf ("NativeProcessProtocol::%s(%d, %d, %s, %s) called",
87 __FUNCTION__,
88 exit_type,
89 status,
90 exit_description ? exit_description : "nullptr",
91 bNotifyStateChange ? "true" : "false");
92
93 // Exit status already set
94 if (m_state == lldb::eStateExited)
95 {
96 if (log)
97 log->Printf ("NativeProcessProtocol::%s exit status already set to %d, ignoring new set to %d", __FUNCTION__, m_exit_status, status);
98 return false;
99 }
100
101 m_state = lldb::eStateExited;
102
103 m_exit_type = exit_type;
104 m_exit_status = status;
105 if (exit_description && exit_description[0])
106 m_exit_description = exit_description;
107 else
108 m_exit_description.clear();
109
110 if (bNotifyStateChange)
111 SynchronouslyNotifyProcessStateChanged (lldb::eStateExited);
112
113 return true;
114}
115
116NativeThreadProtocolSP
117NativeProcessProtocol::GetThreadAtIndex (uint32_t idx)
118{
119 Mutex::Locker locker (m_threads_mutex);
120 if (idx < m_threads.size ())
121 return m_threads[idx];
122 return NativeThreadProtocolSP ();
123}
124
125NativeThreadProtocolSP
Todd Fiala511e5cd2014-09-11 23:29:14 +0000126NativeProcessProtocol::GetThreadByIDUnlocked (lldb::tid_t tid)
Todd Fialaaf245d12014-06-30 21:05:18 +0000127{
Todd Fialaaf245d12014-06-30 21:05:18 +0000128 for (auto thread_sp : m_threads)
129 {
130 if (thread_sp->GetID() == tid)
131 return thread_sp;
132 }
133 return NativeThreadProtocolSP ();
134}
135
Todd Fiala511e5cd2014-09-11 23:29:14 +0000136NativeThreadProtocolSP
137NativeProcessProtocol::GetThreadByID (lldb::tid_t tid)
138{
139 Mutex::Locker locker (m_threads_mutex);
140 return GetThreadByIDUnlocked (tid);
141}
142
Todd Fialaaf245d12014-06-30 21:05:18 +0000143bool
144NativeProcessProtocol::IsAlive () const
145{
146 return m_state != eStateDetached
147 && m_state != eStateExited
148 && m_state != eStateInvalid
149 && m_state != eStateUnloaded;
150}
151
152bool
153NativeProcessProtocol::GetByteOrder (lldb::ByteOrder &byte_order) const
154{
155 ArchSpec process_arch;
156 if (!GetArchitecture (process_arch))
157 return false;
158 byte_order = process_arch.GetByteOrder ();
159 return true;
160}
161
162uint32_t
163NativeProcessProtocol::GetMaxWatchpoints () const
164{
165 // This default implementation will return the number of
166 // *hardware* breakpoints available. MacOSX and other OS
167 // implementations that support software breakpoints will want to
168 // override this correctly for their implementation.
169 Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
170
171 // get any thread
172 NativeThreadProtocolSP thread_sp (const_cast<NativeProcessProtocol*> (this)->GetThreadAtIndex (0));
173 if (!thread_sp)
174 {
175 if (log)
176 log->Warning ("NativeProcessProtocol::%s (): failed to find a thread to grab a NativeRegisterContext!", __FUNCTION__);
177 return 0;
178 }
179
180 NativeRegisterContextSP reg_ctx_sp (thread_sp->GetRegisterContext ());
181 if (!reg_ctx_sp)
182 {
183 if (log)
184 log->Warning ("NativeProcessProtocol::%s (): failed to get a RegisterContextNativeProcess from the first thread!", __FUNCTION__);
185 return 0;
186 }
187
188 return reg_ctx_sp->NumSupportedHardwareWatchpoints ();
189}
190
191Error
192NativeProcessProtocol::SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware)
193{
194 // This default implementation assumes setting the watchpoint for
195 // the process will require setting the watchpoint for each of the
196 // threads. Furthermore, it will track watchpoints set for the
197 // process and will add them to each thread that is attached to
198 // via the (FIXME implement) OnThreadAttached () method.
199
200 Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
201
202 // FIXME save the watchpoint on the set of process watchpoint vars
203 // so we can add them to a thread each time a new thread is registered.
204
205 // Update the thread list
206 UpdateThreads ();
207
208 // Keep track of the threads we successfully set the watchpoint
209 // for. If one of the thread watchpoint setting operations fails,
210 // back off and remove the watchpoint for all the threads that
211 // were successfully set so we get back to a consistent state.
212 std::vector<NativeThreadProtocolSP> watchpoint_established_threads;
213
214 // Tell each thread to set a watchpoint. In the event that
215 // hardware watchpoints are requested but the SetWatchpoint fails,
216 // try to set a software watchpoint as a fallback. It's
217 // conceivable that if there are more threads than hardware
218 // watchpoints available, some of the threads will fail to set
219 // hardware watchpoints while software ones may be available.
220 Mutex::Locker locker (m_threads_mutex);
221 for (auto thread_sp : m_threads)
222 {
223 assert (thread_sp && "thread list should not have a NULL thread!");
224 if (!thread_sp)
225 continue;
226
227 Error thread_error = thread_sp->SetWatchpoint (addr, size, watch_flags, hardware);
228 if (thread_error.Fail () && hardware)
229 {
230 // Try software watchpoints since we failed on hardware watchpoint setting
231 // and we may have just run out of hardware watchpoints.
232 thread_error = thread_sp->SetWatchpoint (addr, size, watch_flags, false);
233 if (thread_error.Success ())
234 {
235 if (log)
236 log->Warning ("hardware watchpoint requested but software watchpoint set");
237 }
238 }
239
240 if (thread_error.Success ())
241 {
242 // Remember that we set this watchpoint successfully in
243 // case we need to clear it later.
244 watchpoint_established_threads.push_back (thread_sp);
245 }
246 else
247 {
248 // Unset the watchpoint for each thread we successfully
249 // set so that we get back to a consistent state of "not
250 // set" for the watchpoint.
251 for (auto unwatch_thread_sp : watchpoint_established_threads)
252 {
253 Error remove_error = unwatch_thread_sp->RemoveWatchpoint (addr);
254 if (remove_error.Fail () && log)
255 {
256 log->Warning ("NativeProcessProtocol::%s (): RemoveWatchpoint failed for pid=%" PRIu64 ", tid=%" PRIu64 ": %s",
257 __FUNCTION__, GetID (), unwatch_thread_sp->GetID (), remove_error.AsCString ());
258 }
259 }
260
261 return thread_error;
262 }
263 }
264 return Error ();
265}
266
267Error
268NativeProcessProtocol::RemoveWatchpoint (lldb::addr_t addr)
269{
270 // FIXME remove the watchpoint on the set of process watchpoint vars
271 // so we can add them to a thread each time a new thread is registered.
272
273 // Update the thread list
274 UpdateThreads ();
275
276 Error overall_error;
277
278 Mutex::Locker locker (m_threads_mutex);
279 for (auto thread_sp : m_threads)
280 {
281 assert (thread_sp && "thread list should not have a NULL thread!");
282 if (!thread_sp)
283 continue;
284
285 const Error thread_error = thread_sp->RemoveWatchpoint (addr);
286 if (thread_error.Fail ())
287 {
288 // Keep track of the first thread error if any threads
289 // fail. We want to try to remove the watchpoint from
290 // every thread, though, even if one or more have errors.
291 if (!overall_error.Fail ())
292 overall_error = thread_error;
293 }
294 }
295 return overall_error;
296}
297
298bool
299NativeProcessProtocol::RegisterNativeDelegate (NativeDelegate &native_delegate)
300{
301 Mutex::Locker locker (m_delegates_mutex);
302 if (std::find (m_delegates.begin (), m_delegates.end (), &native_delegate) != m_delegates.end ())
303 return false;
304
305 m_delegates.push_back (&native_delegate);
306 native_delegate.InitializeDelegate (this);
307 return true;
308}
309
310bool
311NativeProcessProtocol::UnregisterNativeDelegate (NativeDelegate &native_delegate)
312{
313 Mutex::Locker locker (m_delegates_mutex);
314
315 const auto initial_size = m_delegates.size ();
316 m_delegates.erase (remove (m_delegates.begin (), m_delegates.end (), &native_delegate), m_delegates.end ());
317
318 // We removed the delegate if the count of delegates shrank after
319 // removing all copies of the given native_delegate from the vector.
320 return m_delegates.size () < initial_size;
321}
322
323void
324NativeProcessProtocol::SynchronouslyNotifyProcessStateChanged (lldb::StateType state)
325{
326 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
327
328 Mutex::Locker locker (m_delegates_mutex);
329 for (auto native_delegate: m_delegates)
330 native_delegate->ProcessStateChanged (this, state);
331
332 if (log)
333 {
334 if (!m_delegates.empty ())
335 {
336 log->Printf ("NativeProcessProtocol::%s: sent state notification [%s] from process %" PRIu64,
337 __FUNCTION__, lldb_private::StateAsCString (state), GetID ());
338 }
339 else
340 {
341 log->Printf ("NativeProcessProtocol::%s: would send state notification [%s] from process %" PRIu64 ", but no delegates",
342 __FUNCTION__, lldb_private::StateAsCString (state), GetID ());
343 }
344 }
345}
346
Todd Fialaa9882ce2014-08-28 15:46:54 +0000347void
348NativeProcessProtocol::NotifyDidExec ()
349{
350 Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
351 if (log)
352 log->Printf ("NativeProcessProtocol::%s - preparing to call delegates", __FUNCTION__);
353
354 {
355 Mutex::Locker locker (m_delegates_mutex);
356 for (auto native_delegate: m_delegates)
357 native_delegate->DidExec (this);
358 }
359}
360
361
Todd Fialaaf245d12014-06-30 21:05:18 +0000362Error
363NativeProcessProtocol::SetSoftwareBreakpoint (lldb::addr_t addr, uint32_t size_hint)
364{
365 Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
366 if (log)
367 log->Printf ("NativeProcessProtocol::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
368
369 return m_breakpoint_list.AddRef (addr, size_hint, false,
370 [this] (lldb::addr_t addr, size_t size_hint, bool /* hardware */, NativeBreakpointSP &breakpoint_sp)->Error
371 { return SoftwareBreakpoint::CreateSoftwareBreakpoint (*this, addr, size_hint, breakpoint_sp); });
372}
373
374Error
375NativeProcessProtocol::RemoveBreakpoint (lldb::addr_t addr)
376{
377 return m_breakpoint_list.DecRef (addr);
378}
379
380Error
381NativeProcessProtocol::EnableBreakpoint (lldb::addr_t addr)
382{
383 return m_breakpoint_list.EnableBreakpoint (addr);
384}
385
386Error
387NativeProcessProtocol::DisableBreakpoint (lldb::addr_t addr)
388{
389 return m_breakpoint_list.DisableBreakpoint (addr);
390}
391
392lldb::StateType
393NativeProcessProtocol::GetState () const
394{
395 Mutex::Locker locker (m_state_mutex);
396 return m_state;
397}
398
399void
400NativeProcessProtocol::SetState (lldb::StateType state, bool notify_delegates)
401{
402 Mutex::Locker locker (m_state_mutex);
403 m_state = state;
404
405 if (StateIsStoppedState (state, false))
406 {
407 ++m_stop_id;
408
409 // Give process a chance to do any stop id bump processing, such as
410 // clearing cached data that is invalidated each time the process runs.
411 // Note if/when we support some threads running, we'll end up needing
412 // to manage this per thread and per process.
413 DoStopIDBumped (m_stop_id);
414 }
415
416 // Optionally notify delegates of the state change.
417 if (notify_delegates)
418 SynchronouslyNotifyProcessStateChanged (state);
419}
420
421uint32_t NativeProcessProtocol::GetStopID () const
422{
423 Mutex::Locker locker (m_state_mutex);
424 return m_stop_id;
425}
426
427void
428NativeProcessProtocol::DoStopIDBumped (uint32_t /* newBumpId */)
429{
430 // Default implementation does nothing.
431}