[Lldb-commits] [lldb] r127709 - in /lldb/branches/apple/calcite/lldb/source/Plugins: Process/gdb-remote/GDBRemoteCommunication.cpp Process/gdb-remote/GDBRemoteCommunication.h Process/gdb-remote/ProcessGDBRemote.cpp Process/gdb-remote/ProcessGDBRemoteLog.cpp Process/gdb-remote/ProcessGDBRemoteLog.h SymbolFile/DWARF/UniqueDWARFASTType.cpp

Greg Clayton gclayton at apple.com
Tue Mar 15 16:08:25 PDT 2011


Author: gclayton
Date: Tue Mar 15 18:08:25 2011
New Revision: 127709

URL: http://llvm.org/viewvc/llvm-project?rev=127709&view=rev
Log:
Fixed a race condition withing GDB remote where interrupting an executing
process could result in an error being returned from a send packet and
wait for response if the packet was sent asynchronously. 

Also patched an infinite loop found by Caroline Tice from the previous
unique type fix.


Modified:
    lldb/branches/apple/calcite/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
    lldb/branches/apple/calcite/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
    lldb/branches/apple/calcite/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/branches/apple/calcite/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
    lldb/branches/apple/calcite/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
    lldb/branches/apple/calcite/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp

Modified: lldb/branches/apple/calcite/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/calcite/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp?rev=127709&r1=127708&r2=127709&view=diff
==============================================================================
--- lldb/branches/apple/calcite/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (original)
+++ lldb/branches/apple/calcite/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Tue Mar 15 18:08:25 2011
@@ -39,6 +39,7 @@
     m_sequence_mutex (Mutex::eMutexTypeRecursive),
     m_public_is_running (false),
     m_private_is_running (false),
+    m_interrupt_in_progress (false),
     m_async_mutex (Mutex::eMutexTypeRecursive),
     m_async_packet_predicate (false),
     m_async_packet (),
@@ -134,7 +135,7 @@
     TimeValue timeout_time;
     timeout_time = TimeValue::Now();
     timeout_time.OffsetWithSeconds (timeout_seconds);
-    LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+    LogSP log (ProcessGDBRemoteLog::GetLogIfAnyCategoriesSet (GDBR_LOG_PROCESS | GDBR_LOG_ASYNC));
 
     if (GetSequenceMutex (locker))
     {
@@ -284,6 +285,9 @@
                         process->BuildDynamicRegisterInfo (true);
                     }
 
+                    // If we are interrupting by sending a CTRL+C (0x03), the
+                    // we need to let the sender know that the interrupt happened
+                    m_interrupt_in_progress.SetValue (false, eBroadcastAlways);
                     // Privately notify any internal threads that we have stopped
                     // in case we wanted to interrupt our process, yet we might
                     // send a packet and continue without returning control to the
@@ -370,6 +374,10 @@
 
                 case 'W':
                 case 'X':
+                    // If we are interrupting by sending a CTRL+C (0x03), the
+                    // we need to let the sender know that the interrupt happened
+                    m_interrupt_in_progress.SetValue (false, eBroadcastAlways);
+
                     // process exited
                     state = eStateExited;
                     break;
@@ -408,6 +416,7 @@
     if (log)
         log->Printf ("GDBRemoteCommunication::%s () => %s", __FUNCTION__, StateAsCString(state));
     response.SetFilePos(0);
+    m_interrupt_in_progress.SetValue (false, eBroadcastAlways);
     m_private_is_running.SetValue (false, eBroadcastAlways);
     m_public_is_running.SetValue (false, eBroadcastAlways);
     return state;
