Added a test case that verifies that LLDB can debug across a process exec'ing itself into a new program. This currently is only enabled for Darwin since we exec from 64 bit to 32 bit and vice versa for 'x86_64' targets.

This can easily be adapted for linux and other platforms, but I didn't want to break any buildbots by assuming it will work.



git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@182428 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index ce1fd8d..fb539b1 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -1005,15 +1005,6 @@
     DidLaunchOrAttach ();
 }
 
-void
-ProcessGDBRemote::DoDidExec ()
-{
-    // The process exec'ed itself, figure out the dynamic loader, etc...
-    BuildDynamicRegisterInfo (true);
-    m_gdb_comm.ResetDiscoverableSettings();
-}
-
-
 
 Error
 ProcessGDBRemote::WillResume ()
@@ -1354,15 +1345,8 @@
             // register info before we lookup and threads and populate the expedited
             // register values so we need to know this right away so we can cleanup
             // and update our registers.
-            const bool did_exec = stop_packet.GetStringRef().find(";reason:exec;") != std::string::npos;
-
-            if (did_exec)
-            {
-                m_thread_list_real.Clear();
-                m_thread_list.Clear();
-            }
-
-            if (GetStopID() == 0 || did_exec)
+            const uint32_t stop_id = GetStopID();
+            if (stop_id == 0)
             {
                 // Our first stop, make sure we have a process ID, and also make
                 // sure we know about our registers
@@ -1519,6 +1503,7 @@
                 else
                 {
                     bool handled = false;
+                    bool did_exec = false;
                     if (!reason.empty())
                     {
                         if (reason.compare("trace") == 0)
@@ -1566,6 +1551,7 @@
                         }
                         else if (reason.compare("exec") == 0)
                         {
+                            did_exec = true;
                             thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithExec(*thread_sp));
                             handled = true;
                         }
@@ -1898,6 +1884,26 @@
     return error;
 }
 
+void
+ProcessGDBRemote::SetLastStopPacket (const StringExtractorGDBRemote &response)
+{
+    lldb_private::Mutex::Locker locker (m_last_stop_packet_mutex);
+    const bool did_exec = response.GetStringRef().find(";reason:exec;") != std::string::npos;
+    if (did_exec)
+    {
+        Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+        if (log)
+            log->Printf ("ProcessGDBRemote::SetLastStopPacket () - detected exec");
+
+        m_thread_list_real.Clear();
+        m_thread_list.Clear();
+        BuildDynamicRegisterInfo (true);
+        m_gdb_comm.ResetDiscoverableSettings();
+    }
+    m_last_stop_packet = response;
+}
+
+
 //------------------------------------------------------------------
 // Process Queries
 //------------------------------------------------------------------
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index b42a61d..ab8fef3 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -114,9 +114,6 @@
     virtual void
     DidAttach ();
 
-    virtual void
-    DoDidExec ();
-
     //------------------------------------------------------------------
     // PluginInterface protocol
     //------------------------------------------------------------------
@@ -289,11 +286,7 @@
     BuildDynamicRegisterInfo (bool force);
 
     void
-    SetLastStopPacket (const StringExtractorGDBRemote &response)
-    {
-        lldb_private::Mutex::Locker locker (m_last_stop_packet_mutex);
-        m_last_stop_packet = response;
-    }
+    SetLastStopPacket (const StringExtractorGDBRemote &response);
 
     //------------------------------------------------------------------
     /// Broadcaster event bits definitions.
diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp
index b86b140..5ed9a68 100644
--- a/source/Target/Process.cpp
+++ b/source/Target/Process.cpp
@@ -5588,8 +5588,6 @@
     m_allocated_memory_cache.Clear();
     m_language_runtimes.clear();
     m_thread_list.DiscardThreadPlans();
-    m_thread_list.Clear();
-    m_thread_list_real.Clear();
     m_memory_cache.Clear(true);
     DoDidExec();
     CompleteAttach ();
diff --git a/source/Target/Thread.cpp b/source/Target/Thread.cpp
index 9abf514..850fc80 100644
--- a/source/Target/Thread.cpp
+++ b/source/Target/Thread.cpp
@@ -442,6 +442,9 @@
         m_stop_info_stop_id = process_sp->GetStopID();
     else
         m_stop_info_stop_id = UINT32_MAX;
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
+    if (log)
+        log->Printf("%p: tid = 0x%llx: stop info = %s (stop_id = %u)\n", this, GetID(), stop_info_sp ? stop_info_sp->GetDescription() : "<NULL>", m_stop_info_stop_id);
 }
 
 void
diff --git a/source/Utility/StringExtractor.h b/source/Utility/StringExtractor.h
index df4a97a..0ded310 100644
--- a/source/Utility/StringExtractor.h
+++ b/source/Utility/StringExtractor.h
@@ -73,6 +73,12 @@
         return m_packet;
     }
 
+    const std::string &
+    GetStringRef () const
+    {
+        return m_packet;
+    }
+
     bool
     Empty()
     {