[Lldb-commits] [lldb] r196787 - Threaded inferior support for FreeBSD

Ed Maste emaste at freebsd.org
Mon Dec 9 07:51:17 PST 2013


Author: emaste
Date: Mon Dec  9 09:51:17 2013
New Revision: 196787

URL: http://llvm.org/viewvc/llvm-project?rev=196787&view=rev
Log:
Threaded inferior support for FreeBSD

Modelled in part on GDBRemoteCommunicationClient.

Review: http://llvm-reviews.chandlerc.com/D2267

Added:
    lldb/trunk/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
    lldb/trunk/source/Plugins/Process/FreeBSD/FreeBSDThread.h
Modified:
    lldb/trunk/source/Plugins/Process/FreeBSD/CMakeLists.txt
    lldb/trunk/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
    lldb/trunk/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h
    lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
    lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.h
    lldb/trunk/source/Plugins/Process/Linux/LinuxThread.cpp
    lldb/trunk/source/Plugins/Process/Linux/LinuxThread.h
    lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.cpp
    lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.h
    lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp
    lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.h
    lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
    lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.h

Modified: lldb/trunk/source/Plugins/Process/FreeBSD/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/FreeBSD/CMakeLists.txt?rev=196787&r1=196786&r2=196787&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/FreeBSD/CMakeLists.txt (original)
+++ lldb/trunk/source/Plugins/Process/FreeBSD/CMakeLists.txt Mon Dec  9 09:51:17 2013
@@ -5,5 +5,6 @@ include_directories(../POSIX)
 
 add_lldb_library(lldbPluginProcessFreeBSD
   ProcessFreeBSD.cpp
+  FreeBSDThread.cpp
   ProcessMonitor.cpp
   )

Added: lldb/trunk/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp?rev=196787&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp (added)
+++ lldb/trunk/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp Mon Dec  9 09:51:17 2013
@@ -0,0 +1,69 @@
+//===-- FreeBSDThread.cpp ---------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "lldb/Core/State.h"
+
+// Project includes
+#include "FreeBSDThread.h"
+#include "ProcessFreeBSD.h"
+#include "ProcessPOSIXLog.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//------------------------------------------------------------------------------
+// Constructors and destructors.
+
+FreeBSDThread::FreeBSDThread(Process &process, lldb::tid_t tid)
+    : POSIXThread(process, tid)
+{
+}
+
+FreeBSDThread::~FreeBSDThread()
+{
+}
+
+//------------------------------------------------------------------------------
+// ProcessInterface protocol.
+
+void
+FreeBSDThread::WillResume(lldb::StateType resume_state)
+{
+    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
+    if (log)
+        log->Printf("tid %lu resume_state = %s", GetID(),
+                    lldb_private::StateAsCString(resume_state));
+    ProcessSP process_sp(GetProcess());
+    ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(process_sp.get());
+    int signo = GetResumeSignal();
+    bool signo_valid = process->GetUnixSignals().SignalIsValid(signo);
+
+    switch (resume_state)
+    {
+    case eStateSuspended:
+    case eStateStopped:
+        process->m_suspend_tids.push_back(GetID());
+        break;
+    case eStateRunning:
+        process->m_run_tids.push_back(GetID());
+        if (signo_valid)
+            process->m_resume_signo = signo;
+        break;
+    case eStateStepping:
+        process->m_step_tids.push_back(GetID());
+        if (signo_valid)
+            process->m_resume_signo = signo;
+        break; 
+    default:
+        break;
+    }
+}

Added: lldb/trunk/source/Plugins/Process/FreeBSD/FreeBSDThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/FreeBSD/FreeBSDThread.h?rev=196787&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/FreeBSD/FreeBSDThread.h (added)
+++ lldb/trunk/source/Plugins/Process/FreeBSD/FreeBSDThread.h Mon Dec  9 09:51:17 2013
@@ -0,0 +1,39 @@
+//===-- FreeBSDThread.h -----------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_FreeBSDThread_H_
+#define liblldb_FreeBSDThread_H_
+
+// Other libraries and framework includes
+#include "POSIXThread.h"
+
+//------------------------------------------------------------------------------
+// @class FreeBSDThread
+// @brief Abstraction of a FreeBSD thread.
+class FreeBSDThread
+    : public POSIXThread
+{
+public:
+
+    //------------------------------------------------------------------
+    // Constructors and destructors
+    //------------------------------------------------------------------
+    FreeBSDThread(lldb_private::Process &process, lldb::tid_t tid);
+
+    virtual ~FreeBSDThread();
+
+    //--------------------------------------------------------------------------
+    // FreeBSDThread internal API.
+
+    // POSIXThread override
+    virtual void
+    WillResume(lldb::StateType resume_state);
+};
+
+#endif // #ifndef liblldb_FreeBSDThread_H_

