<rdar://problem/14526890>

Fixed a crasher when using memory threads where a thread is sticking around too long and was causing problems when it didn't have a thread plan. 

llvm-svn: 187395
diff --git a/lldb/source/Target/ThreadPlan.cpp b/lldb/source/Target/ThreadPlan.cpp
index ba35db1..11240db 100644
--- a/lldb/source/Target/ThreadPlan.cpp
+++ b/lldb/source/Target/ThreadPlan.cpp
@@ -210,3 +210,144 @@
     else
         return GetPlanRunState();
 }
+
+//----------------------------------------------------------------------
+// ThreadPlanNull
+//----------------------------------------------------------------------
+
+ThreadPlanNull::ThreadPlanNull (Thread &thread) :
+    ThreadPlan (ThreadPlan::eKindNull,
+                "Null Thread Plan",
+                thread,
+                eVoteNoOpinion,
+                eVoteNoOpinion)
+{
+}
+
+ThreadPlanNull::~ThreadPlanNull ()
+{
+}
+
+void
+ThreadPlanNull::GetDescription (Stream *s,
+                                lldb::DescriptionLevel level)
+{
+    s->PutCString("Null thread plan - thread has been destroyed.");
+}
+
+bool
+ThreadPlanNull::ValidatePlan (Stream *error)
+{
+#ifdef LLDB_CONFIGURATION_DEBUG
+    fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%llx, ptid = 0x%llx)",
+            __PRETTY_FUNCTION__,
+            m_thread.GetID(),
+            m_thread.GetProtocolID());
+#else
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
+    if (log)
+        log->Error("%s called on thread that has been destroyed (tid = 0x%llx, ptid = 0x%llx)",
+                    __PRETTY_FUNCTION__,
+                    m_thread.GetID(),
+                    m_thread.GetProtocolID());
+#endif
+    return true;
+}
+
+bool
+ThreadPlanNull::ShouldStop (Event *event_ptr)
+{
+#ifdef LLDB_CONFIGURATION_DEBUG
+    fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%llx, ptid = 0x%llx)",
+            __PRETTY_FUNCTION__,
+            m_thread.GetID(),
+            m_thread.GetProtocolID());
+#else
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
+    if (log)
+        log->Error("%s called on thread that has been destroyed (tid = 0x%llx, ptid = 0x%llx)",
+                    __PRETTY_FUNCTION__,
+                    m_thread.GetID(),
+                    m_thread.GetProtocolID());
+#endif
+    return true;
+}
+
+bool
+ThreadPlanNull::WillStop ()
+{
+#ifdef LLDB_CONFIGURATION_DEBUG
+    fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%llx, ptid = 0x%llx)",
+            __PRETTY_FUNCTION__,
+            m_thread.GetID(),
+            m_thread.GetProtocolID());
+#else
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
+    if (log)
+        log->Error("%s called on thread that has been destroyed (tid = 0x%llx, ptid = 0x%llx)",
+                    __PRETTY_FUNCTION__,
+                    m_thread.GetID(),
+                    m_thread.GetProtocolID());
+#endif
+    return true;
+}
+
+bool
+ThreadPlanNull::DoPlanExplainsStop (Event *event_ptr)
+{
+#ifdef LLDB_CONFIGURATION_DEBUG
+    fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%llx, ptid = 0x%llx)",
+            __PRETTY_FUNCTION__,
+            m_thread.GetID(),
+            m_thread.GetProtocolID());
+#else
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
+    if (log)
+        log->Error("%s called on thread that has been destroyed (tid = 0x%llx, ptid = 0x%llx)",
+                   __PRETTY_FUNCTION__,
+                   m_thread.GetID(),
+                   m_thread.GetProtocolID());
+#endif
+    return true;
+}
+
+// The null plan is never done.
+bool
+ThreadPlanNull::MischiefManaged ()
+{
+    // The null plan is never done.
+#ifdef LLDB_CONFIGURATION_DEBUG
+    fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%llx, ptid = 0x%llx)",
+            __PRETTY_FUNCTION__,
+            m_thread.GetID(),
+            m_thread.GetProtocolID());
+#else
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
+    if (log)
+        log->Error("%s called on thread that has been destroyed (tid = 0x%llx, ptid = 0x%llx)",
+                   __PRETTY_FUNCTION__,
+                   m_thread.GetID(),
+                   m_thread.GetProtocolID());
+#endif
+    return false;
+}
+
+lldb::StateType
+ThreadPlanNull::GetPlanRunState ()
+{
+    // Not sure what to return here.  This is a dead thread.
+#ifdef LLDB_CONFIGURATION_DEBUG
+    fprintf(stderr, "error: %s called on thread that has been destroyed (tid = 0x%llx, ptid = 0x%llx)",
+            __PRETTY_FUNCTION__,
+            m_thread.GetID(),
+            m_thread.GetProtocolID());
+#else
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
+    if (log)
+        log->Error("%s called on thread that has been destroyed (tid = 0x%llx, ptid = 0x%llx)",
+                   __PRETTY_FUNCTION__,
+                   m_thread.GetID(),
+                   m_thread.GetProtocolID());
+#endif
+    return eStateRunning;
+}