1 //===-- ProcessPOSIX.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 "lldb/lldb-python.h"
11 
12 // C Includes
13 #include <errno.h>
14 
15 // C++ Includes
16 // Other libraries and framework includes
17 #include "lldb/Breakpoint/Watchpoint.h"
18 #include "lldb/Core/Module.h"
19 #include "lldb/Core/PluginManager.h"
20 #include "lldb/Core/State.h"
21 #include "lldb/Host/FileSpec.h"
22 #include "lldb/Host/Host.h"
23 #include "lldb/Symbol/ObjectFile.h"
24 #include "lldb/Target/DynamicLoader.h"
25 #include "lldb/Target/Platform.h"
26 #include "lldb/Target/Target.h"
27 
28 #include "ProcessPOSIX.h"
29 #include "ProcessPOSIXLog.h"
30 #include "Plugins/Process/Utility/InferiorCallPOSIX.h"
31 #include "ProcessMonitor.h"
32 #include "POSIXThread.h"
33 
34 using namespace lldb;
35 using namespace lldb_private;
36 
37 //------------------------------------------------------------------------------
38 // Static functions.
39 #if 0
40 Process*
41 ProcessPOSIX::CreateInstance(Target& target, Listener &listener)
42 {
43     return new ProcessPOSIX(target, listener);
44 }
45 
46 
47 void
48 ProcessPOSIX::Initialize()
49 {
50     static bool g_initialized = false;
51 
52     if (!g_initialized)
53     {
54         g_initialized = true;
55         PluginManager::RegisterPlugin(GetPluginNameStatic(),
56                                       GetPluginDescriptionStatic(),
57                                       CreateInstance);
58 
59         Log::Callbacks log_callbacks = {
60             ProcessPOSIXLog::DisableLog,
61             ProcessPOSIXLog::EnableLog,
62             ProcessPOSIXLog::ListLogCategories
63         };
64 
65         Log::RegisterLogChannel (ProcessPOSIX::GetPluginNameStatic(), log_callbacks);
66     }
67 }
68 #endif
69 
70 //------------------------------------------------------------------------------
71 // Constructors and destructors.
72 
ProcessPOSIX(Target & target,Listener & listener)73 ProcessPOSIX::ProcessPOSIX(Target& target, Listener &listener)
74     : Process(target, listener),
75       m_byte_order(lldb::endian::InlHostByteOrder()),
76       m_monitor(NULL),
77       m_module(NULL),
78       m_message_mutex (Mutex::eMutexTypeRecursive),
79       m_exit_now(false),
80       m_seen_initial_stop()
81 {
82     // FIXME: Putting this code in the ctor and saving the byte order in a
83     // member variable is a hack to avoid const qual issues in GetByteOrder.
84 	lldb::ModuleSP module = GetTarget().GetExecutableModule();
85 	if (module && module->GetObjectFile())
86 		m_byte_order = module->GetObjectFile()->GetByteOrder();
87 }
88 
~ProcessPOSIX()89 ProcessPOSIX::~ProcessPOSIX()
90 {
91     delete m_monitor;
92 }
93 
94 //------------------------------------------------------------------------------
95 // Process protocol.
96 void
Finalize()97 ProcessPOSIX::Finalize()
98 {
99   Process::Finalize();
100 
101   if (m_monitor)
102     m_monitor->StopMonitor();
103 }
104 
105 bool
CanDebug(Target & target,bool plugin_specified_by_name)106 ProcessPOSIX::CanDebug(Target &target, bool plugin_specified_by_name)
107 {
108     // For now we are just making sure the file exists for a given module
109     ModuleSP exe_module_sp(target.GetExecutableModule());
110     if (exe_module_sp.get())
111         return exe_module_sp->GetFileSpec().Exists();
112     // If there is no executable module, we return true since we might be preparing to attach.
113     return true;
114 }
115 
116 Error
DoAttachToProcessWithID(lldb::pid_t pid)117 ProcessPOSIX::DoAttachToProcessWithID(lldb::pid_t pid)
118 {
119     Error error;
120     assert(m_monitor == NULL);
121 
122     Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
123     if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
124         log->Printf ("ProcessPOSIX::%s(pid = %" PRIi64 ")", __FUNCTION__, GetID());
125 
126     m_monitor = new ProcessMonitor(this, pid, error);
127 
128     if (!error.Success())
129         return error;
130 
131     PlatformSP platform_sp (m_target.GetPlatform ());
132     assert (platform_sp.get());
133     if (!platform_sp)
134         return error;  // FIXME: Detatch?
135 
136     // Find out what we can about this process
137     ProcessInstanceInfo process_info;
138     platform_sp->GetProcessInfo (pid, process_info);
139 
140     // Resolve the executable module
141     ModuleSP exe_module_sp;
142     FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
143     error = platform_sp->ResolveExecutable(process_info.GetExecutableFile(),
144                                            m_target.GetArchitecture(),
145                                            exe_module_sp,
146                                            executable_search_paths.GetSize() ? &executable_search_paths : NULL);
147     if (!error.Success())
148         return error;
149 
150     // Fix the target architecture if necessary
151     const ArchSpec &module_arch = exe_module_sp->GetArchitecture();
152     if (module_arch.IsValid() && !m_target.GetArchitecture().IsExactMatch(module_arch))
153         m_target.SetArchitecture(module_arch);
154 
155     // Initialize the target module list
156     m_target.SetExecutableModule (exe_module_sp, true);
157 
158     SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
159 
160     SetID(pid);
161 
162     return error;
163 }
164 
165 Error
DoAttachToProcessWithID(lldb::pid_t pid,const ProcessAttachInfo & attach_info)166 ProcessPOSIX::DoAttachToProcessWithID (lldb::pid_t pid,  const ProcessAttachInfo &attach_info)
167 {
168     return DoAttachToProcessWithID(pid);
169 }
170 
171 Error
WillLaunch(Module * module)172 ProcessPOSIX::WillLaunch(Module* module)
173 {
174     Error error;
175     return error;
176 }
177 
178 const char *
GetFilePath(const lldb_private::ProcessLaunchInfo::FileAction * file_action,const char * default_path)179 ProcessPOSIX::GetFilePath(
180     const lldb_private::ProcessLaunchInfo::FileAction *file_action,
181     const char *default_path)
182 {
183     const char *pts_name = "/dev/pts/";
184     const char *path = NULL;
185 
186     if (file_action)
187     {
188         if (file_action->GetAction () == ProcessLaunchInfo::FileAction::eFileActionOpen)
189             path = file_action->GetPath();
190             // By default the stdio paths passed in will be pseudo-terminal
191             // (/dev/pts). If so, convert to using a different default path
192             // instead to redirect I/O to the debugger console. This should
193             //  also handle user overrides to /dev/null or a different file.
194             if (::strncmp(path, pts_name, ::strlen(pts_name)) == 0)
195                 path = default_path;
196     }
197 
198     return path;
199 }
200 
201 Error
DoLaunch(Module * module,const ProcessLaunchInfo & launch_info)202 ProcessPOSIX::DoLaunch (Module *module,
203                        const ProcessLaunchInfo &launch_info)
204 {
205     Error error;
206     assert(m_monitor == NULL);
207 
208     const char* working_dir = launch_info.GetWorkingDirectory();
209     if (working_dir) {
210       FileSpec WorkingDir(working_dir, true);
211       if (!WorkingDir || WorkingDir.GetFileType() != FileSpec::eFileTypeDirectory)
212       {
213           error.SetErrorStringWithFormat("No such file or directory: %s", working_dir);
214           return error;
215       }
216     }
217 
218     SetPrivateState(eStateLaunching);
219 
220     const lldb_private::ProcessLaunchInfo::FileAction *file_action;
221 
222     // Default of NULL will mean to use existing open file descriptors
223     const char *stdin_path = NULL;
224     const char *stdout_path = NULL;
225     const char *stderr_path = NULL;
226 
227     file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
228     stdin_path = GetFilePath(file_action, stdin_path);
229 
230     file_action = launch_info.GetFileActionForFD (STDOUT_FILENO);
231     stdout_path = GetFilePath(file_action, stdout_path);
232 
233     file_action = launch_info.GetFileActionForFD (STDERR_FILENO);
234     stderr_path = GetFilePath(file_action, stderr_path);
235 
236     m_monitor = new ProcessMonitor (this,
237                                     module,
238                                     launch_info.GetArguments().GetConstArgumentVector(),
239                                     launch_info.GetEnvironmentEntries().GetConstArgumentVector(),
240                                     stdin_path,
241                                     stdout_path,
242                                     stderr_path,
243                                     working_dir,
244                                     error);
245 
246     m_module = module;
247 
248     if (!error.Success())
249         return error;
250 
251     SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
252 
253     SetID(m_monitor->GetPID());
254     return error;
255 }
256 
257 void
DidLaunch()258 ProcessPOSIX::DidLaunch()
259 {
260 }
261 
262 Error
DoResume()263 ProcessPOSIX::DoResume()
264 {
265     StateType state = GetPrivateState();
266 
267     assert(state == eStateStopped);
268 
269     SetPrivateState(eStateRunning);
270 
271     bool did_resume = false;
272 
273     Mutex::Locker lock(m_thread_list.GetMutex());
274 
275     uint32_t thread_count = m_thread_list.GetSize(false);
276     for (uint32_t i = 0; i < thread_count; ++i)
277     {
278         POSIXThread *thread = static_cast<POSIXThread*>(
279             m_thread_list.GetThreadAtIndex(i, false).get());
280         did_resume = thread->Resume() || did_resume;
281     }
282     assert(did_resume && "Process resume failed!");
283 
284     return Error();
285 }
286 
287 addr_t
GetImageInfoAddress()288 ProcessPOSIX::GetImageInfoAddress()
289 {
290     Target *target = &GetTarget();
291     ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
292     Address addr = obj_file->GetImageInfoAddress();
293 
294     if (addr.IsValid())
295         return addr.GetLoadAddress(target);
296     else
297         return LLDB_INVALID_ADDRESS;
298 }
299 
300 Error
DoHalt(bool & caused_stop)301 ProcessPOSIX::DoHalt(bool &caused_stop)
302 {
303     Error error;
304 
305     if (IsStopped())
306     {
307         caused_stop = false;
308     }
309     else if (kill(GetID(), SIGSTOP))
310     {
311         caused_stop = false;
312         error.SetErrorToErrno();
313     }
314     else
315     {
316         caused_stop = true;
317     }
318     return error;
319 }
320 
321 Error
DoDetach(bool keep_stopped)322 ProcessPOSIX::DoDetach(bool keep_stopped)
323 {
324     Error error;
325     if (keep_stopped)
326     {
327         // FIXME: If you want to implement keep_stopped,
328         // this would be the place to do it.
329         error.SetErrorString("Detaching with keep_stopped true is not currently supported on this platform.");
330         return error;
331     }
332 
333     Mutex::Locker lock(m_thread_list.GetMutex());
334 
335     uint32_t thread_count = m_thread_list.GetSize(false);
336     for (uint32_t i = 0; i < thread_count; ++i)
337     {
338         POSIXThread *thread = static_cast<POSIXThread*>(
339             m_thread_list.GetThreadAtIndex(i, false).get());
340         error = m_monitor->Detach(thread->GetID());
341     }
342 
343     if (error.Success())
344         SetPrivateState(eStateDetached);
345 
346     return error;
347 }
348 
349 Error
DoSignal(int signal)350 ProcessPOSIX::DoSignal(int signal)
351 {
352     Error error;
353 
354     if (kill(GetID(), signal))
355         error.SetErrorToErrno();
356 
357     return error;
358 }
359 
360 Error
DoDestroy()361 ProcessPOSIX::DoDestroy()
362 {
363     Error error;
364 
365     if (!HasExited())
366     {
367         // Drive the exit event to completion (do not keep the inferior in
368         // limbo).
369         m_exit_now = true;
370 
371         if ((m_monitor == NULL || kill(m_monitor->GetPID(), SIGKILL)) && error.Success())
372         {
373             error.SetErrorToErrno();
374             return error;
375         }
376 
377         SetPrivateState(eStateExited);
378     }
379 
380     return error;
381 }
382 
383 void
SendMessage(const ProcessMessage & message)384 ProcessPOSIX::SendMessage(const ProcessMessage &message)
385 {
386     Mutex::Locker lock(m_message_mutex);
387 
388     Mutex::Locker thread_lock(m_thread_list.GetMutex());
389 
390     POSIXThread *thread = static_cast<POSIXThread*>(
391         m_thread_list.FindThreadByID(message.GetTID(), false).get());
392 
393     switch (message.GetKind())
394     {
395     case ProcessMessage::eInvalidMessage:
396         return;
397 
398     case ProcessMessage::eLimboMessage:
399         assert(thread);
400         thread->SetState(eStateStopped);
401         if (message.GetTID() == GetID())
402         {
403             m_exit_status = message.GetExitStatus();
404             if (m_exit_now)
405             {
406                 SetPrivateState(eStateExited);
407                 m_monitor->Detach(GetID());
408             }
409             else
410             {
411                 StopAllThreads(message.GetTID());
412                 SetPrivateState(eStateStopped);
413             }
414         }
415         else
416         {
417             StopAllThreads(message.GetTID());
418             SetPrivateState(eStateStopped);
419         }
420         break;
421 
422     case ProcessMessage::eExitMessage:
423         assert(thread);
424         thread->SetState(eStateExited);
425         // FIXME: I'm not sure we need to do this.
426         if (message.GetTID() == GetID())
427         {
428             m_exit_status = message.GetExitStatus();
429             SetExitStatus(m_exit_status, NULL);
430         }
431         else if (!IsAThreadRunning())
432             SetPrivateState(eStateStopped);
433         break;
434 
435         assert(thread);
436         thread->SetState(eStateStopped);
437         StopAllThreads(message.GetTID());
438         SetPrivateState(eStateStopped);
439         break;
440 
441     case ProcessMessage::eSignalMessage:
442     case ProcessMessage::eSignalDeliveredMessage:
443         if (message.GetSignal() == SIGSTOP &&
444             AddThreadForInitialStopIfNeeded(message.GetTID()))
445             return;
446         // Intentional fall-through
447 
448     case ProcessMessage::eBreakpointMessage:
449     case ProcessMessage::eTraceMessage:
450     case ProcessMessage::eWatchpointMessage:
451     case ProcessMessage::eNewThreadMessage:
452     case ProcessMessage::eCrashMessage:
453         assert(thread);
454         thread->SetState(eStateStopped);
455         StopAllThreads(message.GetTID());
456         SetPrivateState(eStateStopped);
457         break;
458     }
459 
460     m_message_queue.push(message);
461 }
462 
463 void
StopAllThreads(lldb::tid_t stop_tid)464 ProcessPOSIX::StopAllThreads(lldb::tid_t stop_tid)
465 {
466     // FIXME: Will this work the same way on FreeBSD and Linux?
467 }
468 
469 bool
AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid)470 ProcessPOSIX::AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid)
471 {
472     bool added_to_set = false;
473     ThreadStopSet::iterator it = m_seen_initial_stop.find(stop_tid);
474     if (it == m_seen_initial_stop.end())
475     {
476         m_seen_initial_stop.insert(stop_tid);
477         added_to_set = true;
478     }
479     return added_to_set;
480 }
481 
482 POSIXThread *
CreateNewPOSIXThread(lldb_private::Process & process,lldb::tid_t tid)483 ProcessPOSIX::CreateNewPOSIXThread(lldb_private::Process &process, lldb::tid_t tid)
484 {
485     return new POSIXThread(process, tid);
486 }
487 
488 void
RefreshStateAfterStop()489 ProcessPOSIX::RefreshStateAfterStop()
490 {
491     Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
492     if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
493         log->Printf ("ProcessPOSIX::%s(), message_queue size = %d", __FUNCTION__, (int)m_message_queue.size());
494 
495     Mutex::Locker lock(m_message_mutex);
496 
497     // This method used to only handle one message.  Changing it to loop allows
498     // it to handle the case where we hit a breakpoint while handling a different
499     // breakpoint.
500     while (!m_message_queue.empty())
501     {
502         ProcessMessage &message = m_message_queue.front();
503 
504         // Resolve the thread this message corresponds to and pass it along.
505         lldb::tid_t tid = message.GetTID();
506         if (log)
507             log->Printf ("ProcessPOSIX::%s(), message_queue size = %d, pid = %" PRIi64, __FUNCTION__, (int)m_message_queue.size(), tid);
508         POSIXThread *thread = static_cast<POSIXThread*>(
509             GetThreadList().FindThreadByID(tid, false).get());
510 
511         if (message.GetKind() == ProcessMessage::eNewThreadMessage)
512         {
513             if (log)
514                 log->Printf ("ProcessPOSIX::%s() adding thread, tid = %" PRIi64, __FUNCTION__, message.GetChildTID());
515             lldb::tid_t child_tid = message.GetChildTID();
516             ThreadSP thread_sp;
517             thread_sp.reset(CreateNewPOSIXThread(*this, child_tid));
518 
519             Mutex::Locker lock(m_thread_list.GetMutex());
520 
521             m_thread_list.AddThread(thread_sp);
522         }
523 
524         m_thread_list.RefreshStateAfterStop();
525 
526         if (thread)
527             thread->Notify(message);
528 
529         if (message.GetKind() == ProcessMessage::eExitMessage)
530         {
531             // FIXME: We should tell the user about this, but the limbo message is probably better for that.
532             if (log)
533                 log->Printf ("ProcessPOSIX::%s() removing thread, tid = %" PRIi64, __FUNCTION__, tid);
534 
535             Mutex::Locker lock(m_thread_list.GetMutex());
536 
537             ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false);
538             thread_sp.reset();
539             m_seen_initial_stop.erase(tid);
540         }
541 
542         m_message_queue.pop();
543     }
544 }
545 
546 bool
IsAlive()547 ProcessPOSIX::IsAlive()
548 {
549     StateType state = GetPrivateState();
550     return state != eStateDetached
551         && state != eStateExited
552         && state != eStateInvalid
553         && state != eStateUnloaded;
554 }
555 
556 size_t
DoReadMemory(addr_t vm_addr,void * buf,size_t size,Error & error)557 ProcessPOSIX::DoReadMemory(addr_t vm_addr,
558                            void *buf, size_t size, Error &error)
559 {
560     assert(m_monitor);
561     return m_monitor->ReadMemory(vm_addr, buf, size, error);
562 }
563 
564 size_t
DoWriteMemory(addr_t vm_addr,const void * buf,size_t size,Error & error)565 ProcessPOSIX::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
566                             Error &error)
567 {
568     assert(m_monitor);
569     return m_monitor->WriteMemory(vm_addr, buf, size, error);
570 }
571 
572 addr_t
DoAllocateMemory(size_t size,uint32_t permissions,Error & error)573 ProcessPOSIX::DoAllocateMemory(size_t size, uint32_t permissions,
574                                Error &error)
575 {
576     addr_t allocated_addr = LLDB_INVALID_ADDRESS;
577 
578     unsigned prot = 0;
579     if (permissions & lldb::ePermissionsReadable)
580         prot |= eMmapProtRead;
581     if (permissions & lldb::ePermissionsWritable)
582         prot |= eMmapProtWrite;
583     if (permissions & lldb::ePermissionsExecutable)
584         prot |= eMmapProtExec;
585 
586     if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
587                          eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
588         m_addr_to_mmap_size[allocated_addr] = size;
589         error.Clear();
590     } else {
591         allocated_addr = LLDB_INVALID_ADDRESS;
592         error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
593     }
594 
595     return allocated_addr;
596 }
597 
598 Error
DoDeallocateMemory(lldb::addr_t addr)599 ProcessPOSIX::DoDeallocateMemory(lldb::addr_t addr)
600 {
601     Error error;
602     MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
603     if (pos != m_addr_to_mmap_size.end() &&
604         InferiorCallMunmap(this, addr, pos->second))
605         m_addr_to_mmap_size.erase (pos);
606     else
607         error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
608 
609     return error;
610 }
611 
612 addr_t
ResolveIndirectFunction(const Address * address,Error & error)613 ProcessPOSIX::ResolveIndirectFunction(const Address *address, Error &error)
614 {
615     addr_t function_addr = LLDB_INVALID_ADDRESS;
616     if (address == NULL) {
617         error.SetErrorStringWithFormat("unable to determine direct function call for NULL address");
618     } else if (!InferiorCall(this, address, function_addr)) {
619         function_addr = LLDB_INVALID_ADDRESS;
620         error.SetErrorStringWithFormat("unable to determine direct function call for indirect function %s",
621                                        address->CalculateSymbolContextSymbol()->GetName().AsCString());
622     }
623     return function_addr;
624 }
625 
626 size_t
GetSoftwareBreakpointTrapOpcode(BreakpointSite * bp_site)627 ProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
628 {
629     static const uint8_t g_i386_opcode[] = { 0xCC };
630 
631     ArchSpec arch = GetTarget().GetArchitecture();
632     const uint8_t *opcode = NULL;
633     size_t opcode_size = 0;
634 
635     switch (arch.GetCore())
636     {
637     default:
638         assert(false && "CPU type not supported!");
639         break;
640 
641     case ArchSpec::eCore_x86_32_i386:
642     case ArchSpec::eCore_x86_64_x86_64:
643         opcode = g_i386_opcode;
644         opcode_size = sizeof(g_i386_opcode);
645         break;
646     }
647 
648     bp_site->SetTrapOpcode(opcode, opcode_size);
649     return opcode_size;
650 }
651 
652 Error
EnableBreakpointSite(BreakpointSite * bp_site)653 ProcessPOSIX::EnableBreakpointSite(BreakpointSite *bp_site)
654 {
655     return EnableSoftwareBreakpoint(bp_site);
656 }
657 
658 Error
DisableBreakpointSite(BreakpointSite * bp_site)659 ProcessPOSIX::DisableBreakpointSite(BreakpointSite *bp_site)
660 {
661     return DisableSoftwareBreakpoint(bp_site);
662 }
663 
664 Error
EnableWatchpoint(Watchpoint * wp,bool notify)665 ProcessPOSIX::EnableWatchpoint(Watchpoint *wp, bool notify)
666 {
667     Error error;
668     if (wp)
669     {
670         user_id_t watchID = wp->GetID();
671         addr_t addr = wp->GetLoadAddress();
672         Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
673         if (log)
674             log->Printf ("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64 ")",
675                          watchID);
676         if (wp->IsEnabled())
677         {
678             if (log)
679                 log->Printf("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64
680                             ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
681                             watchID, (uint64_t)addr);
682             return error;
683         }
684 
685         // Try to find a vacant watchpoint slot in the inferiors' main thread
686         uint32_t wp_hw_index = LLDB_INVALID_INDEX32;
687         Mutex::Locker lock(m_thread_list.GetMutex());
688         POSIXThread *thread = static_cast<POSIXThread*>(
689                                m_thread_list.GetThreadAtIndex(0, false).get());
690 
691         if (thread)
692             wp_hw_index = thread->FindVacantWatchpointIndex();
693 
694         if (wp_hw_index == LLDB_INVALID_INDEX32)
695         {
696             error.SetErrorString("Setting hardware watchpoint failed.");
697         }
698         else
699         {
700             wp->SetHardwareIndex(wp_hw_index);
701             bool wp_enabled = true;
702             uint32_t thread_count = m_thread_list.GetSize(false);
703             for (uint32_t i = 0; i < thread_count; ++i)
704             {
705                 thread = static_cast<POSIXThread*>(
706                          m_thread_list.GetThreadAtIndex(i, false).get());
707                 if (thread)
708                     wp_enabled &= thread->EnableHardwareWatchpoint(wp);
709                 else
710                     wp_enabled = false;
711             }
712             if (wp_enabled)
713             {
714                 wp->SetEnabled(true, notify);
715                 return error;
716             }
717             else
718             {
719                 // Watchpoint enabling failed on at least one
720                 // of the threads so roll back all of them
721                 DisableWatchpoint(wp, false);
722                 error.SetErrorString("Setting hardware watchpoint failed");
723             }
724         }
725     }
726     else
727         error.SetErrorString("Watchpoint argument was NULL.");
728     return error;
729 }
730 
731 Error
DisableWatchpoint(Watchpoint * wp,bool notify)732 ProcessPOSIX::DisableWatchpoint(Watchpoint *wp, bool notify)
733 {
734     Error error;
735     if (wp)
736     {
737         user_id_t watchID = wp->GetID();
738         addr_t addr = wp->GetLoadAddress();
739         Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
740         if (log)
741             log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64 ")",
742                         watchID);
743         if (!wp->IsEnabled())
744         {
745             if (log)
746                 log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64
747                             ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.",
748                             watchID, (uint64_t)addr);
749             // This is needed (for now) to keep watchpoints disabled correctly
750             wp->SetEnabled(false, notify);
751             return error;
752         }
753 
754         if (wp->IsHardware())
755         {
756             bool wp_disabled = true;
757             Mutex::Locker lock(m_thread_list.GetMutex());
758             uint32_t thread_count = m_thread_list.GetSize(false);
759             for (uint32_t i = 0; i < thread_count; ++i)
760             {
761                 POSIXThread *thread = static_cast<POSIXThread*>(
762                                       m_thread_list.GetThreadAtIndex(i, false).get());
763                 if (thread)
764                     wp_disabled &= thread->DisableHardwareWatchpoint(wp);
765                 else
766                     wp_disabled = false;
767             }
768             if (wp_disabled)
769             {
770                 wp->SetHardwareIndex(LLDB_INVALID_INDEX32);
771                 wp->SetEnabled(false, notify);
772                 return error;
773             }
774             else
775                 error.SetErrorString("Disabling hardware watchpoint failed");
776         }
777     }
778     else
779         error.SetErrorString("Watchpoint argument was NULL.");
780     return error;
781 }
782 
783 Error
GetWatchpointSupportInfo(uint32_t & num)784 ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num)
785 {
786     Error error;
787     Mutex::Locker lock(m_thread_list.GetMutex());
788     POSIXThread *thread = static_cast<POSIXThread*>(
789                           m_thread_list.GetThreadAtIndex(0, false).get());
790     if (thread)
791         num = thread->NumSupportedHardwareWatchpoints();
792     else
793         error.SetErrorString("Process does not exist.");
794     return error;
795 }
796 
797 Error
GetWatchpointSupportInfo(uint32_t & num,bool & after)798 ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num, bool &after)
799 {
800     Error error = GetWatchpointSupportInfo(num);
801     // Watchpoints trigger and halt the inferior after
802     // the corresponding instruction has been executed.
803     after = true;
804     return error;
805 }
806 
807 uint32_t
UpdateThreadListIfNeeded()808 ProcessPOSIX::UpdateThreadListIfNeeded()
809 {
810     Mutex::Locker lock(m_thread_list.GetMutex());
811     // Do not allow recursive updates.
812     return m_thread_list.GetSize(false);
813 }
814 
815 bool
UpdateThreadList(ThreadList & old_thread_list,ThreadList & new_thread_list)816 ProcessPOSIX::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
817 {
818     Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
819     if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
820         log->Printf ("ProcessPOSIX::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID());
821 
822     // Update the process thread list with this new thread.
823     // FIXME: We should be using tid, not pid.
824     assert(m_monitor);
825     ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
826     if (!thread_sp) {
827         thread_sp.reset(CreateNewPOSIXThread(*this, GetID()));
828     }
829 
830     if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
831         log->Printf ("ProcessPOSIX::%s() updated pid = %" PRIi64, __FUNCTION__, GetID());
832     new_thread_list.AddThread(thread_sp);
833 
834     return new_thread_list.GetSize(false) > 0;
835 }
836 
837 ByteOrder
GetByteOrder() const838 ProcessPOSIX::GetByteOrder() const
839 {
840     // FIXME: We should be able to extract this value directly.  See comment in
841     // ProcessPOSIX().
842     return m_byte_order;
843 }
844 
845 size_t
PutSTDIN(const char * buf,size_t len,Error & error)846 ProcessPOSIX::PutSTDIN(const char *buf, size_t len, Error &error)
847 {
848     ssize_t status;
849     if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0)
850     {
851         error.SetErrorToErrno();
852         return 0;
853     }
854     return status;
855 }
856 
857 UnixSignals &
GetUnixSignals()858 ProcessPOSIX::GetUnixSignals()
859 {
860     return m_signals;
861 }
862 
863 //------------------------------------------------------------------------------
864 // Utility functions.
865 
866 bool
HasExited()867 ProcessPOSIX::HasExited()
868 {
869     switch (GetPrivateState())
870     {
871     default:
872         break;
873 
874     case eStateDetached:
875     case eStateExited:
876         return true;
877     }
878 
879     return false;
880 }
881 
882 bool
IsStopped()883 ProcessPOSIX::IsStopped()
884 {
885     switch (GetPrivateState())
886     {
887     default:
888         break;
889 
890     case eStateStopped:
891     case eStateCrashed:
892     case eStateSuspended:
893         return true;
894     }
895 
896     return false;
897 }
898 
899 bool
IsAThreadRunning()900 ProcessPOSIX::IsAThreadRunning()
901 {
902     bool is_running = false;
903     Mutex::Locker lock(m_thread_list.GetMutex());
904     uint32_t thread_count = m_thread_list.GetSize(false);
905     for (uint32_t i = 0; i < thread_count; ++i)
906     {
907         POSIXThread *thread = static_cast<POSIXThread*>(
908             m_thread_list.GetThreadAtIndex(i, false).get());
909         StateType thread_state = thread->GetState();
910         if (thread_state == eStateRunning || thread_state == eStateStepping)
911         {
912             is_running = true;
913             break;
914         }
915     }
916     return is_running;
917 }
918