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.

llvm-svn: 182428
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index ce1fd8d..fb539b1 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/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
 //------------------------------------------------------------------