[Lldb-commits] [lldb] r125433 - in /lldb/trunk: include/lldb/lldb-enumerations.h source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp source/Plugins/Process/gdb-remote/ProcessGDBRemote.h source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp tools/debugserver/source/DNBLog.cpp

Greg Clayton gclayton at apple.com
Fri Feb 11 22:28:37 PST 2011


Author: gclayton
Date: Sat Feb 12 00:28:37 2011
New Revision: 125433

URL: http://llvm.org/viewvc/llvm-project?rev=125433&view=rev
Log:
Added the ability to detect which vCont packets (using the "vCont?") packet
are supported by the remote GDB target. We can also now deal with the lack of
vCont support and send packets that the remote GDB stub can use. We also error
out of the continue if LLDB tries to do something too complex when vCont isn't
supported.


Modified:
    lldb/trunk/include/lldb/lldb-enumerations.h
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
    lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
    lldb/trunk/tools/debugserver/source/DNBLog.cpp

Modified: lldb/trunk/include/lldb/lldb-enumerations.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=125433&r1=125432&r2=125433&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-enumerations.h (original)
+++ lldb/trunk/include/lldb/lldb-enumerations.h Sat Feb 12 00:28:37 2011
@@ -606,6 +606,18 @@
     eAppleObjC_V2 = 2
 } ObjCRuntimeVersions;
 
+    
+//----------------------------------------------------------------------
+// LazyBool is for boolean values that need to be calculated lazily.
+// Values start off set to eLazyBoolCalculate, and then they can be
+// calculated once and set to eLazyBoolNo or eLazyBoolYes.
+//----------------------------------------------------------------------
+typedef enum LazyBool {
+    eLazyBoolCalculate  = -1,
+    eLazyBoolNo         = 0,
+    eLazyBoolYes        = 1
+} LazyBool;
+
 } // namespace lldb
 
 

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp?rev=125433&r1=125432&r2=125433&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Sat Feb 12 00:28:37 2011
@@ -34,8 +34,15 @@
 //----------------------------------------------------------------------
 GDBRemoteCommunication::GDBRemoteCommunication() :
     Communication("gdb-remote.packets"),
-    m_send_acks (true),
-    m_thread_suffix_supported (false),
+    m_supports_not_sending_acks (eLazyBoolCalculate),
+    m_supports_thread_suffix (eLazyBoolCalculate),
+    m_supports_qHostInfo (eLazyBoolCalculate),
+    m_supports_vCont_all (eLazyBoolCalculate),
+    m_supports_vCont_any (eLazyBoolCalculate),
+    m_supports_vCont_c (eLazyBoolCalculate),
+    m_supports_vCont_C (eLazyBoolCalculate),
+    m_supports_vCont_s (eLazyBoolCalculate),
+    m_supports_vCont_S (eLazyBoolCalculate),
     m_rx_packet_listener ("gdbremote.rx_packet"),
     m_sequence_mutex (Mutex::eMutexTypeRecursive),
     m_public_is_running (false),
@@ -79,7 +86,7 @@
     int checksum = 0;
 
     // We only need to compute the checksum if we are sending acks
-    if (m_send_acks)
+    if (GetSendAcks ())
     {
         for (size_t i = 0; i < payload_length; ++i)
             checksum += payload[i];
@@ -109,6 +116,112 @@
     return Write (&nack_char, 1, status, NULL) == 1;
 }
 