Modified: lldb/trunk/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp?rev=196787&r1=196786&r2=196787&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp (original)
+++ lldb/trunk/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp Mon Dec  9 09:51:17 2013
@@ -23,7 +23,7 @@
 #include "ProcessPOSIXLog.h"
 #include "Plugins/Process/Utility/InferiorCallPOSIX.h"
 #include "ProcessMonitor.h"
-#include "POSIXThread.h"
+#include "FreeBSDThread.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -140,29 +140,136 @@ ProcessFreeBSD::DoDetach(bool keep_stopp
     return error;
 }
 
+Error
+ProcessFreeBSD::DoResume()
+{
+    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
+
+    // FreeBSD's ptrace() uses 0 to indicate "no signal is to be sent."
+    int resume_signal = 0;
+
+    SetPrivateState(eStateRunning);
+
+    Mutex::Locker lock(m_thread_list.GetMutex());
+    bool do_step = false;
+
+    for (tid_collection::const_iterator t_pos = m_run_tids.begin(), t_end = m_run_tids.end(); t_pos != t_end; ++t_pos)
+    {
+        m_monitor->ThreadSuspend(*t_pos, false);
+    }
+    for (tid_collection::const_iterator t_pos = m_step_tids.begin(), t_end = m_step_tids.end(); t_pos != t_end; ++t_pos)
+    {
+        m_monitor->ThreadSuspend(*t_pos, false);
+        do_step = true;
+    }
+    for (tid_collection::const_iterator t_pos = m_suspend_tids.begin(), t_end = m_suspend_tids.end(); t_pos != t_end; ++t_pos)
+    {
+        m_monitor->ThreadSuspend(*t_pos, true);
+        // XXX Cannot PT_CONTINUE properly with suspended threads.
+        do_step = true;
+    }
+
+    if (log)
+        log->Printf("process %lu resuming (%s)", GetID(), do_step ? "step" : "continue");
+    if (do_step)
+        m_monitor->SingleStep(GetID(), resume_signal);
+    else
+        m_monitor->Resume(GetID(), resume_signal);
+
+    return Error();
+}
+
 bool
 ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
 {
-    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
-    if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
-        log->Printf ("ProcessFreeBSD::%s() (pid = %" PRIu64 ")", __FUNCTION__, GetID());
-
-    bool has_updated = false;
-    const lldb::pid_t pid = GetID();
-    // Update the process thread list with this new thread.
-    // FIXME: We should be using tid, not pid.
-    assert(m_monitor);
-    ThreadSP thread_sp (old_thread_list.FindThreadByID (pid, false));
-    if (!thread_sp) {
-        ProcessSP me = this->shared_from_this();
-        thread_sp.reset(new POSIXThread(*me, pid));
-        has_updated = true;
+    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
+    if (log)
+        log->Printf("ProcessFreeBSD::%s (pid = %" PRIu64 ")", __FUNCTION__, GetID());
+
+    std::vector<lldb::pid_t> tds;
+    if (!GetMonitor().GetCurrentThreadIDs(tds))
+    {
+        return false;
     }
 
-    if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
-        log->Printf ("ProcessFreeBSD::%s() updated tid = %" PRIu64, __FUNCTION__, pid);
+    ThreadList old_thread_list_copy(old_thread_list);
+    for (size_t i = 0; i < tds.size(); ++i)
+    {
+        tid_t tid = tds[i];
+        ThreadSP thread_sp (old_thread_list_copy.RemoveThreadByID(tid, false));
+        if (!thread_sp)
+        {
+            thread_sp.reset(new FreeBSDThread(*this, tid));
+            if (log)
+                log->Printf("ProcessFreeBSD::%s new tid = %" PRIu64, __FUNCTION__, tid);
+        }
+        else
+        {
+            if (log)
+                log->Printf("ProcessFreeBSD::%s existing tid = %" PRIu64, __FUNCTION__, tid);
+        }
+        new_thread_list.AddThread(thread_sp);
+    }
+    for (size_t i = 0; i < old_thread_list_copy.GetSize(false); ++i)
+    {
+        ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex(i, false));
+        if (old_thread_sp)
+        {
+            if (log)
+                log->Printf("ProcessFreeBSD::%s remove tid", __FUNCTION__);
+        }
+    }
 
-    new_thread_list.AddThread(thread_sp);
+    return true;
+}
 