@@ -508,61 +517,76 @@
 {
     sent_interrupt = false;
     timed_out = false;
-    LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
-
     if (IsRunning())
     {
+        LogSP process_or_async_log (ProcessGDBRemoteLog::GetLogIfAnyCategoriesSet (GDBR_LOG_PROCESS | GDBR_LOG_ASYNC));
+
         // Only send an interrupt if our debugserver is running...
         if (GetSequenceMutex (locker) == false)
         {
             // Someone has the mutex locked waiting for a response or for the
             // inferior to stop, so send the interrupt on the down low...
             char ctrl_c = '\x03';
+            bool success = false;
             ConnectionStatus status = eConnectionStatusSuccess;
-            TimeValue timeout;
-            if (seconds_to_wait_for_stop)
+            LogSP async_or_packet_log (ProcessGDBRemoteLog::GetLogIfAnyCategoriesSet (GDBR_LOG_PACKETS | GDBR_LOG_ASYNC));
+
+            if (m_interrupt_in_progress.GetValue())
             {
-                timeout = TimeValue::Now();
-                timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
+                success = true;
+                if (async_or_packet_log)
+                    async_or_packet_log->Printf ("interrupt already in progress");
             }
-            ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_PROCESS, "sending packet: \\x03");
-            size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
-            ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_PROCESS, "sent packet: \\x03");
-            if (bytes_written > 0)
+            else
+            {
+                m_interrupt_in_progress.SetValue (true, eBroadcastNever);
+                if (async_or_packet_log)
+                    async_or_packet_log->Printf ("send packet: \\x03");
+                size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
+                if (async_or_packet_log)
+                    async_or_packet_log->Printf ("send packet returned %zu", bytes_written);
+                success = bytes_written > 0;
+            }
+            
+            if (success)
             {
                 sent_interrupt = true;
                 if (seconds_to_wait_for_stop)
                 {
-                    if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
+                    TimeValue timeout;
+                    timeout = TimeValue::Now();
+                    timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
+                    if (m_interrupt_in_progress.WaitForValueEqualTo (false, &timeout, &timed_out))
                     {
-                        if (log)
-                            log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, private state stopped", __FUNCTION__);
-                        return true;
+                        if (process_or_async_log)
+                            process_or_async_log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, private state stopped", __FUNCTION__);
                     }
                     else
                     {
-                        if (log)
-                            log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, timed out wating for async thread resume", __FUNCTION__);
+                        if (process_or_async_log)
+                            process_or_async_log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, timed out wating for async thread resume", __FUNCTION__);
+                        success = false;
                     }
                 }
                 else
                 {
-                    if (log)
-                        log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, not waiting for stop...", __FUNCTION__);                    
-                    return true;
+                    if (process_or_async_log)
+                        process_or_async_log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, not waiting for stop...", __FUNCTION__);                    
                 }
             }
             else
             {
-                if (log)
-                    log->Printf ("GDBRemoteCommunication::%s () - failed to write interrupt", __FUNCTION__);
+                if (process_or_async_log)
+                    process_or_async_log->Printf ("GDBRemoteCommunication::%s () - failed to write interrupt", __FUNCTION__);
             }
-            return false;
+            
+            m_interrupt_in_progress.SetValue (false, eBroadcastNever);
+            return success;
         }
         else
         {
-            if (log)
-                log->Printf ("GDBRemoteCommunication::%s () - got sequence mutex without having to interrupt", __FUNCTION__);
+            if (process_or_async_log)
+                process_or_async_log->Printf ("GDBRemoteCommunication::%s () - got sequence mutex without having to interrupt", __FUNCTION__);
         }
     }
     return true;

Modified: lldb/branches/apple/calcite/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/calcite/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h?rev=127709&r1=127708&r2=127709&view=diff
==============================================================================
--- lldb/branches/apple/calcite/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h (original)
+++ lldb/branches/apple/calcite/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h Tue Mar 15 18:08:25 2011
@@ -273,6 +273,7 @@
     lldb_private::Mutex m_sequence_mutex;    // Restrict access to sending/receiving packets to a single thread at a time
     lldb_private::Predicate<bool> m_public_is_running;
     lldb_private::Predicate<bool> m_private_is_running;
+    lldb_private::Predicate<bool> m_interrupt_in_progress;
 
     // If we need to send a packet while the target is running, the m_async_XXX
     // member variables take care of making this happen.

