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