+bool
+GDBRemoteCommunication::GetSendAcks ()
+{
+    if (m_supports_not_sending_acks == eLazyBoolCalculate)
+    {
+        StringExtractorGDBRemote response;
+        m_supports_not_sending_acks = eLazyBoolNo;
+        if (SendPacketAndWaitForResponse("QStartNoAckMode", response, 1, false))
+        {
+            if (response.IsOKPacket())
+                m_supports_not_sending_acks = eLazyBoolYes;
+        }
+    }
+    return m_supports_not_sending_acks != eLazyBoolYes;
+}
+
+void
+GDBRemoteCommunication::ResetDiscoverableSettings()
+{
+    m_supports_not_sending_acks = eLazyBoolCalculate;
+    m_supports_thread_suffix = eLazyBoolCalculate;
+    m_supports_qHostInfo = eLazyBoolCalculate;
+    m_supports_vCont_c = eLazyBoolCalculate;
+    m_supports_vCont_C = eLazyBoolCalculate;
+    m_supports_vCont_s = eLazyBoolCalculate;
+    m_supports_vCont_S = eLazyBoolCalculate;
+    m_arch.Clear();
+    m_os.Clear();
+    m_vendor.Clear();
+    m_byte_order = lldb::endian::InlHostByteOrder();
+    m_pointer_byte_size = 0;
+}
+
+
+bool
+GDBRemoteCommunication::GetThreadSuffixSupported ()
+{
+    if (m_supports_thread_suffix == eLazyBoolCalculate)
+    {
+        StringExtractorGDBRemote response;
+        m_supports_thread_suffix = eLazyBoolNo;
+        if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, 1, false))
+        {
+            if (response.IsOKPacket())
+                m_supports_thread_suffix = eLazyBoolYes;
+        }
+    }
+    return m_supports_thread_suffix;
+}
+bool
+GDBRemoteCommunication::GetVContSupported (char flavor)
+{
+    if (m_supports_vCont_c == eLazyBoolCalculate)
+    {
+        StringExtractorGDBRemote response;
+        m_supports_vCont_c = eLazyBoolNo;
+        m_supports_vCont_C = eLazyBoolNo;
+        m_supports_vCont_s = eLazyBoolNo;
+        m_supports_vCont_S = eLazyBoolNo;
+        if (SendPacketAndWaitForResponse("vCont?", response, 1, false))
+        {
+            const char *response_cstr = response.GetStringRef().c_str();
+            if (::strstr (response_cstr, ";c"))
+                m_supports_vCont_c = eLazyBoolYes;
+
+            if (::strstr (response_cstr, ";C"))
+                m_supports_vCont_C = eLazyBoolYes;
+
+            if (::strstr (response_cstr, ";s"))
+                m_supports_vCont_s = eLazyBoolYes;
+
+            if (::strstr (response_cstr, ";S"))
+                m_supports_vCont_S = eLazyBoolYes;
+
+            if (m_supports_vCont_c == eLazyBoolYes &&
+                m_supports_vCont_C == eLazyBoolYes &&
+                m_supports_vCont_s == eLazyBoolYes &&
+                m_supports_vCont_S == eLazyBoolYes)
+            {
+                m_supports_vCont_all = eLazyBoolYes;
+            }
+            
+            if (m_supports_vCont_c == eLazyBoolYes ||
+                m_supports_vCont_C == eLazyBoolYes ||
+                m_supports_vCont_s == eLazyBoolYes ||
+                m_supports_vCont_S == eLazyBoolYes)
+            {
+                m_supports_vCont_any = eLazyBoolYes;
+            }
+        }
+    }
+    
+    switch (flavor)
+    {
+    case 'a': return m_supports_vCont_any;
+    case 'A': return m_supports_vCont_all;
+    case 'c': return m_supports_vCont_c;
+    case 'C': return m_supports_vCont_C;
+    case 's': return m_supports_vCont_s;
+    case 'S': return m_supports_vCont_S;
+    default: break;
+    }
+    return false;
+}
+
+
 size_t
 GDBRemoteCommunication::SendPacketAndWaitForResponse
 (
@@ -451,7 +564,7 @@
         size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL);
         if (bytes_written == packet.GetSize())
         {
-            if (m_send_acks)
+            if (GetSendAcks ())
             {
                 if (GetAck (1) != '+')
                     return 0;
@@ -643,7 +756,7 @@
                         
                         if (success)
                             response_str.assign (packet_data + 1, packet_size - 4);
-                        if (m_send_acks)
+                        if (GetSendAcks ())
                         {
                             char packet_checksum = strtol (&packet_data[packet_size-2], NULL, 16);
                             char actual_checksum = CalculcateChecksum (&response_str[0], response_str.size());
@@ -829,66 +942,66 @@
 }
 
 bool
-GDBRemoteCommunication::GetHostInfo (uint32_t timeout_seconds)
+GDBRemoteCommunication::GetHostInfo ()
 {
-    m_arch.Clear();
-    m_os.Clear();
-    m_vendor.Clear();
-    m_byte_order = lldb::endian::InlHostByteOrder();
-    m_pointer_byte_size = 0;
-
-    StringExtractorGDBRemote response;
-    if (SendPacketAndWaitForResponse ("qHostInfo", response, timeout_seconds, false))
+    if (m_supports_qHostInfo == eLazyBoolCalculate)
     {
-        if (response.IsUnsupportedPacket())
-            return false;
+        m_supports_qHostInfo = eLazyBoolNo;
 
-        
-        std::string name;
-        std::string value;
-        uint32_t cpu = LLDB_INVALID_CPUTYPE;
-        uint32_t sub = 0;
-    
-        while (response.GetNameColonValue(name, value))
+        StringExtractorGDBRemote response;
+        if (SendPacketAndWaitForResponse ("qHostInfo", response, 1, false))
         {
-            if (name.compare("cputype") == 0)
-            {
-                // exception type in big endian hex
-                cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
-            }
-            else if (name.compare("cpusubtype") == 0)
-            {
-                // exception count in big endian hex
-                sub = Args::StringToUInt32 (value.c_str(), 0, 0);
-            }
-            else if (name.compare("ostype") == 0)
-            {
-                // exception data in big endian hex
-                m_os.SetCString(value.c_str());
-            }
-            else if (name.compare("vendor") == 0)
-            {
-                m_vendor.SetCString(value.c_str());
-            }
-            else if (name.compare("endian") == 0)
-            {
-                if (value.compare("little") == 0)
-                    m_byte_order = eByteOrderLittle;
-                else if (value.compare("big") == 0)
-                    m_byte_order = eByteOrderBig;
-                else if (value.compare("pdp") == 0)
-                    m_byte_order = eByteOrderPDP;
-            }
-            else if (name.compare("ptrsize") == 0)
+            if (response.IsUnsupportedPacket())
+                return false;
+
+            m_supports_qHostInfo = eLazyBoolYes;
+
+            std::string name;
+            std::string value;
+            uint32_t cpu = LLDB_INVALID_CPUTYPE;
+            uint32_t sub = 0;
+        
+            while (response.GetNameColonValue(name, value))
             {
-                m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
+                if (name.compare("cputype") == 0)
+                {
+                    // exception type in big endian hex
+                    cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
+                }
+                else if (name.compare("cpusubtype") == 0)
+                {
+                    // exception count in big endian hex
+                    sub = Args::StringToUInt32 (value.c_str(), 0, 0);
+                }
+                else if (name.compare("ostype") == 0)
+                {
+                    // exception data in big endian hex
+                    m_os.SetCString(value.c_str());
+                }
+                else if (name.compare("vendor") == 0)
+                {
+                    m_vendor.SetCString(value.c_str());
+                }
+                else if (name.compare("endian") == 0)
+                {
+                    if (value.compare("little") == 0)
+                        m_byte_order = eByteOrderLittle;
+                    else if (value.compare("big") == 0)
+                        m_byte_order = eByteOrderBig;
+                    else if (value.compare("pdp") == 0)
+                        m_byte_order = eByteOrderPDP;
+                }
+                else if (name.compare("ptrsize") == 0)
+                {
+                    m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
+                }
             }
+            
+            if (cpu != LLDB_INVALID_CPUTYPE)
+                m_arch.SetMachOArch (cpu, sub);
         }
-        
-        if (cpu != LLDB_INVALID_CPUTYPE)
-            m_arch.SetMachOArch (cpu, sub);
     }
-    return HostInfoIsValid();
+    return m_supports_qHostInfo == eLazyBoolYes;
 }
 
 int
@@ -918,7 +1031,7 @@
 GDBRemoteCommunication::GetHostArchitecture ()
 {
     if (!HostInfoIsValid ())
-        GetHostInfo (1);
+        GetHostInfo ();
     return m_arch;
 }
 
@@ -926,7 +1039,7 @@
 GDBRemoteCommunication::GetOSString ()
 {
     if (!HostInfoIsValid ())
-        GetHostInfo (1);
+        GetHostInfo ();
     return m_os;
 }
 
@@ -934,7 +1047,7 @@
 GDBRemoteCommunication::GetVendorString()
 {
     if (!HostInfoIsValid ())
-        GetHostInfo (1);
+        GetHostInfo ();
     return m_vendor;
 }
 
@@ -942,7 +1055,7 @@
 GDBRemoteCommunication::GetByteOrder ()
 {
     if (!HostInfoIsValid ())
-        GetHostInfo (1);
+        GetHostInfo ();
     return m_byte_order;
 }
 
@@ -950,7 +1063,7 @@
 GDBRemoteCommunication::GetAddressByteSize ()
 {
     if (!HostInfoIsValid ())
-        GetHostInfo (1);
+        GetHostInfo ();
     return m_pointer_byte_size;
 }
 

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h?rev=125433&r1=125432&r2=125433&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h Sat Feb 12 00:28:37 2011
@@ -97,23 +97,8 @@
     CalculcateChecksum (const char *payload,
                         size_t payload_length);
 
-    void
-    SetAckMode (bool enabled)
-    {
-        m_send_acks = enabled;
-    }
-
     bool
-    GetThreadSuffixSupported () const
-    {
-        return m_thread_suffix_supported;
-    }
-    
-    void
-    SetThreadSuffixSupported (bool enabled)
-    {
-        m_thread_suffix_supported = enabled;
-    }
+    GetThreadSuffixSupported ();
 
     bool
     SendAsyncSignal (int signo);
@@ -229,12 +214,6 @@
     bool
     GetHostInfo (uint32_t timeout_seconds);
 
-    bool 
-    HostInfoIsValid () const
-    {
-        return m_pointer_byte_size != 0;
-    }
-
     const lldb_private::ArchSpec &
     GetHostArchitecture ();
     
@@ -250,6 +229,33 @@
     uint32_t
     GetAddressByteSize ();
 
+    bool
+    GetVContSupported (char flavor);
+
+    void
+    ResetDiscoverableSettings();
+
+    bool
+    GetHostInfo ();
+    
+    bool
+    GetSendAcks ();
+    
+    bool
+    GetSupportsThreadSuffix ();
+
+    bool
+    HasFullVContSupport ()
+    {
+        return GetVContSupported ('A');
+    }
+
+    bool
+    HasAnyVContSupport ()
+    {
+        return GetVContSupported ('a');
+    }
+
 protected:
     typedef std::list<std::string> packet_collection;
 
@@ -264,11 +270,24 @@
     bool
     WaitForNotRunningPrivate (const lldb_private::TimeValue *timeout_ptr);
 
+    bool
+    HostInfoIsValid () const
+    {
+        return m_supports_qHostInfo != lldb::eLazyBoolCalculate;
+    }
+
     //------------------------------------------------------------------
     // Classes that inherit from GDBRemoteCommunication can see and modify these
     //------------------------------------------------------------------
-    bool m_send_acks:1,
-         m_thread_suffix_supported:1;
+    lldb::LazyBool m_supports_not_sending_acks;
+    lldb::LazyBool m_supports_thread_suffix;
+    lldb::LazyBool m_supports_qHostInfo;
+    lldb::LazyBool m_supports_vCont_all;
+    lldb::LazyBool m_supports_vCont_any;
+    lldb::LazyBool m_supports_vCont_c;
+    lldb::LazyBool m_supports_vCont_C;
+    lldb::LazyBool m_supports_vCont_s;
+    lldb::LazyBool m_supports_vCont_S;
     lldb_private::Listener m_rx_packet_listener;
     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;

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=125433&r1=125432&r2=125433&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Sat Feb 12 00:28:37 2011
@@ -114,7 +114,10 @@
     m_curr_tid (LLDB_INVALID_THREAD_ID),
     m_curr_tid_run (LLDB_INVALID_THREAD_ID),
     m_z0_supported (1),
-    m_continue_packet(),
+    m_continue_c_tids (),
+    m_continue_C_tids (),
+    m_continue_s_tids (),
+    m_continue_S_tids (),
     m_dispatch_queue_offsets_addr (LLDB_INVALID_ADDRESS),
     m_packet_timeout (1),
     m_max_memory_size (512),
@@ -599,7 +602,6 @@
         return error;
     }
 
-    m_gdb_comm.SetAckMode (true);
     if (m_gdb_comm.StartReadThread(&error))
     {
         // Send an initial ack
@@ -611,19 +613,11 @@
                                                                       m_debugserver_pid,
                                                                       false);
         
-        StringExtractorGDBRemote response;
-        if (m_gdb_comm.SendPacketAndWaitForResponse("QStartNoAckMode", response, 1, false))
-        {
-            if (response.IsOKPacket())
-                m_gdb_comm.SetAckMode (false);
-        }
-
-        if (m_gdb_comm.SendPacketAndWaitForResponse("QThreadSuffixSupported", response, 1, false))
-        {
-            if (response.IsOKPacket())
-                m_gdb_comm.SetThreadSuffixSupported (true);
-        }
-
+        m_gdb_comm.ResetDiscoverableSettings();
+        m_gdb_comm.GetSendAcks ();
+        m_gdb_comm.GetThreadSuffixSupported ();
+        m_gdb_comm.GetHostInfo ();
+        m_gdb_comm.GetVContSupported ('c');
     }
     return error;
 }