-    return has_updated; // the list has been updated
+Error
+ProcessFreeBSD::WillResume()
+{
+    m_suspend_tids.clear();
+    m_run_tids.clear();
+    m_step_tids.clear();
+    return ProcessPOSIX::WillResume();
 }
+
+void
+ProcessFreeBSD::SendMessage(const ProcessMessage &message)
+{
+    Mutex::Locker lock(m_message_mutex);
+
+    switch (message.GetKind())
+    {
+    case ProcessMessage::eInvalidMessage:
+        return;
+
+    case ProcessMessage::eAttachMessage:
+        SetPrivateState(eStateStopped);
+        return;
+
+    case ProcessMessage::eLimboMessage:
+    case ProcessMessage::eExitMessage:
+        m_exit_status = message.GetExitStatus();
+        SetExitStatus(m_exit_status, NULL);
+        break;
+
+    case ProcessMessage::eSignalMessage:
+    case ProcessMessage::eSignalDeliveredMessage:
+    case ProcessMessage::eBreakpointMessage:
+    case ProcessMessage::eTraceMessage:
+    case ProcessMessage::eWatchpointMessage:
+    case ProcessMessage::eCrashMessage:
+        SetPrivateState(eStateStopped);
+        break;
+
+    case ProcessMessage::eNewThreadMessage:
+        assert(0 && "eNewThreadMessage unexpected on FreeBSD");
+        break;
+
+    case ProcessMessage::eExecMessage:
+        SetPrivateState(eStateStopped);
+        break;
+    }
+
+    m_message_queue.push(message);
+}
+

Modified: lldb/trunk/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h?rev=196787&r1=196786&r2=196787&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h (original)
+++ lldb/trunk/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h Mon Dec  9 09:51:17 2013
@@ -60,6 +60,15 @@ public:
     virtual bool
     UpdateThreadList(lldb_private::ThreadList &old_thread_list, lldb_private::ThreadList &new_thread_list);
 
+    virtual lldb_private::Error
+    DoResume();
+
+    virtual lldb_private::Error
+    WillResume();
+
+    virtual void
+    SendMessage(const ProcessMessage &message);
+
     //------------------------------------------------------------------
     // PluginInterface protocol
     //------------------------------------------------------------------
@@ -80,6 +89,16 @@ public:
     EnablePluginLogging(lldb_private::Stream *strm,
                         lldb_private::Args &command);
 
+protected:
+    friend class FreeBSDThread;
+
+    typedef std::vector<lldb::tid_t> tid_collection;
+    tid_collection m_suspend_tids;
+    tid_collection m_run_tids;
+    tid_collection m_step_tids;
+
+    int m_resume_signo;
+
 };
 
 #endif  // liblldb_ProcessFreeBSD_H_

Modified: lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp?rev=196787&r1=196786&r2=196787&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp (original)
+++ lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp Mon Dec  9 09:51:17 2013
@@ -560,6 +560,31 @@ LwpInfoOperation::Execute(ProcessMonitor
 }
 
 //------------------------------------------------------------------------------
+/// @class ThreadSuspendOperation
+/// @brief Implements ProcessMonitor::ThreadSuspend.
+class ThreadSuspendOperation : public Operation
+{
+public:
+    ThreadSuspendOperation(lldb::tid_t tid, bool suspend, bool &result)
+        : m_tid(tid), m_suspend(suspend), m_result(result) { }
+
+    void Execute(ProcessMonitor *monitor);
+
+private:
+    lldb::tid_t m_tid;
+    bool m_suspend;
+    bool &m_result;
+} ;
+
+void
+ThreadSuspendOperation::Execute(ProcessMonitor *monitor)
+{
+    m_result = !PTRACE(m_suspend ? PT_SUSPEND : PT_RESUME, m_tid, NULL, 0);
+}
+
+
+
+//------------------------------------------------------------------------------
 /// @class EventMessageOperation
 /// @brief Implements ProcessMonitor::GetEventMessage.
 class EventMessageOperation : public Operation
@@ -1041,6 +1066,29 @@ FINISH:
     return args->m_error.Success();
 }
 
