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