@@ -847,12 +841,10 @@
 Error
 ProcessGDBRemote::WillResume ()
 {
-    m_continue_packet.Clear();
-    // Start the continue packet we will use to run the target. Each thread
-    // will append what it is supposed to be doing to this packet when the
-    // ThreadList::WillResume() is called. If a thread it supposed
-    // to stay stopped, then don't append anything to this string.
-    m_continue_packet.Printf("vCont");
+    m_continue_c_tids.clear();
+    m_continue_C_tids.clear();
+    m_continue_s_tids.clear();
+    m_continue_S_tids.clear();
     return Error();
 }
 
@@ -867,14 +859,210 @@
     Listener listener ("gdb-remote.resume-packet-sent");
     if (listener.StartListeningForEvents (&m_gdb_comm, GDBRemoteCommunication::eBroadcastBitRunPacketSent))
     {
-        EventSP event_sp;
-        TimeValue timeout;
-        timeout = TimeValue::Now();
-        timeout.OffsetWithSeconds (5);
-        m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (m_continue_packet.GetData(), m_continue_packet.GetSize()));
+        StreamString continue_packet;
+        bool continue_packet_error = false;
+        if (m_gdb_comm.HasAnyVContSupport ())
+        {
+            continue_packet.PutCString ("vCont");
+        
+            if (!m_continue_c_tids.empty())
+            {
+                if (m_gdb_comm.GetVContSupported ('c'))
+                {
+                    for (tid_collection::const_iterator t_pos = m_continue_c_tids.begin(), t_end = m_continue_c_tids.end(); t_pos != t_end; ++t_pos)
+                        continue_packet.Printf(";c:%4.4x", *t_pos);
+                }
+                else 
+                    continue_packet_error = true;
+            }
+            
+            if (!continue_packet_error && !m_continue_C_tids.empty())
+            {
+                if (m_gdb_comm.GetVContSupported ('C'))
+                {
+                    for (tid_sig_collection::const_iterator s_pos = m_continue_C_tids.begin(), s_end = m_continue_C_tids.end(); s_pos != s_end; ++s_pos)
+                        continue_packet.Printf(";C%2.2x:%4.4x", s_pos->second, s_pos->first);
+                }
+                else 
+                    continue_packet_error = true;
+            }
+
+            if (!continue_packet_error && !m_continue_s_tids.empty())
+            {
+                if (m_gdb_comm.GetVContSupported ('s'))
+                {
+                    for (tid_collection::const_iterator t_pos = m_continue_s_tids.begin(), t_end = m_continue_s_tids.end(); t_pos != t_end; ++t_pos)
+                        continue_packet.Printf(";s:%4.4x", *t_pos);
+                }
+                else 
+                    continue_packet_error = true;
+            }
+            
+            if (!continue_packet_error && !m_continue_S_tids.empty())
+            {
+                if (m_gdb_comm.GetVContSupported ('S'))
+                {
+                    for (tid_sig_collection::const_iterator s_pos = m_continue_S_tids.begin(), s_end = m_continue_S_tids.end(); s_pos != s_end; ++s_pos)
+                        continue_packet.Printf(";S%2.2x:%4.4x", s_pos->second, s_pos->first);
+                }
+                else
+                    continue_packet_error = true;
+            }
+            
+            if (continue_packet_error)
+                continue_packet.GetString().clear();
+        }
+        else
+            continue_packet_error = true;
+        
+        if (continue_packet_error)
+        {
+            continue_packet_error = false;
+            // Either no vCont support, or we tried to use part of the vCont
+            // packet that wasn't supported by the remote GDB server.
+            // We need to try and make a simple packet that can do our continue
+            const size_t num_threads = GetThreadList().GetSize();
+            const size_t num_continue_c_tids = m_continue_c_tids.size();
+            const size_t num_continue_C_tids = m_continue_C_tids.size();
+            const size_t num_continue_s_tids = m_continue_s_tids.size();
+            const size_t num_continue_S_tids = m_continue_S_tids.size();
+            if (num_continue_c_tids > 0)
+            {
+                if (num_continue_c_tids == num_threads)
+                {
+                    // All threads are resuming...
+                    SetCurrentGDBRemoteThreadForRun (-1);
+                    continue_packet.PutChar ('c');                
+                }
+                else if (num_continue_c_tids == 1 &&
+                         num_continue_C_tids == 0 && 
+                         num_continue_s_tids == 0 && 
+                         num_continue_S_tids == 0 )
+                {
+                    // Only one thread is continuing
+                    SetCurrentGDBRemoteThreadForRun (m_continue_c_tids.front());
+                    continue_packet.PutChar ('c');                
+                }
+                else
+                {
+                    // We can't represent this continue packet....
+                    continue_packet_error = true;
+                }
+            }
 
-        if (listener.WaitForEvent (&timeout, event_sp) == false)
-            error.SetErrorString("Resume timed out.");
+            if (!continue_packet_error && num_continue_C_tids > 0)
+            {
+                if (num_continue_C_tids == num_threads)
+                {
+                    const int continue_signo = m_continue_C_tids.front().second;
+                    if (num_continue_C_tids > 1)
+                    {
+                        for (size_t i=1; i<num_threads; ++i)
+                        {
+                            if (m_continue_C_tids[i].second != continue_signo)
+                                continue_packet_error = true;
+                        }
+                    }
+                    if (!continue_packet_error)
+                    {
+                        // Add threads continuing with the same signo...
+                        SetCurrentGDBRemoteThreadForRun (-1);
+                        continue_packet.Printf("C%2.2x", continue_signo);
+                    }
+                }
+                else if (num_continue_c_tids == 0 &&
+                         num_continue_C_tids == 1 && 
+                         num_continue_s_tids == 0 && 
+                         num_continue_S_tids == 0 )
+                {
+                    // Only one thread is continuing with signal
+                    SetCurrentGDBRemoteThreadForRun (m_continue_C_tids.front().first);
+                    continue_packet.Printf("C%2.2x", m_continue_C_tids.front().second);
+                }
+                else
+                {
+                    // We can't represent this continue packet....
+                    continue_packet_error = true;
+                }
+            }
+
+            if (!continue_packet_error && num_continue_s_tids > 0)
+            {
+                if (num_continue_s_tids == num_threads)
+                {
+                    // All threads are resuming...
+                    SetCurrentGDBRemoteThreadForRun (-1);
+                    continue_packet.PutChar ('s');                
+                }
+                else if (num_continue_c_tids == 0 &&
+                         num_continue_C_tids == 0 && 
+                         num_continue_s_tids == 1 && 
+                         num_continue_S_tids == 0 )
+                {
+                    // Only one thread is stepping
+                    SetCurrentGDBRemoteThreadForRun (m_continue_s_tids.front());
+                    continue_packet.PutChar ('s');                
+                }
+                else
+                {
+                    // We can't represent this continue packet....
+                    continue_packet_error = true;
+                }
+            }
+
+            if (!continue_packet_error && num_continue_S_tids > 0)
+            {
+                if (num_continue_S_tids == num_threads)
+                {
+                    const int step_signo = m_continue_S_tids.front().second;
+                    // Are all threads trying to step with the same signal?
+                    if (num_continue_S_tids > 1)
+                    {
+                        for (size_t i=1; i<num_threads; ++i)
+                        {
+                            if (m_continue_S_tids[i].second != step_signo)
+                                continue_packet_error = true;
+                        }
+                    }
+                    if (!continue_packet_error)
+                    {
+                        // Add threads stepping with the same signo...
+                        SetCurrentGDBRemoteThreadForRun (-1);
+                        continue_packet.Printf("S%2.2x", step_signo);
+                    }
+                }
+                else if (num_continue_c_tids == 0 &&
+                         num_continue_C_tids == 0 && 
+                         num_continue_s_tids == 0 && 
+                         num_continue_S_tids == 1 )
+                {
+                    // Only one thread is stepping with signal
+                    SetCurrentGDBRemoteThreadForRun (m_continue_S_tids.front().first);
+                    continue_packet.Printf("S%2.2x", m_continue_S_tids.front().second);
+                }
+                else
+                {
+                    // We can't represent this continue packet....
+                    continue_packet_error = true;
+                }
+            }
+        }
+
+        if (continue_packet_error)
+        {
+            error.SetErrorString ("can't make continue packet for this resume");
+        }
+        else
+        {
+            EventSP event_sp;
+            TimeValue timeout;
+            timeout = TimeValue::Now();
+            timeout.OffsetWithSeconds (5);
+            m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (continue_packet.GetData(), continue_packet.GetSize()));
+
+            if (listener.WaitForEvent (&timeout, event_sp) == false)
+                error.SetErrorString("Resume timed out.");
+        }
     }
 
     return error;
