All UnwindPlan objects are now passed around as shared pointers.

ArchDefaultUnwindPlan plug-in interfaces are now cached per architecture 
instead of being leaked for every frame.

Split the ArchDefaultUnwindPlan_x86 into ArchDefaultUnwindPlan_x86_64 and
ArchDefaultUnwindPlan_i386 interfaces.

There were sporadic crashes that were due to something leaking or being 
destroyed when doing stack crawls. This patch should clear up these issues.



git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@125541 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
index 0e29f2f..873974f 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -178,11 +178,12 @@
     return false;
 }
 
-void
+bool
 GDBRemoteRegisterContext::PrivateSetRegisterValue (uint32_t reg, StringExtractor &response)
 {
     const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg);
-    assert (reg_info);
+    if (reg_info == NULL)
+        return false;
 
     // Invalidate if needed
     InvalidateIfNeeded(false);
@@ -200,6 +201,7 @@
         // leave it as it was.
         m_reg_valid[reg] = false;
     }
+    return success;
 }
 
 
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
index 72c640f..ac6bbe5 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
@@ -228,7 +228,7 @@
 protected:
     friend class ThreadGDBRemote;
 
-    void
+    bool
     PrivateSetRegisterValue (uint32_t reg, StringExtractor &response);
     
     void
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 87bc0b9..cee2d3d 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -642,7 +642,6 @@
 
         StreamString strm;
 
-        ;
         // See if the GDB server supports the qHostInfo information
         const char *vendor = m_gdb_comm.GetVendorString().AsCString();
         const char *os_type = m_gdb_comm.GetOSString().AsCString();
@@ -1176,6 +1175,18 @@
     case 'T':
     case 'S':
         {
+            if (GetStopID() == 0)
+            {
+                // Our first stop, make sure we have a process ID, and also make
+                // sure we know about our registers
+                if (GetID() == LLDB_INVALID_PROCESS_ID)
+                {
+                    lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID (1);
+                    if (pid != LLDB_INVALID_PROCESS_ID)
+                        SetID (pid);
+                }
+                BuildDynamicRegisterInfo (true);
+            }
             // Stop with signal and thread info
             const uint8_t signo = stop_packet.GetHexU8();
             std::string name;
@@ -1209,7 +1220,14 @@
                 {
                     // thread in big endian hex
                     tid = Args::StringToUInt32 (value.c_str(), 0, 16);
+                    Mutex::Locker locker (m_thread_list.GetMutex ());
                     thread_sp = m_thread_list.FindThreadByID(tid, false);
+                    if (!thread_sp)
+                    {
+                        // Create the thread if we need to
+                        thread_sp.reset (new ThreadGDBRemote (*this, tid));
+                        m_thread_list.AddThread(thread_sp);
+                    }
                 }
                 else if (name.compare("hexname") == 0)
                 {
@@ -1242,7 +1260,15 @@
                             StringExtractor reg_value_extractor;
                             // Swap "value" over into "reg_value_extractor"
                             reg_value_extractor.GetStringRef().swap(value);
-                            static_cast<ThreadGDBRemote *> (thread_sp.get())->PrivateSetRegisterValue (reg, reg_value_extractor);
+                            if (!static_cast<ThreadGDBRemote *> (thread_sp.get())->PrivateSetRegisterValue (reg, reg_value_extractor))
+                            {
+                                Host::SetCrashDescriptionWithFormat("Setting thread register '%s' (decoded to %u (0x%x)) with value '%s' for stop packet: '%s'", 
+                                                                    name.c_str(), 
+                                                                    reg, 
+                                                                    reg, 
+                                                                    reg_value_extractor.GetStringRef().c_str(), 
+                                                                    stop_packet.GetStringRef().c_str());
+                            }
                         }
                     }
                 }
diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index 6acefff..635c00c 100644
--- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -26,7 +26,7 @@
 #include "Plugins/Process/Utility/UnwindLLDB.h"
 #include "Utility/StringExtractorGDBRemote.h"
 
-#ifdef __APPLE__
+#if defined(__APPLE__)
 #include "UnwindMacOSXFrameBackchain.h"
 #endif
 
@@ -98,6 +98,7 @@
     {
     case eStateSuspended:
     case eStateStopped:
+        // Don't append anything for threads that should stay stopped.
         break;
 
     case eStateRunning:
@@ -145,7 +146,7 @@
         {
             m_unwinder_ap.reset (new UnwindLLDB (*this));
         }
-#ifdef __APPLE__
+#if defined(__APPLE__)
         else
         {
             m_unwinder_ap.reset (new UnwindMacOSXFrameBackchain (*this));
@@ -207,12 +208,12 @@
     return reg_ctx_sp;
 }
 
-void
+bool
 ThreadGDBRemote::PrivateSetRegisterValue (uint32_t reg, StringExtractor &response)
 {
     GDBRemoteRegisterContext *gdb_reg_ctx = static_cast<GDBRemoteRegisterContext *>(GetRegisterContext ().get());
     assert (gdb_reg_ctx);
-    gdb_reg_ctx->PrivateSetRegisterValue (reg, response);
+    return gdb_reg_ctx->PrivateSetRegisterValue (reg, response);
 }
 
 bool
diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
index bf70848..c085b6c 100644
--- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
+++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
@@ -105,7 +105,7 @@
     virtual bool
     RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint);
 
-    void
+    bool
     PrivateSetRegisterValue (uint32_t reg, 
                              StringExtractor &response);