Modified: lldb/branches/apple/calcite/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/calcite/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=127709&r1=127708&r2=127709&view=diff
==============================================================================
--- lldb/branches/apple/calcite/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/branches/apple/calcite/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Tue Mar 15 18:08:25 2011
@@ -1492,7 +1492,7 @@
                 {
                     uint8_t error_byte = response.GetError();
                     if (error_byte)
-                        error.SetErrorStringWithFormat("%x packet failed with error: %i (0x%2.2x).\n", packet, error_byte, error_byte);
+                        error.SetErrorStringWithFormat("'%s' packet failed with error: %i (0x%2.2x).\n", packet, error_byte, error_byte);
                 }
             }
         }

Modified: lldb/branches/apple/calcite/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/calcite/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp?rev=127709&r1=127708&r2=127709&view=diff
==============================================================================
--- lldb/branches/apple/calcite/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp (original)
+++ lldb/branches/apple/calcite/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp Tue Mar 15 18:08:25 2011
@@ -42,6 +42,19 @@
     return log;
 }
 
+LogSP
+ProcessGDBRemoteLog::GetLogIfAnyCategoriesSet (uint32_t mask)
+{
+    LogSP log(GetLog ());
+    if (log)
+    {
+        uint32_t log_mask = log->GetMask().Get();
+        if (log_mask & mask)
+            return log; 
+    }
+    return LogSP();
+}
+
 void
 ProcessGDBRemoteLog::DisableLog (Args &args, Stream *feedback_strm)
 {

Modified: lldb/branches/apple/calcite/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/calcite/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h?rev=127709&r1=127708&r2=127709&view=diff
==============================================================================
--- lldb/branches/apple/calcite/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h (original)
+++ lldb/branches/apple/calcite/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h Tue Mar 15 18:08:25 2011
@@ -38,6 +38,9 @@
     static lldb::LogSP
     GetLogIfAllCategoriesSet(uint32_t mask = 0);
 
+    static lldb::LogSP
+    GetLogIfAnyCategoriesSet (uint32_t mask = UINT32_MAX);
+
     static void
     DisableLog (lldb_private::Args &args, lldb_private::Stream *feedback_strm);
 

Modified: lldb/branches/apple/calcite/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/apple/calcite/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp?rev=127709&r1=127708&r2=127709&view=diff
==============================================================================
--- lldb/branches/apple/calcite/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp (original)
+++ lldb/branches/apple/calcite/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp Tue Mar 15 18:08:25 2011
@@ -43,12 +43,12 @@
                     // The type has the same name, and was defined on the same
                     // file and line. Now verify all of the parent DIEs match.
                     const DWARFDebugInfoEntry *parent_arg_die = die->GetParent();
-                    const DWARFDebugInfoEntry *parend_pos_die = pos->m_die->GetParent();
+                    const DWARFDebugInfoEntry *parent_pos_die = pos->m_die->GetParent();
                     bool match = true;
                     bool done = false;
-                    while (!done && match && parent_arg_die && parend_pos_die)
+                    while (!done && match && parent_arg_die && parent_pos_die)
                     {
-                        if (parent_arg_die->Tag() == parend_pos_die->Tag())
+                        if (parent_arg_die->Tag() == parent_pos_die->Tag())
                         {
                             const dw_tag_t tag = parent_arg_die->Tag();
                             switch (tag)
@@ -59,7 +59,7 @@
                             case DW_TAG_namespace:
                                 {
                                     const char *parent_arg_die_name = parent_arg_die->GetName(symfile, cu);
-                                    const char *parent_pos_die_name = parend_pos_die->GetName(pos->m_symfile, pos->m_cu);
+                                    const char *parent_pos_die_name = parent_pos_die->GetName(pos->m_symfile, pos->m_cu);
                                     if (strcmp (parent_arg_die_name, parent_pos_die_name))
                                         match = false;
                                 }
@@ -70,6 +70,8 @@
                                 break;
                             }
                         }
+                        parent_arg_die = parent_arg_die->GetParent();
+                        parent_pos_die = parent_pos_die->GetParent();
                     }
 
                     if (match)





More information about the lldb-commits mailing list