@@ -2118,7 +2306,11 @@
         return true;
 
     char packet[32];
-    const int packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid);
+    int packet_len;
+    if (tid <= 0)
+        packet_len = ::snprintf (packet, sizeof(packet), "Hg%i", tid);
+    else
+        packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid);
     assert (packet_len + 1 < sizeof(packet));
     StringExtractorGDBRemote response;
     if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, 2, false))
@@ -2139,7 +2331,12 @@
         return true;
 
     char packet[32];
-    const int packet_len = ::snprintf (packet, sizeof(packet), "Hc%x", tid);
+    int packet_len;
+    if (tid <= 0)
+        packet_len = ::snprintf (packet, sizeof(packet), "Hc%i", tid);
+    else
+        packet_len = ::snprintf (packet, sizeof(packet), "Hc%x", tid);
+
     assert (packet_len + 1 < sizeof(packet));
     StringExtractorGDBRemote response;
     if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, 2, false))

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h?rev=125433&r1=125432&r2=125433&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Sat Feb 12 00:28:37 2011
@@ -14,6 +14,7 @@
 
 // C++ Includes
 #include <list>
+#include <vector>
 
 // Other libraries and framework includes
 #include "lldb/Core/ArchSpec.h"
@@ -343,7 +344,12 @@
     lldb::tid_t m_curr_tid;         // Current gdb remote protocol thread index for all other operations
     lldb::tid_t m_curr_tid_run;     // Current gdb remote protocol thread index for continue, step, etc
     uint32_t m_z0_supported:1;      // Set to non-zero if Z0 and z0 packets are supported
