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                       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
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();
293
294    if (addr.IsValid())
295        return addr.GetLoadAddress(target);
296    else
297        return LLDB_INVALID_ADDRESS;
298}
299
300Error
301ProcessPOSIX::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
321Error
322ProcessPOSIX::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
349Error
350ProcessPOSIX::DoSignal(int signal)
351{
352    Error error;
353
354    if (kill(GetID(), signal))
355        error.SetErrorToErrno();
356
357    return error;
358}
359
360Error
361ProcessPOSIX::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
383void
384ProcessPOSIX::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
463void
464ProcessPOSIX::StopAllThreads(lldb::tid_t stop_tid)
465{
466    // FIXME: Will this work the same way on FreeBSD and Linux?
467}
468
469bool
470ProcessPOSIX::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
482POSIXThread *
483ProcessPOSIX::CreateNewPOSIXThread(lldb_private::Process &process, lldb::tid_t tid)
484{
485    return new POSIXThread(process, tid);
486}
487
488void
489ProcessPOSIX::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
546bool
547ProcessPOSIX::IsAlive()
548{
549    StateType state = GetPrivateState();
550    return state != eStateDetached
551        && state != eStateExited
552        && state != eStateInvalid
553        && state != eStateUnloaded;
554}
555
556size_t
557ProcessPOSIX::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
564size_t
565ProcessPOSIX::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
572addr_t
573ProcessPOSIX::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
598Error
599ProcessPOSIX::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
612addr_t
613ProcessPOSIX::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
626size_t
627ProcessPOSIX::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
652Error
653ProcessPOSIX::EnableBreakpointSite(BreakpointSite *bp_site)
654{
655    return EnableSoftwareBreakpoint(bp_site);
656}
657
658Error
659ProcessPOSIX::DisableBreakpointSite(BreakpointSite *bp_site)
660{
661    return DisableSoftwareBreakpoint(bp_site);
662}
663
664Error
665ProcessPOSIX::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
731Error
732ProcessPOSIX::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
783Error
784ProcessPOSIX::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
797Error
798ProcessPOSIX::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
807uint32_t
808ProcessPOSIX::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
815bool
816ProcessPOSIX::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
837ByteOrder
838ProcessPOSIX::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
845size_t
846ProcessPOSIX::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
857UnixSignals &
858ProcessPOSIX::GetUnixSignals()
859{
860    return m_signals;
861}
862
863//------------------------------------------------------------------------------
864// Utility functions.
865
866bool
867ProcessPOSIX::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
882bool
883ProcessPOSIX::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
899bool
900ProcessPOSIX::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