+size_t
+ProcessMonitor::GetCurrentThreadIDs(std::vector<lldb::tid_t>&thread_ids)
+{
+    lwpid_t *tids;
+    int tdcnt;
+
+    thread_ids.clear();
+
+    tdcnt = PTRACE(PT_GETNUMLWPS, m_pid, NULL, 0);
+    if (tdcnt <= 0)
+        return 0;
+    tids = (lwpid_t *)malloc(tdcnt * sizeof(*tids));
+    if (tids == NULL)
+        return 0;
+    if (PTRACE(PT_GETLWPLIST, m_pid, (void *)tids, tdcnt) < 0) {
+        free(tids);
+        return 0;
+    }
+    thread_ids = std::vector<lldb::tid_t>(tids, tids + tdcnt);
+    free(tids);
+    return thread_ids.size();
+}
+
 bool
 ProcessMonitor::MonitorCallback(void *callback_baton,
                                 lldb::pid_t pid,
@@ -1073,11 +1121,11 @@ ProcessMonitor::MonitorCallback(void *ca
         switch (plwp.pl_siginfo.si_signo)
         {
         case SIGTRAP:
-            message = MonitorSIGTRAP(monitor, &plwp.pl_siginfo, pid);
+            message = MonitorSIGTRAP(monitor, &plwp.pl_siginfo, plwp.pl_lwpid);
             break;
             
         default:
-            message = MonitorSignal(monitor, &plwp.pl_siginfo, pid);
+            message = MonitorSignal(monitor, &plwp.pl_siginfo, plwp.pl_lwpid);
             break;
         }
 
@@ -1090,7 +1138,7 @@ ProcessMonitor::MonitorCallback(void *ca
 
 ProcessMessage
 ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor,
-                               const siginfo_t *info, lldb::pid_t pid)
+                               const siginfo_t *info, lldb::tid_t tid)
 {
     ProcessMessage message;
 
@@ -1111,26 +1159,26 @@ ProcessMonitor::MonitorSIGTRAP(ProcessMo
         // state of "limbo" until we are explicitly commanded to detach,
         // destroy, resume, etc.
         unsigned long data = 0;
-        if (!monitor->GetEventMessage(pid, &data))
+        if (!monitor->GetEventMessage(tid, &data))
             data = -1;
         if (log)
-            log->Printf ("ProcessMonitor::%s() received exit? event, data = %lx, pid = %" PRIu64, __FUNCTION__, data, pid);
-        message = ProcessMessage::Limbo(pid, (data >> 8));
+            log->Printf ("ProcessMonitor::%s() received exit? event, data = %lx, tid = %" PRIu64, __FUNCTION__, data, tid);
+        message = ProcessMessage::Limbo(tid, (data >> 8));
         break;
     }
 
     case 0:
     case TRAP_TRACE:
         if (log)
-            log->Printf ("ProcessMonitor::%s() received trace event, pid = %" PRIu64, __FUNCTION__, pid);
-        message = ProcessMessage::Trace(pid);
+            log->Printf ("ProcessMonitor::%s() received trace event, tid = %" PRIu64, __FUNCTION__, tid);
+        message = ProcessMessage::Trace(tid);
         break;
 
     case SI_KERNEL:
     case TRAP_BRKPT:
         if (log)
-            log->Printf ("ProcessMonitor::%s() received breakpoint event, pid = %" PRIu64, __FUNCTION__, pid);
-        message = ProcessMessage::Break(pid);
+            log->Printf ("ProcessMonitor::%s() received breakpoint event, tid = %" PRIu64, __FUNCTION__, tid);
+        message = ProcessMessage::Break(tid);
         break;
     }
 
@@ -1139,7 +1187,7 @@ ProcessMonitor::MonitorSIGTRAP(ProcessMo
 
 ProcessMessage
 ProcessMonitor::MonitorSignal(ProcessMonitor *monitor,
-                              const siginfo_t *info, lldb::pid_t pid)
+                              const siginfo_t *info, lldb::tid_t tid)
 {
     ProcessMessage message;
     int signo = info->si_signo;
@@ -1163,9 +1211,9 @@ ProcessMonitor::MonitorSignal(ProcessMon
                             "SI_USER",
                             info->si_pid);
         if (info->si_pid == getpid())
-            return ProcessMessage::SignalDelivered(pid, signo);
+            return ProcessMessage::SignalDelivered(tid, signo);
         else
-            return ProcessMessage::Signal(pid, signo);
+            return ProcessMessage::Signal(tid, signo);
     }
 
     if (log)
@@ -1174,30 +1222,30 @@ ProcessMonitor::MonitorSignal(ProcessMon
     if (signo == SIGSEGV) {
         lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
         ProcessMessage::CrashReason reason = GetCrashReasonForSIGSEGV(info);
-        return ProcessMessage::Crash(pid, reason, signo, fault_addr);
+        return ProcessMessage::Crash(tid, reason, signo, fault_addr);
     }
 
     if (signo == SIGILL) {
         lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
         ProcessMessage::CrashReason reason = GetCrashReasonForSIGILL(info);
-        return ProcessMessage::Crash(pid, reason, signo, fault_addr);
+        return ProcessMessage::Crash(tid, reason, signo, fault_addr);
     }
 
     if (signo == SIGFPE) {
         lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
         ProcessMessage::CrashReason reason = GetCrashReasonForSIGFPE(info);
-        return ProcessMessage::Crash(pid, reason, signo, fault_addr);
+        return ProcessMessage::Crash(tid, reason, signo, fault_addr);
     }
 
     if (signo == SIGBUS) {
         lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
         ProcessMessage::CrashReason reason = GetCrashReasonForSIGBUS(info);
-        return ProcessMessage::Crash(pid, reason, signo, fault_addr);
+        return ProcessMessage::Crash(tid, reason, signo, fault_addr);
     }
 
     // Everything else is "normal" and does not require any special action on
     // our part.
-    return ProcessMessage::Signal(pid, signo);
+    return ProcessMessage::Signal(tid, signo);
 }
 
 ProcessMessage::CrashReason
@@ -1506,6 +1554,15 @@ ProcessMonitor::GetLwpInfo(lldb::tid_t t
     DoOperation(&op);
     return result;
 }
+
+bool
+ProcessMonitor::ThreadSuspend(lldb::tid_t tid, bool suspend)
+{
+    bool result;
+    ThreadSuspendOperation op(tid, suspend, result);
+    DoOperation(&op);
+    return result;
+}
 
 bool
 ProcessMonitor::GetEventMessage(lldb::tid_t tid, unsigned long *message)

Modified: lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.h?rev=196787&r1=196786&r2=196787&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.h (original)
+++ lldb/trunk/source/Plugins/Process/FreeBSD/ProcessMonitor.h Mon Dec  9 09:51:17 2013
@@ -164,11 +164,19 @@ public:
     bool
     ReadThreadPointer(lldb::tid_t tid, lldb::addr_t &value);
 
+    /// Returns current thread IDs in process
+    size_t
+    GetCurrentThreadIDs(std::vector<lldb::tid_t> &thread_ids);
+
     /// Writes a ptrace_lwpinfo structure corresponding to the given thread ID
     /// to the memory region pointed to by @p lwpinfo.
     bool
     GetLwpInfo(lldb::tid_t tid, void *lwpinfo, int &error_no);
 
+    /// Suspends or unsuspends a thread prior to process resume or step.
+    bool
+    ThreadSuspend(lldb::tid_t tid, bool suspend);
+
     /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
     /// corresponding to the given thread IDto the memory pointed to by @p
     /// message.

Modified: lldb/trunk/source/Plugins/Process/Linux/LinuxThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/LinuxThread.cpp?rev=196787&r1=196786&r2=196787&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/LinuxThread.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/LinuxThread.cpp Mon Dec  9 09:51:17 2013
@@ -31,6 +31,43 @@ LinuxThread::~LinuxThread()
 //------------------------------------------------------------------------------
 // ProcessInterface protocol.
 
+bool
+LinuxThread::Resume()
+{
+    lldb::StateType resume_state = GetResumeState();
+    ProcessMonitor &monitor = GetMonitor();
+    bool status;
+
+    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
+    if (log)
+        log->Printf ("POSIXThread::%s (), resume_state = %s", __FUNCTION__,
+                         StateAsCString(resume_state));
+
+    switch (resume_state)
+    {
+    default:
+        assert(false && "Unexpected state for resume!");
+        status = false;
+        break;
+
+    case lldb::eStateRunning:
+        SetState(resume_state);
+        status = monitor.Resume(GetID(), GetResumeSignal());
+        break;
+
+    case lldb::eStateStepping:
+        SetState(resume_state);
+        status = monitor.SingleStep(GetID(), GetResumeSignal());
+        break;
+    case lldb::eStateStopped:
+    case lldb::eStateSuspended:
+        status = true;
+        break;
+    }
+
+    return status;
+}
+
 void
 LinuxThread::RefreshStateAfterStop()
 {
@@ -60,4 +97,4 @@ LinuxThread::TraceNotify(const ProcessMe
     }
     
     POSIXThread::TraceNotify (message);
-}
\ No newline at end of file
+}

