[Lldb-commits] [PATCH] Fix race condition in Target::Launch

Zachary Turner zturner at google.com
Mon Mar 23 13:14:30 PDT 2015


Hi jingham,

Based on the message at http://lists.cs.uiuc.edu/pipermail/lldb-dev/2015-March/007046.html, it looks like the global event listener is racing with the event thread to pull the process stop event in the case of synchronous execution.  This patch addresses this by *always* hijacking process events, and not restoring them until after *both* waits are complete.

With this patch, I can successfully use .lldbinit file to run a process.  It still does not fix the issue with the stack trace not displaying as discussed in http://lists.cs.uiuc.edu/pipermail/lldb-dev/2015-March/007033.html, but it seems to be a different but related issue, so I don't attempt to address it here.

http://reviews.llvm.org/D8562

Files:
  source/Target/Target.cpp

Index: source/Target/Target.cpp
===================================================================
--- source/Target/Target.cpp
+++ source/Target/Target.cpp
@@ -2594,35 +2594,50 @@
         if (launch_info.GetFlags().Test(eLaunchFlagStopAtEntry) == false)
         {
             ListenerSP hijack_listener_sp (launch_info.GetHijackListener());
+            if (!hijack_listener_sp)
+            {
+                hijack_listener_sp.reset(new Listener("lldb.Target.Launch.hijack"));
+                launch_info.SetHijackListener(hijack_listener_sp);
+                m_process_sp->HijackProcessEvents(hijack_listener_sp.get());
+            }
 
             StateType state = m_process_sp->WaitForProcessToStop (NULL, NULL, false, hijack_listener_sp.get(), NULL);
             
             if (state == eStateStopped)
             {
-                if (!synchronous_execution)
-                    m_process_sp->RestoreProcessEvents ();
-
-                error = m_process_sp->PrivateResume();
-
-                if (error.Success())
+                if (synchronous_execution)
                 {
-                    // there is a race condition where this thread will return up the call stack to the main command
-                    // handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
-                    // a chance to call PushProcessIOHandler()
-                    m_process_sp->SyncIOHandler(2000);
-
-                    if (synchronous_execution)
+                    error = m_process_sp->PrivateResume();
+                    if (error.Success())
                     {
+                        // there is a race condition where this thread will return up the call stack to the main command
+                        // handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
+                        // a chance to call PushProcessIOHandler()
+                        m_process_sp->SyncIOHandler(2000);
                         state = m_process_sp->WaitForProcessToStop (NULL, NULL, true, hijack_listener_sp.get(), stream);
                         const bool must_be_alive = false; // eStateExited is ok, so this must be false
                         if (!StateIsStoppedState(state, must_be_alive))
                         {
                             error.SetErrorStringWithFormat("process isn't stopped: %s", StateAsCString(state));
                         }
                     }
+                    m_process_sp->RestoreProcessEvents();
                 }
                 else
                 {
+                    m_process_sp->RestoreProcessEvents();
+                    error = m_process_sp->PrivateResume();
+                    if (error.Success())
+                    {
+                        // there is a race condition where this thread will return up the call stack to the main command
+                        // handler and show an (lldb) prompt before HandlePrivateEvent (from PrivateStateThread) has
+                        // a chance to call PushProcessIOHandler()
+                        m_process_sp->SyncIOHandler(2000);
+                    }
+                }
+
+                if (!error.Success())
+                {
                     Error error2;
                     error2.SetErrorStringWithFormat("process resume at entry point failed: %s", error.AsCString());
                     error = error2;

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D8562.22510.patch
Type: text/x-patch
Size: 3449 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20150323/6f99edf6/attachment.bin>


More information about the lldb-commits mailing list