-    lldb_private::StreamString m_continue_packet;
+    typedef std::vector<lldb::tid_t> tid_collection;
+    typedef std::vector< std::pair<lldb::tid_t,int> > tid_sig_collection;
+    tid_collection m_continue_c_tids;                  // 'c' for continue
+    tid_sig_collection m_continue_C_tids; // 'C' for continue with signal
+    tid_collection m_continue_s_tids;                  // 's' for step
+    tid_sig_collection m_continue_S_tids; // 'S' for step with signal
     lldb::addr_t m_dispatch_queue_offsets_addr;
     uint32_t m_packet_timeout;
     size_t m_max_memory_size;       // The maximum number of bytes to read/write when reading and writing memory

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp?rev=125433&r1=125432&r2=125433&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp Sat Feb 12 00:28:37 2011
@@ -93,25 +93,25 @@
     if (log)
         log->Printf ("Resuming thread: %4.4x with state: %s.", GetID(), StateAsCString(resume_state));
 
+    ProcessGDBRemote &process = GetGDBProcess();
     switch (resume_state)
     {
     case eStateSuspended:
     case eStateStopped:
-        // Don't append anything for threads that should stay stopped.
         break;
 
     case eStateRunning:
         if (m_process.GetUnixSignals().SignalIsValid (signo))
-            GetGDBProcess().m_continue_packet.Printf(";C%2.2x:%4.4x", signo, GetID());
+            process.m_continue_C_tids.push_back(std::make_pair(GetID(), signo));
         else
-            GetGDBProcess().m_continue_packet.Printf(";c:%4.4x", GetID());
+            process.m_continue_c_tids.push_back(GetID());
         break;
 
     case eStateStepping:
         if (m_process.GetUnixSignals().SignalIsValid (signo))
-            GetGDBProcess().m_continue_packet.Printf(";S%2.2x:%4.4x", signo, GetID());
+            process.m_continue_S_tids.push_back(std::make_pair(GetID(), signo));
         else
-            GetGDBProcess().m_continue_packet.Printf(";s:%4.4x", GetID());
+            process.m_continue_s_tids.push_back(GetID());
         break;
 
     default:

Modified: lldb/trunk/tools/debugserver/source/DNBLog.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNBLog.cpp?rev=125433&r1=125432&r2=125433&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNBLog.cpp (original)
+++ lldb/trunk/tools/debugserver/source/DNBLog.cpp Sat Feb 12 00:28:37 2011
@@ -93,6 +93,9 @@
 static inline void
 _DNBLogVAPrintf(uint32_t flags, const char *format, va_list args)
 {
+    static PThreadMutex g_LogThreadedMutex(PTHREAD_MUTEX_RECURSIVE);
+    PTHREAD_MUTEX_LOCKER(locker, g_LogThreadedMutex);
+
     if (g_log_callback)
       g_log_callback(g_log_baton, flags, format, args);
 }
@@ -140,12 +143,6 @@
 }
 
 
-static pthread_mutex_t *
-GetLogThreadedMutex()
-{
-    static PThreadMutex g_LogThreadedMutex(PTHREAD_MUTEX_RECURSIVE);
-    return g_LogThreadedMutex.Mutex();
-}
 static uint32_t g_message_id = 0;
 
 //----------------------------------------------------------------------
@@ -157,7 +154,7 @@
 {
     if (DNBLogEnabled ())
     {
-        PTHREAD_MUTEX_LOCKER(locker, GetLogThreadedMutex());
+        //PTHREAD_MUTEX_LOCKER(locker, GetLogThreadedMutex());
 
         char *arg_msg = NULL;
         va_list args;
@@ -202,7 +199,7 @@
 {
     if (DNBLogEnabled () && (log_bit & g_log_bits) == log_bit)
     {
-        PTHREAD_MUTEX_LOCKER(locker, GetLogThreadedMutex());
+        //PTHREAD_MUTEX_LOCKER(locker, GetLogThreadedMutex());
 
         char *arg_msg = NULL;
         va_list args;





More information about the lldb-commits mailing list