Modified: lldb/trunk/source/Plugins/Process/Linux/LinuxThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/LinuxThread.h?rev=196787&r1=196786&r2=196787&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/LinuxThread.h (original)
+++ lldb/trunk/source/Plugins/Process/Linux/LinuxThread.h Mon Dec  9 09:51:17 2013
@@ -31,7 +31,10 @@ public:
     //--------------------------------------------------------------------------
     // LinuxThread internal API.
 
-    // POSIXThread override
+    // POSIXThread overrides
+    virtual bool
+    LinuxThread::Resume();
+
     virtual void
     RefreshStateAfterStop();
 

Modified: lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.cpp?rev=196787&r1=196786&r2=196787&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.cpp Mon Dec  9 09:51:17 2013
@@ -166,6 +166,31 @@ ProcessLinux::DoDetach(bool keep_stopped
 
 
 // ProcessPOSIX override
+Error
+ProcessLinux::DoResume()
+{
+    StateType state = GetPrivateState();
+
+    assert(state == eStateStopped);
+
+    SetPrivateState(eStateRunning);
+
+    bool did_resume = false;
+
+    Mutex::Locker lock(m_thread_list.GetMutex());
+
+    uint32_t thread_count = m_thread_list.GetSize(false);
+    for (uint32_t i = 0; i < thread_count; ++i)
+    {
+        POSIXThread *thread = static_cast<POSIXThread*>(
+            m_thread_list.GetThreadAtIndex(i, false).get());
+        did_resume = thread->Resume() || did_resume;
+    }
+    assert(did_resume && "Process resume failed!");
+
+    return Error();
+}
+
 void
 ProcessLinux::StopAllThreads(lldb::tid_t stop_tid)
 {
@@ -221,3 +246,103 @@ ProcessLinux::CanDebug(Target &target, b
     return ProcessPOSIX::CanDebug(target, plugin_specified_by_name);
 }
 
+void
+ProcessLinux::SendMessage(const ProcessMessage &message)
+{
+    Mutex::Locker lock(m_message_mutex);
+
+    Mutex::Locker thread_lock(m_thread_list.GetMutex());
+
+    POSIXThread *thread = static_cast<POSIXThread*>(
+        m_thread_list.FindThreadByID(message.GetTID(), false).get());
+
+    switch (message.GetKind())
+    {
+    case ProcessMessage::eInvalidMessage:
+        return;
+
+    case ProcessMessage::eAttachMessage:
+        SetPrivateState(eStateStopped);
+        return;
+
+    case ProcessMessage::eLimboMessage:
+        assert(thread);
+        thread->SetState(eStateStopped);
+        if (message.GetTID() == GetID())
+        {
+            m_exit_status = message.GetExitStatus();
+            if (m_exit_now)
+            {
+                SetPrivateState(eStateExited);
+                m_monitor->Detach(GetID());
+            }
+            else
+            {
+                StopAllThreads(message.GetTID());
+                SetPrivateState(eStateStopped);
+            }
+        }
+        else
+        {
+            StopAllThreads(message.GetTID());
+            SetPrivateState(eStateStopped);
+        }
+        break;
+
+    case ProcessMessage::eExitMessage:
+        assert(thread);
+        thread->SetState(eStateExited);
+        // FIXME: I'm not sure we need to do this.
+        if (message.GetTID() == GetID())
+        {
+            m_exit_status = message.GetExitStatus();
+            SetExitStatus(m_exit_status, NULL);
+        }
+        else if (!IsAThreadRunning())
+            SetPrivateState(eStateStopped);
+        break;
+
+    case ProcessMessage::eSignalMessage:
+    case ProcessMessage::eSignalDeliveredMessage:
+        if (message.GetSignal() == SIGSTOP &&
+            AddThreadForInitialStopIfNeeded(message.GetTID()))
+            return;
+        // Intentional fall-through
+
+    case ProcessMessage::eBreakpointMessage:
+    case ProcessMessage::eTraceMessage:
+    case ProcessMessage::eWatchpointMessage:
+    case ProcessMessage::eCrashMessage:
+        assert(thread);
+        thread->SetState(eStateStopped);
+        StopAllThreads(message.GetTID());
+        break;
+
+    case ProcessMessage::eNewThreadMessage:
+    {
+        lldb::tid_t  new_tid = message.GetChildTID();
+        if (WaitingForInitialStop(new_tid))
+        {
+            m_monitor->WaitForInitialTIDStop(new_tid);
+        }
+        assert(thread);
+        thread->SetState(eStateStopped);
+        StopAllThreads(message.GetTID());
+        SetPrivateState(eStateStopped);
+        break;
+    }
+
+    case ProcessMessage::eExecMessage:
+    {
+        assert(thread);
+        thread->SetState(eStateStopped);
+        StopAllThreads(message.GetTID());
+        SetPrivateState(eStateStopped);
+        break;
+    }
+    }
+
+
+    m_message_queue.push(message);
+}
+

Modified: lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.h?rev=196787&r1=196786&r2=196787&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.h (original)
+++ lldb/trunk/source/Plugins/Process/Linux/ProcessLinux.h Mon Dec  9 09:51:17 2013
@@ -101,6 +101,9 @@ public:
     virtual POSIXThread *
     CreateNewPOSIXThread(lldb_private::Process &process, lldb::tid_t tid);
 
+    virtual void
+    SendMessage(const ProcessMessage &message);
+
 private:
 
     /// Linux-specific signal set.

Modified: lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp?rev=196787&r1=196786&r2=196787&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.cpp Mon Dec  9 09:51:17 2013
@@ -83,6 +83,7 @@ POSIXThread::GetMonitor()
     return process.GetMonitor();
 }
 
+// Overridden by FreeBSDThread; this is used only on Linux.
 void
 POSIXThread::RefreshStateAfterStop()
 {
@@ -257,6 +258,7 @@ POSIXThread::GetUnwinder()
     return m_unwinder_ap.get();
 }
 
+// Overridden by FreeBSDThread; this is used only on Linux.
 void
 POSIXThread::WillResume(lldb::StateType resume_state)
 {
@@ -274,43 +276,6 @@ POSIXThread::DidStop()
     // Don't set the thread state to stopped unless we really stopped.
 }
 
-bool
-POSIXThread::Resume()
-{
-    lldb::StateType resume_state = GetResumeState();
-    ProcessMonitor &monitor = GetMonitor();
-    bool status;
-
-    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
-    if (log)
-        log->Printf ("POSIXThread::%s (), resume_state = %s", __FUNCTION__,
-                         StateAsCString(resume_state));
-
-    switch (resume_state)
-    {
-    default:
-        assert(false && "Unexpected state for resume!");
-        status = false;
-        break;
-
-    case lldb::eStateRunning:
-        SetState(resume_state);
-        status = monitor.Resume(GetID(), GetResumeSignal());
-        break;
-
-    case lldb::eStateStepping:
-        SetState(resume_state);
-        status = monitor.SingleStep(GetID(), GetResumeSignal());
-        break;
-    case lldb::eStateStopped:
-    case lldb::eStateSuspended:
-        status = true;
-        break;
-    }
-
-    return status;
-}
-
 void
 POSIXThread::Notify(const ProcessMessage &message)
 {

Modified: lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.h?rev=196787&r1=196786&r2=196787&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.h (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/POSIXThread.h Mon Dec  9 09:51:17 2013
@@ -79,8 +79,6 @@ public:
     //--------------------------------------------------------------------------
     // These methods form a specialized interface to POSIX threads.
     //
-    bool Resume();
-
     void Notify(const ProcessMessage &message);
 
     //--------------------------------------------------------------------------

Modified: lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.cpp?rev=196787&r1=196786&r2=196787&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.cpp (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.cpp Mon Dec  9 09:51:17 2013
@@ -259,31 +259,6 @@ ProcessPOSIX::DidLaunch()
 {
 }
 
-Error
-ProcessPOSIX::DoResume()
-{
-    StateType state = GetPrivateState();
-
-    assert(state == eStateStopped);
-
-    SetPrivateState(eStateRunning);
-
-    bool did_resume = false;
-
-    Mutex::Locker lock(m_thread_list.GetMutex());
-
-    uint32_t thread_count = m_thread_list.GetSize(false);
-    for (uint32_t i = 0; i < thread_count; ++i)
-    {
-        POSIXThread *thread = static_cast<POSIXThread*>(
-            m_thread_list.GetThreadAtIndex(i, false).get());
-        did_resume = thread->Resume() || did_resume;
-    }
-    assert(did_resume && "Process resume failed!");
-
-    return Error();
-}
-
 addr_t
 ProcessPOSIX::GetImageInfoAddress()
 {
@@ -376,107 +351,6 @@ ProcessPOSIX::DoDidExec()
     }
 }
 
-void
-ProcessPOSIX::SendMessage(const ProcessMessage &message)
-{
-    Mutex::Locker lock(m_message_mutex);
-
-    Mutex::Locker thread_lock(m_thread_list.GetMutex());
-
-    POSIXThread *thread = static_cast<POSIXThread*>(
-        m_thread_list.FindThreadByID(message.GetTID(), false).get());
-
-    switch (message.GetKind())
-    {
-    case ProcessMessage::eInvalidMessage:
-        return;
-
-    case ProcessMessage::eAttachMessage:
-        SetPrivateState(eStateStopped);
-        return;
-
-    case ProcessMessage::eLimboMessage:
-        assert(thread);
-        thread->SetState(eStateStopped);
-        if (message.GetTID() == GetID())
-        {
-            m_exit_status = message.GetExitStatus();
-            if (m_exit_now)
-            {
-                SetPrivateState(eStateExited);
-                m_monitor->Detach(GetID());
-            }
-            else
-            {
-                StopAllThreads(message.GetTID());
-                SetPrivateState(eStateStopped);
-            }
-        }
-        else
-        {
-            StopAllThreads(message.GetTID());
-            SetPrivateState(eStateStopped);
-        }
-        break;
-
-    case ProcessMessage::eExitMessage:
-        assert(thread);
-        thread->SetState(eStateExited);
-        // FIXME: I'm not sure we need to do this.
-        if (message.GetTID() == GetID())
-        {
-            m_exit_status = message.GetExitStatus();
-            SetExitStatus(m_exit_status, NULL);
-        }
-        else if (!IsAThreadRunning())
-            SetPrivateState(eStateStopped);
-        break;
-
-    case ProcessMessage::eSignalMessage:
-    case ProcessMessage::eSignalDeliveredMessage:
-        if (message.GetSignal() == SIGSTOP &&
-            AddThreadForInitialStopIfNeeded(message.GetTID()))
-            return;
-        // Intentional fall-through
-
-    case ProcessMessage::eBreakpointMessage:
-    case ProcessMessage::eTraceMessage:
-    case ProcessMessage::eWatchpointMessage:
-    case ProcessMessage::eCrashMessage:
-        assert(thread);
-        thread->SetState(eStateStopped);
-        StopAllThreads(message.GetTID());
-        SetPrivateState(eStateStopped);
-        break;
-
-    case ProcessMessage::eNewThreadMessage:
-    {
-        lldb::tid_t  new_tid = message.GetChildTID();
-        if (WaitingForInitialStop(new_tid))
-        {
-            m_monitor->WaitForInitialTIDStop(new_tid);
-        }
-        assert(thread);
-        thread->SetState(eStateStopped);
-        StopAllThreads(message.GetTID());
-        SetPrivateState(eStateStopped);
-        break;
-    }
-
-    case ProcessMessage::eExecMessage:
-    {
-        assert(thread);
-        thread->SetState(eStateStopped);
-        StopAllThreads(message.GetTID());
-        SetPrivateState(eStateStopped);
-        break;
-    }
-    }
-
-
-    m_message_queue.push(message);
-}
-
 void 
 ProcessPOSIX::StopAllThreads(lldb::tid_t stop_tid)
 {

Modified: lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.h?rev=196787&r1=196786&r2=196787&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.h (original)
+++ lldb/trunk/source/Plugins/Process/POSIX/ProcessPOSIX.h Mon Dec  9 09:51:17 2013
@@ -64,7 +64,7 @@ public:
     DidLaunch();
 
     virtual lldb_private::Error
-    DoResume();
+    DoResume() = 0;
 
     virtual lldb_private::Error
     DoHalt(bool &caused_stop);
@@ -148,7 +148,8 @@ public:
     // ProcessPOSIX internal API.
 
     /// Registers the given message with this process.
-    void SendMessage(const ProcessMessage &message);
+    virtual void
+    SendMessage(const ProcessMessage &message) = 0;
 
     ProcessMonitor &
     GetMonitor() { assert(m_monitor); return *m_monitor; }





More information about the lldb-commits mailing list