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
34using namespace lldb;
35using namespace lldb_private;
36
37//------------------------------------------------------------------------------
38// Static functions.
39#if 0
40Process*
41ProcessPOSIX::CreateInstance(Target& target, Listener &listener)
42{
43    return new ProcessPOSIX(target, listener);
44}
45
46
47void
48ProcessPOSIX::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
73ProcessPOSIX::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
89ProcessPOSIX::~ProcessPOSIX()
90{
91    delete m_monitor;
92}
93
94//------------------------------------------------------------------------------
95// Process protocol.
96void
97ProcessPOSIX::Finalize()
98{
99  Process::Finalize();
100
101  if (m_monitor)
102    m_monitor->StopMonitor();
103}
104
105bool
106ProcessPOSIX::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
116Error
117ProcessPOSIX::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
165Error
166ProcessPOSIX::DoAttachToProcessWithID (lldb::pid_t pid,  const ProcessAttachInfo &attach_info)
167{
168    return DoAttachToProcessWithID(pid);
169}
170
171Error
172ProcessPOSIX::WillLaunch(Module* module)
173{
174    Error error;
175    return error;
176}
177
178const char *
179ProcessPOSIX::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
201Error
202ProcessPOSIX::DoLaunch (Module *module,
203                        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
257void
258ProcessPOSIX::DidLaunch()
259{
260}
261
262Error
263ProcessPOSIX::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
287addr_t
288ProcessPOSIX::GetImageInfoAddress()
289{
290    Target *target = &GetTarget();
291    ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
292    Address addr = obj_file->GetImageInfoAddress(target);
293
294    if (addr.IsValid())
295        return addr.GetLoadAddress(target);
296    return LLDB_INVALID_ADDRESS;
297}
298
299Error
300ProcessPOSIX::DoHalt(bool &caused_stop)
301{
302    Error error;
303
304    if (IsStopped())
305    {
306        caused_stop = false;
307    }
308    else if (kill(GetID(), SIGSTOP))
309    {
310        caused_stop = false;
311        error.SetErrorToErrno();
312    }
313    else
314    {
315        caused_stop = true;
316    }
317    return error;
318}
319
320Error
321ProcessPOSIX::DoSignal(int signal)
322{
323    Error error;
324
325    if (kill(GetID(), signal))
326        error.SetErrorToErrno();
327
328    return error;
329}
330
331Error
332ProcessPOSIX::DoDestroy()
333{
334    Error error;
335
336    if (!HasExited())
337    {
338        assert (m_monitor);
339        m_exit_now = true;
340        if (m_monitor->BringProcessIntoLimbo())
341        {
342            error.SetErrorToErrno();
343            return error;
344        }
345
346        SetPrivateState(eStateExited);
347    }
348
349    return error;
350}
351
352void
353ProcessPOSIX::DoDidExec()
354{
355    Target *target = &GetTarget();
356    if (target)
357    {
358        PlatformSP platform_sp (target->GetPlatform());
359        assert (platform_sp.get());
360        if (platform_sp)
361        {
362            ProcessInstanceInfo process_info;
363            platform_sp->GetProcessInfo(GetID(), process_info);
364            ModuleSP exe_module_sp;
365            FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
366            Error error = platform_sp->ResolveExecutable(process_info.GetExecutableFile(),
367                                                   target->GetArchitecture(),
368                                                   exe_module_sp,
369                                                   executable_search_paths.GetSize() ? &executable_search_paths : NULL);
370            if (!error.Success())
371                return;
372            target->SetExecutableModule(exe_module_sp, true);
373        }
374    }
375}
376
377void
378ProcessPOSIX::SendMessage(const ProcessMessage &message)
379{
380    Mutex::Locker lock(m_message_mutex);
381
382    Mutex::Locker thread_lock(m_thread_list.GetMutex());
383
384    POSIXThread *thread = static_cast<POSIXThread*>(
385        m_thread_list.FindThreadByID(message.GetTID(), false).get());
386
387    switch (message.GetKind())
388    {
389    case ProcessMessage::eInvalidMessage:
390        return;
391
392    case ProcessMessage::eAttachMessage:
393        SetPrivateState(eStateStopped);
394        return;
395
396    case ProcessMessage::eLimboMessage:
397        assert(thread);
398        thread->SetState(eStateStopped);
399        if (message.GetTID() == GetID())
400        {
401            m_exit_status = message.GetExitStatus();
402            if (m_exit_now)
403            {
404                SetPrivateState(eStateExited);
405                m_monitor->Detach(GetID());
406            }
407            else
408            {
409                StopAllThreads(message.GetTID());
410                SetPrivateState(eStateStopped);
411            }
412        }
413        else
414        {
415            StopAllThreads(message.GetTID());
416            SetPrivateState(eStateStopped);
417        }
418        break;
419
420    case ProcessMessage::eExitMessage:
421        assert(thread);
422        thread->SetState(eStateExited);
423        // FIXME: I'm not sure we need to do this.
424        if (message.GetTID() == GetID())
425        {
426            m_exit_status = message.GetExitStatus();
427            SetExitStatus(m_exit_status, NULL);
428        }
429        else if (!IsAThreadRunning())
430            SetPrivateState(eStateStopped);
431        break;
432
433    case ProcessMessage::eSignalMessage:
434    case ProcessMessage::eSignalDeliveredMessage:
435        if (message.GetSignal() == SIGSTOP &&
436            AddThreadForInitialStopIfNeeded(message.GetTID()))
437            return;
438        // Intentional fall-through
439
440    case ProcessMessage::eBreakpointMessage:
441    case ProcessMessage::eTraceMessage:
442    case ProcessMessage::eWatchpointMessage:
443    case ProcessMessage::eCrashMessage:
444        assert(thread);
445        thread->SetState(eStateStopped);
446        StopAllThreads(message.GetTID());
447        SetPrivateState(eStateStopped);
448        break;
449
450    case ProcessMessage::eNewThreadMessage:
451    {
452        lldb::tid_t  new_tid = message.GetChildTID();
453        if (WaitingForInitialStop(new_tid))
454        {
455            m_monitor->WaitForInitialTIDStop(new_tid);
456        }
457        assert(thread);
458        thread->SetState(eStateStopped);
459        StopAllThreads(message.GetTID());
460        SetPrivateState(eStateStopped);
461        break;
462    }
463
464    case ProcessMessage::eExecMessage:
465    {
466        assert(thread);
467        thread->SetState(eStateStopped);
468        StopAllThreads(message.GetTID());
469        SetPrivateState(eStateStopped);
470        break;
471    }
472    }
473
474
475    m_message_queue.push(message);
476}
477
478void
479ProcessPOSIX::StopAllThreads(lldb::tid_t stop_tid)
480{
481    // FIXME: Will this work the same way on FreeBSD and Linux?
482}
483
484bool
485ProcessPOSIX::AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid)
486{
487    bool added_to_set = false;
488    ThreadStopSet::iterator it = m_seen_initial_stop.find(stop_tid);
489    if (it == m_seen_initial_stop.end())
490    {
491        m_seen_initial_stop.insert(stop_tid);
492        added_to_set = true;
493    }
494    return added_to_set;
495}
496
497bool
498ProcessPOSIX::WaitingForInitialStop(lldb::tid_t stop_tid)
499{
500    return (m_seen_initial_stop.find(stop_tid) == m_seen_initial_stop.end());
501}
502
503POSIXThread *
504ProcessPOSIX::CreateNewPOSIXThread(lldb_private::Process &process, lldb::tid_t tid)
505{
506    return new POSIXThread(process, tid);
507}
508
509void
510ProcessPOSIX::RefreshStateAfterStop()
511{
512    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
513    if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
514        log->Printf ("ProcessPOSIX::%s(), message_queue size = %d", __FUNCTION__, (int)m_message_queue.size());
515
516    Mutex::Locker lock(m_message_mutex);
517
518    // This method used to only handle one message.  Changing it to loop allows
519    // it to handle the case where we hit a breakpoint while handling a different
520    // breakpoint.
521    while (!m_message_queue.empty())
522    {
523        ProcessMessage &message = m_message_queue.front();
524
525        // Resolve the thread this message corresponds to and pass it along.
526        lldb::tid_t tid = message.GetTID();
527        if (log)
528            log->Printf ("ProcessPOSIX::%s(), message_queue size = %d, pid = %" PRIi64, __FUNCTION__, (int)m_message_queue.size(), tid);
529
530        if (message.GetKind() == ProcessMessage::eNewThreadMessage)
531        {
532            if (log)
533                log->Printf ("ProcessPOSIX::%s() adding thread, tid = %" PRIi64, __FUNCTION__, message.GetChildTID());
534            lldb::tid_t child_tid = message.GetChildTID();
535            ThreadSP thread_sp;
536            thread_sp.reset(CreateNewPOSIXThread(*this, child_tid));
537
538            Mutex::Locker lock(m_thread_list.GetMutex());
539
540            m_thread_list.AddThread(thread_sp);
541        }
542
543        m_thread_list.RefreshStateAfterStop();
544
545        POSIXThread *thread = static_cast<POSIXThread*>(
546            GetThreadList().FindThreadByID(tid, false).get());
547        if (thread)
548            thread->Notify(message);
549
550        if (message.GetKind() == ProcessMessage::eExitMessage)
551        {
552            // FIXME: We should tell the user about this, but the limbo message is probably better for that.
553            if (log)
554                log->Printf ("ProcessPOSIX::%s() removing thread, tid = %" PRIi64, __FUNCTION__, tid);
555
556            Mutex::Locker lock(m_thread_list.GetMutex());
557
558            ThreadSP thread_sp = m_thread_list.RemoveThreadByID(tid, false);
559            thread_sp.reset();
560            m_seen_initial_stop.erase(tid);
561        }
562
563        m_message_queue.pop();
564    }
565}
566
567bool
568ProcessPOSIX::IsAlive()
569{
570    StateType state = GetPrivateState();
571    return state != eStateDetached
572        && state != eStateExited
573        && state != eStateInvalid
574        && state != eStateUnloaded;
575}
576
577size_t
578ProcessPOSIX::DoReadMemory(addr_t vm_addr,
579                           void *buf, size_t size, Error &error)
580{
581    assert(m_monitor);
582    return m_monitor->ReadMemory(vm_addr, buf, size, error);
583}
584
585size_t
586ProcessPOSIX::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size,
587                            Error &error)
588{
589    assert(m_monitor);
590    return m_monitor->WriteMemory(vm_addr, buf, size, error);
591}
592
593addr_t
594ProcessPOSIX::DoAllocateMemory(size_t size, uint32_t permissions,
595                               Error &error)
596{
597    addr_t allocated_addr = LLDB_INVALID_ADDRESS;
598
599    unsigned prot = 0;
600    if (permissions & lldb::ePermissionsReadable)
601        prot |= eMmapProtRead;
602    if (permissions & lldb::ePermissionsWritable)
603        prot |= eMmapProtWrite;
604    if (permissions & lldb::ePermissionsExecutable)
605        prot |= eMmapProtExec;
606
607    if (InferiorCallMmap(this, allocated_addr, 0, size, prot,
608                         eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
609        m_addr_to_mmap_size[allocated_addr] = size;
610        error.Clear();
611    } else {
612        allocated_addr = LLDB_INVALID_ADDRESS;
613        error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions));
614    }
615
616    return allocated_addr;
617}
618
619Error
620ProcessPOSIX::DoDeallocateMemory(lldb::addr_t addr)
621{
622    Error error;
623    MMapMap::iterator pos = m_addr_to_mmap_size.find(addr);
624    if (pos != m_addr_to_mmap_size.end() &&
625        InferiorCallMunmap(this, addr, pos->second))
626        m_addr_to_mmap_size.erase (pos);
627    else
628        error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
629
630    return error;
631}
632
633size_t
634ProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
635{
636    static const uint8_t g_i386_opcode[] = { 0xCC };
637
638    ArchSpec arch = GetTarget().GetArchitecture();
639    const uint8_t *opcode = NULL;
640    size_t opcode_size = 0;
641
642    switch (arch.GetCore())
643    {
644    default:
645        assert(false && "CPU type not supported!");
646        break;
647
648    case ArchSpec::eCore_x86_32_i386:
649    case ArchSpec::eCore_x86_64_x86_64:
650        opcode = g_i386_opcode;
651        opcode_size = sizeof(g_i386_opcode);
652        break;
653    }
654
655    bp_site->SetTrapOpcode(opcode, opcode_size);
656    return opcode_size;
657}
658
659Error
660ProcessPOSIX::EnableBreakpointSite(BreakpointSite *bp_site)
661{
662    return EnableSoftwareBreakpoint(bp_site);
663}
664
665Error
666ProcessPOSIX::DisableBreakpointSite(BreakpointSite *bp_site)
667{
668    return DisableSoftwareBreakpoint(bp_site);
669}
670
671Error
672ProcessPOSIX::EnableWatchpoint(Watchpoint *wp, bool notify)
673{
674    Error error;
675    if (wp)
676    {
677        user_id_t watchID = wp->GetID();
678        addr_t addr = wp->GetLoadAddress();
679        Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
680        if (log)
681            log->Printf ("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64 ")",
682                         watchID);
683        if (wp->IsEnabled())
684        {
685            if (log)
686                log->Printf("ProcessPOSIX::EnableWatchpoint(watchID = %" PRIu64
687                            ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.",
688                            watchID, (uint64_t)addr);
689            return error;
690        }
691
692        // Try to find a vacant watchpoint slot in the inferiors' main thread
693        uint32_t wp_hw_index = LLDB_INVALID_INDEX32;
694        Mutex::Locker lock(m_thread_list.GetMutex());
695        POSIXThread *thread = static_cast<POSIXThread*>(
696                               m_thread_list.GetThreadAtIndex(0, false).get());
697
698        if (thread)
699            wp_hw_index = thread->FindVacantWatchpointIndex();
700
701        if (wp_hw_index == LLDB_INVALID_INDEX32)
702        {
703            error.SetErrorString("Setting hardware watchpoint failed.");
704        }
705        else
706        {
707            wp->SetHardwareIndex(wp_hw_index);
708            bool wp_enabled = true;
709            uint32_t thread_count = m_thread_list.GetSize(false);
710            for (uint32_t i = 0; i < thread_count; ++i)
711            {
712                thread = static_cast<POSIXThread*>(
713                         m_thread_list.GetThreadAtIndex(i, false).get());
714                if (thread)
715                    wp_enabled &= thread->EnableHardwareWatchpoint(wp);
716                else
717                    wp_enabled = false;
718            }
719            if (wp_enabled)
720            {
721                wp->SetEnabled(true, notify);
722                return error;
723            }
724            else
725            {
726                // Watchpoint enabling failed on at least one
727                // of the threads so roll back all of them
728                DisableWatchpoint(wp, false);
729                error.SetErrorString("Setting hardware watchpoint failed");
730            }
731        }
732    }
733    else
734        error.SetErrorString("Watchpoint argument was NULL.");
735    return error;
736}
737
738Error
739ProcessPOSIX::DisableWatchpoint(Watchpoint *wp, bool notify)
740{
741    Error error;
742    if (wp)
743    {
744        user_id_t watchID = wp->GetID();
745        addr_t addr = wp->GetLoadAddress();
746        Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
747        if (log)
748            log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64 ")",
749                        watchID);
750        if (!wp->IsEnabled())
751        {
752            if (log)
753                log->Printf("ProcessPOSIX::DisableWatchpoint(watchID = %" PRIu64
754                            ") addr = 0x%8.8" PRIx64 ": watchpoint already disabled.",
755                            watchID, (uint64_t)addr);
756            // This is needed (for now) to keep watchpoints disabled correctly
757            wp->SetEnabled(false, notify);
758            return error;
759        }
760
761        if (wp->IsHardware())
762        {
763            bool wp_disabled = true;
764            Mutex::Locker lock(m_thread_list.GetMutex());
765            uint32_t thread_count = m_thread_list.GetSize(false);
766            for (uint32_t i = 0; i < thread_count; ++i)
767            {
768                POSIXThread *thread = static_cast<POSIXThread*>(
769                                      m_thread_list.GetThreadAtIndex(i, false).get());
770                if (thread)
771                    wp_disabled &= thread->DisableHardwareWatchpoint(wp);
772                else
773                    wp_disabled = false;
774            }
775            if (wp_disabled)
776            {
777                wp->SetHardwareIndex(LLDB_INVALID_INDEX32);
778                wp->SetEnabled(false, notify);
779                return error;
780            }
781            else
782                error.SetErrorString("Disabling hardware watchpoint failed");
783        }
784    }
785    else
786        error.SetErrorString("Watchpoint argument was NULL.");
787    return error;
788}
789
790Error
791ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num)
792{
793    Error error;
794    Mutex::Locker lock(m_thread_list.GetMutex());
795    POSIXThread *thread = static_cast<POSIXThread*>(
796                          m_thread_list.GetThreadAtIndex(0, false).get());
797    if (thread)
798        num = thread->NumSupportedHardwareWatchpoints();
799    else
800        error.SetErrorString("Process does not exist.");
801    return error;
802}
803
804Error
805ProcessPOSIX::GetWatchpointSupportInfo(uint32_t &num, bool &after)
806{
807    Error error = GetWatchpointSupportInfo(num);
808    // Watchpoints trigger and halt the inferior after
809    // the corresponding instruction has been executed.
810    after = true;
811    return error;
812}
813
814uint32_t
815ProcessPOSIX::UpdateThreadListIfNeeded()
816{
817    Mutex::Locker lock(m_thread_list.GetMutex());
818    // Do not allow recursive updates.
819    return m_thread_list.GetSize(false);
820}
821
822bool
823ProcessPOSIX::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
824{
825    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
826    if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
827        log->Printf ("ProcessPOSIX::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID());
828
829    bool has_updated = false;
830    // Update the process thread list with this new thread.
831    // FIXME: We should be using tid, not pid.
832    assert(m_monitor);
833    ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
834    if (!thread_sp) {
835        thread_sp.reset(CreateNewPOSIXThread(*this, GetID()));
836        has_updated = true;
837    }
838
839    if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
840        log->Printf ("ProcessPOSIX::%s() updated pid = %" PRIi64, __FUNCTION__, GetID());
841    new_thread_list.AddThread(thread_sp);
842
843    return has_updated; // the list has been updated
844}
845
846ByteOrder
847ProcessPOSIX::GetByteOrder() const
848{
849    // FIXME: We should be able to extract this value directly.  See comment in
850    // ProcessPOSIX().
851    return m_byte_order;
852}
853
854size_t
855ProcessPOSIX::PutSTDIN(const char *buf, size_t len, Error &error)
856{
857    ssize_t status;
858    if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0)
859    {
860        error.SetErrorToErrno();
861        return 0;
862    }
863    return status;
864}
865
866UnixSignals &
867ProcessPOSIX::GetUnixSignals()
868{
869    return m_signals;
870}
871
872//------------------------------------------------------------------------------
873// Utility functions.
874
875bool
876ProcessPOSIX::HasExited()
877{
878    switch (GetPrivateState())
879    {
880    default:
881        break;
882
883    case eStateDetached:
884    case eStateExited:
885        return true;
886    }
887
888    return false;
889}
890
891bool
892ProcessPOSIX::IsStopped()
893{
894    switch (GetPrivateState())
895    {
896    default:
897        break;
898
899    case eStateStopped:
900    case eStateCrashed:
901    case eStateSuspended:
902        return true;
903    }
904
905    return false;
906}
907
908bool
909ProcessPOSIX::IsAThreadRunning()
910{
911    bool is_running = false;
912    Mutex::Locker lock(m_thread_list.GetMutex());
913    uint32_t thread_count = m_thread_list.GetSize(false);
914    for (uint32_t i = 0; i < thread_count; ++i)
915    {
916        POSIXThread *thread = static_cast<POSIXThread*>(
917            m_thread_list.GetThreadAtIndex(i, false).get());
918        StateType thread_state = thread->GetState();
919        if (thread_state == eStateRunning || thread_state == eStateStepping)
920        {
921            is_running = true;
922            break;
923        }
924    }
925    return is_running;
926}
927