[Lldb-commits] [lldb] r123762 - in /lldb/trunk: source/Expression/ source/Plugins/Process/gdb-remote/ source/Target/ source/Utility/ tools/debugserver/source/ tools/debugserver/source/MacOSX/ tools/debugserver/source/MacOSX/i386/ tools/debugserver/source/MacOSX/x86_64/

Greg Clayton gclayton at apple.com
Tue Jan 18 11:36:39 PST 2011


Author: gclayton
Date: Tue Jan 18 13:36:39 2011
New Revision: 123762

URL: http://llvm.org/viewvc/llvm-project?rev=123762&view=rev
Log:
Thread safety changes in debugserver and also in the process GDB remote plugin.
I added support for asking if the GDB remote server supports thread suffixes
for packets that should be thread specific (register read/write packets) because
the way the GDB remote protocol does it right now is to have a notion of a
current thread for register and memory reads/writes (set via the "$Hg%x" packet)
and a current thread for running ("$Hc%x"). Now we ask the remote GDB server
if it supports adding the thread ID to the register packets and we enable
that feature in LLDB if supported. This stops us from having to send a bunch
of packets that update the current thread ID to some value which is prone to
error, or extra packets.


Modified:
    lldb/trunk/source/Expression/ClangUserExpression.cpp
    lldb/trunk/source/Expression/ClangUtilityFunction.cpp
    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/GDBRemoteRegisterContext.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/trunk/source/Target/ThreadList.cpp
    lldb/trunk/source/Utility/StringExtractor.h
    lldb/trunk/tools/debugserver/source/DNBThreadResumeActions.h
    lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h
    lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/MachThread.h
    lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
    lldb/trunk/tools/debugserver/source/RNBRemote.cpp
    lldb/trunk/tools/debugserver/source/RNBRemote.h

Modified: lldb/trunk/source/Expression/ClangUserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUserExpression.cpp?rev=123762&r1=123761&r2=123762&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangUserExpression.cpp (original)
+++ lldb/trunk/source/Expression/ClangUserExpression.cpp Tue Jan 18 13:36:39 2011
@@ -20,6 +20,7 @@
 
 #include "lldb/Core/ConstString.h"
 #include "lldb/Core/Log.h"
+#include "lldb/Core/StreamFile.h"
 #include "lldb/Core/StreamString.h"
 #include "lldb/Core/ValueObjectConstResult.h"
 #include "lldb/Expression/ASTResultSynthesizer.h"
@@ -365,6 +366,12 @@
             error_stream.Printf("Couldn't materialize struct: %s\n", materialize_error.AsCString());
             return false;
         }
+
+#if 0
+		// jingham: look here
+        StreamFile logfile ("/tmp/exprs.txt", "a");
+        logfile.Printf("0x%16.16llx: thread = 0x%4.4x, expr = '%s'\n", m_jit_addr, exe_ctx.thread ? exe_ctx.thread->GetID() : -1, m_expr_text.c_str());
+#endif
         
         if (log)
         {

Modified: lldb/trunk/source/Expression/ClangUtilityFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUtilityFunction.cpp?rev=123762&r1=123761&r2=123762&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangUtilityFunction.cpp (original)
+++ lldb/trunk/source/Expression/ClangUtilityFunction.cpp Tue Jan 18 13:36:39 2011
@@ -17,6 +17,7 @@
 
 #include "lldb/Core/ConstString.h"
 #include "lldb/Core/Stream.h"
+#include "lldb/Core/StreamFile.h"
 #include "lldb/Expression/ClangExpressionDeclMap.h"
 #include "lldb/Expression/ClangExpressionParser.h"
 #include "lldb/Expression/ClangUtilityFunction.h"
@@ -124,6 +125,15 @@
         
     Error jit_error = parser.MakeJIT (m_jit_begin, m_jit_end, exe_ctx);
     
+#if 0
+	// jingham: look here
+    StreamFile logfile ("/tmp/exprs.txt", "a");
+    logfile.Printf ("0x%16.16llx: func = %s, source =\n%s\n", 
+                    m_jit_begin, 
+                    m_function_name.c_str(), 
+                    m_function_text.c_str());
+#endif
+
     m_expr_decl_map->DidParse();
     
     m_expr_decl_map.reset();

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=123762&r1=123761&r2=123762&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Tue Jan 18 13:36:39 2011
@@ -34,6 +34,7 @@
 GDBRemoteCommunication::GDBRemoteCommunication() :
     Communication("gdb-remote.packets"),
     m_send_acks (true),
+    m_thread_suffix_supported (false),
     m_rx_packet_listener ("gdbremote.rx_packet"),
     m_sequence_mutex (Mutex::eMutexTypeRecursive),
     m_is_running (false),

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=123762&r1=123761&r2=123762&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h Tue Jan 18 13:36:39 2011
@@ -100,6 +100,18 @@
     }
 
     bool
+    GetThreadSuffixSupported () const
+    {
+        return m_thread_suffix_supported;
+    }
+    
+    void
+    SetThreadSuffixSupported (bool enabled)
+    {
+        m_thread_suffix_supported = enabled;
+    }
+
+    bool
     SendAsyncSignal (int signo);
 
     bool
@@ -244,7 +256,8 @@
     //------------------------------------------------------------------
     // Classes that inherit from GDBRemoteCommunication can see and modify these
     //------------------------------------------------------------------
-    bool m_send_acks;
+    bool m_send_acks:1,
+         m_thread_suffix_supported:1;
     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_is_running;

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp?rev=123762&r1=123761&r2=123762&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp Tue Jan 18 13:36:39 2011
@@ -217,15 +217,19 @@
         Mutex::Locker locker;
         if (gdb_comm.GetSequenceMutex (locker))
         {
-            if (GetGDBProcess().SetCurrentGDBRemoteThread(m_thread.GetID()))
+            const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
+            if (thread_suffix_supported || GetGDBProcess().SetCurrentGDBRemoteThread(m_thread.GetID()))
             {
-                char packet[32];
+                char packet[64];
                 StringExtractorGDBRemote response;
-                int packet_len;
+                int packet_len = 0;
                 if (m_read_all_at_once)
                 {
                     // Get all registers in one packet
-                    packet_len = ::snprintf (packet, sizeof(packet), "g");
+                    if (thread_suffix_supported)
+                        packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4x;", m_thread.GetID());
+                    else
+                        packet_len = ::snprintf (packet, sizeof(packet), "g");
                     assert (packet_len < (sizeof(packet) - 1));
                     if (gdb_comm.SendPacketAndWaitForResponse(packet, response, 1, false))
                     {
@@ -237,7 +241,10 @@
                 else
                 {
                     // Get each register individually
-                    packet_len = ::snprintf (packet, sizeof(packet), "p%x", reg);
+                    if (thread_suffix_supported)
+                        packet_len = ::snprintf (packet, sizeof(packet), "p%x;thread:%4.4x;", reg, m_thread.GetID());
+                    else
+                        packet_len = ::snprintf (packet, sizeof(packet), "p%x", reg);
                     assert (packet_len < (sizeof(packet) - 1));
                     if (gdb_comm.SendPacketAndWaitForResponse(packet, response, 1, false))
                         PrivateSetRegisterValue (reg, response);
@@ -319,7 +326,8 @@
         Mutex::Locker locker;
         if (gdb_comm.GetSequenceMutex (locker))
         {
-            if (GetGDBProcess().SetCurrentGDBRemoteThread(m_thread.GetID()))
+            const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
+            if (thread_suffix_supported || GetGDBProcess().SetCurrentGDBRemoteThread(m_thread.GetID()))
             {
                 uint32_t offset, end_offset;
                 StreamString packet;
@@ -336,6 +344,9 @@
                                               eByteOrderHost,
                                               eByteOrderHost);
                     
+                    if (thread_suffix_supported)
+                        packet.Printf (";thread:%4.4x;", m_thread.GetID());
+
                     // Invalidate all register values
                     InvalidateIfNeeded (true);
 
@@ -361,6 +372,9 @@
                                               eByteOrderHost,
                                               eByteOrderHost);
 
+                    if (thread_suffix_supported)
+                        packet.Printf (";thread:%4.4x;", m_thread.GetID());
+
                     // Invalidate just this register
                     m_reg_valid[reg] = false;
                     if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
@@ -391,16 +405,31 @@
     Mutex::Locker locker;
     if (gdb_comm.GetSequenceMutex (locker))
     {
-        if (GetGDBProcess().SetCurrentGDBRemoteThread(m_thread.GetID()))
+        char packet[32];
+        const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
+        if (thread_suffix_supported || GetGDBProcess().SetCurrentGDBRemoteThread(m_thread.GetID()))
         {
-            if (gdb_comm.SendPacketAndWaitForResponse("g", response, 1, false))
+            int packet_len = 0;
+            if (thread_suffix_supported)
+                packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4x", m_thread.GetID());
+            else
+                packet_len = ::snprintf (packet, sizeof(packet), "g");
+            assert (packet_len < (sizeof(packet) - 1));
+
+            if (gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, 1, false))
             {
                 if (response.IsErrorPacket())
                     return false;
-                    
+                
                 response.GetStringRef().insert(0, 1, 'G');
-                data_sp.reset (new DataBufferHeap(response.GetStringRef().c_str(), 
-                                                  response.GetStringRef().size()));
+                if (thread_suffix_supported)
+                {
+                    char thread_id_cstr[64];
+                    ::snprintf (thread_id_cstr, sizeof(thread_id_cstr), ";thread:%4.4x;", m_thread.GetID());
+                    response.GetStringRef().append (thread_id_cstr);
+                }
+                data_sp.reset (new DataBufferHeap (response.GetStringRef().c_str(), 
+                                                   response.GetStringRef().size()));
                 return true;
             }
         }
@@ -419,7 +448,8 @@
     Mutex::Locker locker;
     if (gdb_comm.GetSequenceMutex (locker))
     {
-        if (GetGDBProcess().SetCurrentGDBRemoteThread(m_thread.GetID()))
+        const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported();
+        if (thread_suffix_supported || GetGDBProcess().SetCurrentGDBRemoteThread(m_thread.GetID()))
         {
             if (gdb_comm.SendPacketAndWaitForResponse((const char *)data_sp->GetBytes(), 
                                                       data_sp->GetByteSize(), 

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=123762&r1=123761&r2=123762&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Tue Jan 18 13:36:39 2011
@@ -554,6 +554,13 @@
             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);
+        }
+
     }
     return error;
 }
@@ -2021,7 +2028,7 @@
         return true;
 
     char packet[32];
-    const int packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid);
+    const int 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/Target/ThreadList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadList.cpp?rev=123762&r1=123761&r2=123762&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadList.cpp (original)
+++ lldb/trunk/source/Target/ThreadList.cpp Tue Jan 18 13:36:39 2011
@@ -340,6 +340,7 @@
 void
 ThreadList::Clear()
 {
+    Mutex::Locker locker(m_threads_mutex);
     m_stop_id = 0;
     m_threads.clear();
     m_selected_tid = LLDB_INVALID_THREAD_ID;
@@ -504,6 +505,7 @@
 void
 ThreadList::DidResume ()
 {
+    Mutex::Locker locker(m_threads_mutex);
     collection::iterator pos, end = m_threads.end();
     for (pos = m_threads.begin(); pos != end; ++pos)
     {

Modified: lldb/trunk/source/Utility/StringExtractor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/StringExtractor.h?rev=123762&r1=123761&r2=123762&view=diff
==============================================================================
--- lldb/trunk/source/Utility/StringExtractor.h (original)
+++ lldb/trunk/source/Utility/StringExtractor.h Tue Jan 18 13:36:39 2011
@@ -113,6 +113,14 @@
     size_t
     GetHexByteString (std::string &str);
 
+    const char *
+    Peek ()
+    {
+        if (m_index < m_packet.size())
+            return m_packet.c_str() + m_index;
+        return NULL;
+    }
+
 protected:
     //------------------------------------------------------------------
     // For StringExtractor only

Modified: lldb/trunk/tools/debugserver/source/DNBThreadResumeActions.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNBThreadResumeActions.h?rev=123762&r1=123761&r2=123762&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNBThreadResumeActions.h (original)
+++ lldb/trunk/tools/debugserver/source/DNBThreadResumeActions.h Tue Jan 18 13:36:39 2011
@@ -85,6 +85,13 @@
     {
         return m_actions.size();
     }
+    
+    void
+    Clear()
+    {
+        m_actions.clear();
+        m_signal_handled.clear();
+    }
 
 protected:
     std::vector<DNBThreadResumeAction> m_actions;

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp?rev=123762&r1=123761&r2=123762&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.cpp Tue Jan 18 13:36:39 2011
@@ -101,6 +101,7 @@
     m_stdio_thread      (0),
     m_stdio_mutex       (PTHREAD_MUTEX_RECURSIVE),
     m_stdout_data       (),
+    m_thread_actions    (),
     m_thread_list        (),
     m_exception_messages (),
     m_exception_messages_mutex (PTHREAD_MUTEX_RECURSIVE),
@@ -314,7 +315,8 @@
 
     if (CanResume(state))
     {
-        PrivateResume(thread_actions);
+        m_thread_actions = thread_actions;
+        PrivateResume();
         return true;
     }
     else if (state == eStateRunning)
@@ -337,7 +339,8 @@
     DNBError err;
     err.SetErrorToErrno();
     DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Kill() DoSIGSTOP() ::ptrace (PT_KILL, pid=%u, 0, 0) => 0x%8.8x (%s)", err.Error(), err.AsString());
-    PrivateResume (DNBThreadResumeActions (eStateRunning, 0));
+    m_thread_actions = DNBThreadResumeActions (eStateRunning, 0);
+    PrivateResume ();
     return true;
 }
 
@@ -392,7 +395,8 @@
         // No threads were stopped with a SIGSTOP, we need to run and halt the
         // process with a signal
         DNBLogThreadedIf(LOG_PROCESS, "MachProcess::DoSIGSTOP() state = %s -- resuming process", DNBStateAsString (state));
-        PrivateResume (DNBThreadResumeActions (eStateRunning, 0));
+        m_thread_actions = DNBThreadResumeActions (eStateRunning, 0);
+        PrivateResume ();
 
         // Reset the event that says we were indeed running
         m_events.ResetEvents(eEventProcessRunningStateChanged);
@@ -428,20 +432,19 @@
     DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Detach() DoSIGSTOP() returned %s", DNBStateAsString(state));
 
     {
-        DNBThreadResumeActions thread_actions;
+        m_thread_actions.Clear();
         DNBThreadResumeAction thread_action;
         thread_action.tid = m_thread_list.ThreadIDAtIndex (thread_idx);
         thread_action.state = eStateRunning;
         thread_action.signal = -1;
         thread_action.addr = INVALID_NUB_ADDRESS;
         
-        thread_actions.Append (thread_action);
-        
-        thread_actions.SetDefaultThreadActionIfNeeded (eStateRunning, 0);
+        m_thread_actions.Append (thread_action);
+        m_thread_actions.SetDefaultThreadActionIfNeeded (eStateRunning, 0);
         
         PTHREAD_MUTEX_LOCKER (locker, m_exception_messages_mutex);
 
-        ReplyToAllExceptions (thread_actions);
+        ReplyToAllExceptions ();
 
     }
 
@@ -597,7 +600,7 @@
 
 
 void
-MachProcess::ReplyToAllExceptions (const DNBThreadResumeActions& thread_actions)
+MachProcess::ReplyToAllExceptions ()
 {
     PTHREAD_MUTEX_LOCKER(locker, m_exception_messages_mutex);
     if (m_exception_messages.empty() == false)
@@ -610,13 +613,13 @@
             DNBLogThreadedIf(LOG_EXCEPTIONS, "Replying to exception %d...", std::distance(begin, pos));
             int thread_reply_signal = 0;
 
-            const DNBThreadResumeAction *action = thread_actions.GetActionForThread (pos->state.thread_port, false);
+            const DNBThreadResumeAction *action = m_thread_actions.GetActionForThread (pos->state.thread_port, false);
 
             if (action)
             {
                 thread_reply_signal = action->signal;
                 if (thread_reply_signal)
-                    thread_actions.SetSignalHandledForThread (pos->state.thread_port);
+                    m_thread_actions.SetSignalHandledForThread (pos->state.thread_port);
             }
 
             DNBError err (pos->Reply(this, thread_reply_signal));
@@ -630,20 +633,20 @@
     }
 }
 void
-MachProcess::PrivateResume (const DNBThreadResumeActions& thread_actions)
+MachProcess::PrivateResume ()
 {
     PTHREAD_MUTEX_LOCKER (locker, m_exception_messages_mutex);
 
-    ReplyToAllExceptions (thread_actions);
+    ReplyToAllExceptions ();
 //    bool stepOverBreakInstruction = step;
 
     // Let the thread prepare to resume and see if any threads want us to
     // step over a breakpoint instruction (ProcessWillResume will modify
     // the value of stepOverBreakInstruction).
-    m_thread_list.ProcessWillResume (this, thread_actions);
+    m_thread_list.ProcessWillResume (this, m_thread_actions);
 
     // Set our state accordingly
-    if (thread_actions.NumActionsWithState(eStateStepping))
+    if (m_thread_actions.NumActionsWithState(eStateStepping))
         SetState (eStateStepping);
     else
         SetState (eStateRunning);
@@ -1100,7 +1103,7 @@
         else
         {
             // Resume without checking our current state.
-            PrivateResume (DNBThreadResumeActions (eStateRunning, 0));
+            PrivateResume ();
         }
     }
     else

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h?rev=123762&r1=123761&r2=123762&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachProcess.h Tue Jan 18 13:36:39 2011
@@ -17,6 +17,7 @@
 #include "DNBDefs.h"
 #include "DNBBreakpoint.h"
 #include "DNBError.h"
+#include "DNBThreadResumeActions.h"
 //#include "MachDYLD.h"
 #include "MachException.h"
 #include "MachVMMemory.h"
@@ -219,8 +220,8 @@
         eMachProcessFlagsUsingSBS = (1 << 1)
     };
     void                    Clear ();
-    void                    ReplyToAllExceptions (const DNBThreadResumeActions& thread_actions);
-    void                    PrivateResume (const DNBThreadResumeActions& thread_actions);
+    void                    ReplyToAllExceptions ();
+    void                    PrivateResume ();
     nub_size_t              RemoveTrapsFromBuffer (nub_addr_t addr, nub_size_t size, uint8_t *buf) const;
 
     uint32_t                Flags () const { return m_flags; }
@@ -239,6 +240,7 @@
     pthread_t                   m_stdio_thread;             // Thread ID for the thread that watches for child process stdio
     PThreadMutex                m_stdio_mutex;              // Multithreaded protection for stdio
     std::string                 m_stdout_data;
+    DNBThreadResumeActions      m_thread_actions;           // The thread actions for the current MachProcess::Resume() call
     MachException::Message::collection
                                 m_exception_messages;       // A collection of exception messages caught when listening to the exception port
     PThreadMutex                m_exception_messages_mutex; // Multithreaded protection for m_exception_messages

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp?rev=123762&r1=123761&r2=123762&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp Tue Jan 18 13:36:39 2011
@@ -339,6 +339,12 @@
     m_stop_exception.Clear();
 }
 
+nub_break_t
+MachThread::CurrentBreakpoint()
+{
+    return m_process->Breakpoints().FindIDByAddress(GetPC());
+}
+
 bool
 MachThread::ShouldStop(bool &step_more)
 {
@@ -394,14 +400,18 @@
 bool
 MachThread::IsStepping()
 {
+#if ENABLE_AUTO_STEPPING_OVER_BP
     // Return true if this thread is currently being stepped.
     // MachThread::ThreadWillResume currently determines this by looking if we
     // have been asked to single step, or if we are at a breakpoint instruction
     // and have been asked to resume. In the latter case we need to disable the
     // breakpoint we are at, single step, re-enable and continue.
     nub_state_t state = GetState();
-    return    (state == eStateStepping) ||
-            (state == eStateRunning && NUB_BREAK_ID_IS_VALID(CurrentBreakpoint()));
+    return ((state == eStateStepping) ||
+            (state == eStateRunning && NUB_BREAK_ID_IS_VALID(CurrentBreakpoint())));
+#else
+    return GetState() == eStateStepping;
+#endif
 }
 
 
@@ -430,6 +440,7 @@
     // Update the basic information for a thread
     MachThread::GetBasicInfo(m_tid, &m_basicInfo);
 
+#if ENABLE_AUTO_STEPPING_OVER_BP
     // See if we were at a breakpoint when we last resumed that we disabled,
     // re-enable it.
     nub_break_t breakID = CurrentBreakpoint();
@@ -469,10 +480,12 @@
             SetState(eStateStopped);
         }
     }
-
-
-    SetCurrentBreakpoint(INVALID_NUB_BREAK_ID);
-
+#else
+    if (m_basicInfo.suspend_count > 0)
+        SetState(eStateSuspended);
+    else
+        SetState(eStateStopped);
+#endif
     return true;
 }
 
@@ -496,30 +509,27 @@
     if (!handled)
     {
         handled = true;
-        nub_addr_t pc = GetPC();
-        nub_break_t breakID = m_process->Breakpoints().FindIDByAddress(pc);
-        SetCurrentBreakpoint(breakID);
-        switch (exc.exc_type)
-        {
-        case EXC_BAD_ACCESS:
-            break;
-        case EXC_BAD_INSTRUCTION:
-            break;
-        case EXC_ARITHMETIC:
-            break;
-        case EXC_EMULATION:
-            break;
-        case EXC_SOFTWARE:
-            break;
-        case EXC_BREAKPOINT:
-            break;
-        case EXC_SYSCALL:
-            break;
-        case EXC_MACH_SYSCALL:
-            break;
-        case EXC_RPC_ALERT:
-            break;
-        }
+//        switch (exc.exc_type)
+//        {
+//        case EXC_BAD_ACCESS:
+//            break;
+//        case EXC_BAD_INSTRUCTION:
+//            break;
+//        case EXC_ARITHMETIC:
+//            break;
+//        case EXC_EMULATION:
+//            break;
+//        case EXC_SOFTWARE:
+//            break;
+//        case EXC_BREAKPOINT:
+//            break;
+//        case EXC_SYSCALL:
+//            break;
+//        case EXC_MACH_SYSCALL:
+//            break;
+//        case EXC_RPC_ALERT:
+//            break;
+//        }
     }
     return handled;
 }
@@ -658,27 +668,6 @@
     return false;
 }
 
-
-void
-MachThread::NotifyBreakpointChanged (const DNBBreakpoint *bp)
-{
-    nub_break_t breakID = bp->GetID();
-    if (bp->IsEnabled())
-    {
-        if (bp->Address() == GetPC())
-        {
-            SetCurrentBreakpoint(breakID);
-        }
-    }
-    else
-    {
-        if (CurrentBreakpoint() == breakID)
-        {
-            SetCurrentBreakpoint(INVALID_NUB_BREAK_ID);
-        }
-    }
-}
-
 bool
 MachThread::GetIdentifierInfo ()
 {

Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachThread.h?rev=123762&r1=123761&r2=123762&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachThread.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachThread.h Tue Jan 18 13:36:39 2011
@@ -60,8 +60,7 @@
     bool            SetPC(uint64_t value);                              // Set program counter
     uint64_t        GetSP(uint64_t failValue = INVALID_NUB_ADDRESS);    // Get stack pointer
 
-    nub_break_t     CurrentBreakpoint() const { return m_breakID; }
-    void            SetCurrentBreakpoint(nub_break_t breakID) { m_breakID = breakID; }
+    nub_break_t     CurrentBreakpoint();
     uint32_t        EnableHardwareBreakpoint (const DNBBreakpoint *breakpoint);
     uint32_t        EnableHardwareWatchpoint (const DNBBreakpoint *watchpoint);
     bool            DisableHardwareBreakpoint (const DNBBreakpoint *breakpoint);
@@ -88,7 +87,9 @@
     bool            SetRegisterValue ( uint32_t reg_set_idx, uint32_t reg_idx, const DNBRegisterValue *reg_value );
     nub_size_t      GetRegisterContext (void *buf, nub_size_t buf_len);
     nub_size_t      SetRegisterContext (const void *buf, nub_size_t buf_len);
-    void            NotifyBreakpointChanged (const DNBBreakpoint *bp);
+    void            NotifyBreakpointChanged (const DNBBreakpoint *bp)
+                    {
+                    }
 
     bool            IsUserReady();
     struct thread_basic_info *

Modified: lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp?rev=123762&r1=123761&r2=123762&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp Tue Jan 18 13:36:39 2011
@@ -428,8 +428,6 @@
                         // Write the new PC back out
                         SetGPRState ();
                     }
-
-                    m_thread->SetCurrentBreakpoint(breakID);
                 }
                 return true;
             }

Modified: lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp?rev=123762&r1=123761&r2=123762&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp Tue Jan 18 13:36:39 2011
@@ -355,8 +355,6 @@
                             // Write the new PC back out
                             SetGPRState ();
                         }
-                        
-                        m_thread->SetCurrentBreakpoint(breakID);
                     }
                     return true;
                 }

Modified: lldb/trunk/tools/debugserver/source/RNBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.cpp?rev=123762&r1=123761&r2=123762&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBRemote.cpp (original)
+++ lldb/trunk/tools/debugserver/source/RNBRemote.cpp Tue Jan 18 13:36:39 2011
@@ -76,6 +76,7 @@
     m_max_payload_size(DEFAULT_GDB_REMOTE_PROTOCOL_BUFSIZE - 4),
     m_extended_mode(false),
     m_noack_mode(false),
+    m_thread_suffix_supported (false),
     m_use_native_regs (use_native_regs)
 {
     DNBLogThreadedIf (LOG_RNB_REMOTE, "%s", __PRETTY_FUNCTION__);
@@ -170,12 +171,13 @@
     t.push_back (Packet (query_step_packet_supported,   &RNBRemote::HandlePacket_qStepPacketSupported,NULL, "qStepPacketSupported", "Replys with OK if the 's' packet is supported."));
     t.push_back (Packet (query_host_info,               &RNBRemote::HandlePacket_qHostInfo,     NULL, "qHostInfo", "Replies with multiple 'key:value;' tuples appended to each other."));
 //  t.push_back (Packet (query_symbol_lookup,           &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "qSymbol", "Notify that host debugger is ready to do symbol lookups"));
-    t.push_back (Packet (start_noack_mode,              &RNBRemote::HandlePacket_Q            , NULL, "QStartNoAckMode", "Request that " DEBUGSERVER_PROGRAM_NAME " stop acking remote protocol packets"));
-    t.push_back (Packet (set_logging_mode,              &RNBRemote::HandlePacket_Q            , NULL, "QSetLogging:", "Request that the " DEBUGSERVER_PROGRAM_NAME " set its logging mode bits"));
-    t.push_back (Packet (set_max_packet_size,           &RNBRemote::HandlePacket_Q            , NULL, "QSetMaxPacketSize:", "Tell " DEBUGSERVER_PROGRAM_NAME " the max sized packet gdb can handle"));
-    t.push_back (Packet (set_max_payload_size,          &RNBRemote::HandlePacket_Q            , NULL, "QSetMaxPayloadSize:", "Tell " DEBUGSERVER_PROGRAM_NAME " the max sized payload gdb can handle"));
-    t.push_back (Packet (set_environment_variable,      &RNBRemote::HandlePacket_Q            , NULL, "QEnvironment:", "Add an environment variable to the inferior's environment"));
-    t.push_back (Packet (set_disable_aslr,              &RNBRemote::HandlePacket_Q            , NULL, "QSetDisableASLR:", "Set wether to disable ASLR when launching the process with the set argv ('A') packet"));
+    t.push_back (Packet (start_noack_mode,              &RNBRemote::HandlePacket_QStartNoAckMode        , NULL, "QStartNoAckMode", "Request that " DEBUGSERVER_PROGRAM_NAME " stop acking remote protocol packets"));
+    t.push_back (Packet (prefix_reg_packets_with_tid,   &RNBRemote::HandlePacket_QThreadSuffixSupported , NULL, "QThreadSuffixSupported", "Check if thread specifc packets (register packets 'g', 'G', 'p', and 'P') support having the thread ID appended to the end of the command"));
+    t.push_back (Packet (set_logging_mode,              &RNBRemote::HandlePacket_QSetLogging            , NULL, "QSetLogging:", "Check if register packets ('g', 'G', 'p', and 'P' support having the thread ID prefix"));
+    t.push_back (Packet (set_max_packet_size,           &RNBRemote::HandlePacket_QSetMaxPacketSize      , NULL, "QSetMaxPacketSize:", "Tell " DEBUGSERVER_PROGRAM_NAME " the max sized packet gdb can handle"));
+    t.push_back (Packet (set_max_payload_size,          &RNBRemote::HandlePacket_QSetMaxPayloadSize     , NULL, "QSetMaxPayloadSize:", "Tell " DEBUGSERVER_PROGRAM_NAME " the max sized payload gdb can handle"));
+    t.push_back (Packet (set_environment_variable,      &RNBRemote::HandlePacket_QEnvironment           , NULL, "QEnvironment:", "Add an environment variable to the inferior's environment"));
+    t.push_back (Packet (set_disable_aslr,              &RNBRemote::HandlePacket_QSetDisableASLR        , NULL, "QSetDisableASLR:", "Set wether to disable ASLR when launching the process with the set argv ('A') packet"));
 //  t.push_back (Packet (pass_signals_to_inferior,      &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "QPassSignals:", "Specify which signals are passed to the inferior"));
     t.push_back (Packet (allocate_memory,               &RNBRemote::HandlePacket_AllocateMemory, NULL, "_M", "Allocate memory in the inferior process."));
     t.push_back (Packet (deallocate_memory,             &RNBRemote::HandlePacket_DeallocateMemory, NULL, "_m", "Deallocate memory in the inferior process."));
@@ -1702,104 +1704,105 @@
     return rnb_success;
 }
 
-
+rnb_err_t
+RNBRemote::HandlePacket_QThreadSuffixSupported (const char *p)
+{
+    m_thread_suffix_supported = true;
+    return SendPacket ("OK");
+}
 
 rnb_err_t
-RNBRemote::HandlePacket_Q (const char *p)
+RNBRemote::HandlePacket_QStartNoAckMode (const char *p)
 {
-    if (p == NULL || strlen (p) <= 1)
-    {
-        return HandlePacket_ILLFORMED ("No subtype specified in Q packet");
-    }
+    // Send the OK packet first so the correct checksum is appended...
+    rnb_err_t result = SendPacket ("OK");
+    m_noack_mode = true;
+    return result;
+}
 
-    /* Switch to no-ack protocol mode after the "OK" packet is sent
-     and the ack for that comes back from gdb.  */
 
-    if (strcmp (p, "QStartNoAckMode") == 0)
-    {
-        rnb_err_t result = SendPacket ("OK");
-        m_noack_mode = true;
-        return result;
-    }
+rnb_err_t
+RNBRemote::HandlePacket_QSetLogging (const char *p)
+{
+    p += sizeof ("QSetLogging:") - 1;
+    rnb_err_t result = set_logging (p);
+    if (result == rnb_success)
+        return SendPacket ("OK");
+    else
+        return SendPacket ("E35");
+}
 
-    if (strncmp (p, "QSetLogging:", sizeof ("QSetLogging:") - 1) == 0)
+rnb_err_t
+RNBRemote::HandlePacket_QSetDisableASLR (const char *p)
+{
+    extern int g_disable_aslr;
+    p += sizeof ("QSetDisableASLR:") - 1;
+    switch (*p)
     {
-        p += sizeof ("QSetLogging:") - 1;
-        rnb_err_t result = set_logging (p);
-        if (result == rnb_success)
-            return SendPacket ("OK");
-        else
-            return SendPacket ("E35");
+    case '0': g_disable_aslr = 0; break;
+    case '1': g_disable_aslr = 1; break;
+    default:
+        return SendPacket ("E56");
     }
+    return SendPacket ("OK");
+}
 
-    if (strncmp (p, "QSetDisableASLR:", sizeof ("QSetDisableASLR:") - 1) == 0)
-    {
-        extern int g_disable_aslr;
-        p += sizeof ("QSetDisableASLR:") - 1;
-        switch (*p)
-        {
-        case '0': g_disable_aslr = 0; break;
-        case '1': g_disable_aslr = 1; break;
-        default:
-            return SendPacket ("E56");
-        }
-        return SendPacket ("OK");
-    }
 
+rnb_err_t
+RNBRemote::HandlePacket_QSetMaxPayloadSize (const char *p)
+{
     /* The number of characters in a packet payload that gdb is
      prepared to accept.  The packet-start char, packet-end char,
      2 checksum chars and terminating null character are not included
      in this size.  */
-    if (strncmp (p, "QSetMaxPayloadSize:", sizeof ("QSetMaxPayloadSize:") - 1) == 0)
+    p += sizeof ("QSetMaxPayloadSize:") - 1;
+    errno = 0;
+    uint32_t size = strtoul (p, NULL, 16);
+    if (errno != 0 && size == 0)
     {
-        p += sizeof ("QSetMaxPayloadSize:") - 1;
-        errno = 0;
-        uint32_t size = strtoul (p, NULL, 16);
-        if (errno != 0 && size == 0)
-        {
-            return HandlePacket_ILLFORMED ("Invalid length in QSetMaxPayloadSize packet");
-        }
-        m_max_payload_size = size;
-        return SendPacket ("OK");
+        return HandlePacket_ILLFORMED ("Invalid length in QSetMaxPayloadSize packet");
     }
+    m_max_payload_size = size;
+    return SendPacket ("OK");
+}
 
+rnb_err_t
+RNBRemote::HandlePacket_QSetMaxPacketSize (const char *p)
+{
     /* This tells us the largest packet that gdb can handle.
      i.e. the size of gdb's packet-reading buffer.
      QSetMaxPayloadSize is preferred because it is less ambiguous.  */
-
-    if (strncmp (p, "QSetMaxPacketSize:", sizeof ("QSetMaxPacketSize:") - 1) == 0)
+    p += sizeof ("QSetMaxPacketSize:") - 1;
+    errno = 0;
+    uint32_t size = strtoul (p, NULL, 16);
+    if (errno != 0 && size == 0)
     {
-        p += sizeof ("QSetMaxPacketSize:") - 1;
-        errno = 0;
-        uint32_t size = strtoul (p, NULL, 16);
-        if (errno != 0 && size == 0)
-        {
-            return HandlePacket_ILLFORMED ("Invalid length in QSetMaxPacketSize packet");
-        }
-        m_max_payload_size = size - 5;
-        return SendPacket ("OK");
+        return HandlePacket_ILLFORMED ("Invalid length in QSetMaxPacketSize packet");
     }
+    m_max_payload_size = size - 5;
+    return SendPacket ("OK");
+}
+
+
+
 
+rnb_err_t
+RNBRemote::HandlePacket_QEnvironment (const char *p)
+{
     /* This sets the environment for the target program.  The packet is of the form:
 
      QEnvironment:VARIABLE=VALUE
 
      */
 
-    if (strncmp (p, "QEnvironment:", sizeof ("QEnvironment:") - 1) == 0)
-    {
-        DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironment: \"%s\"",
-                          (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p);
+    DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironment: \"%s\"",
+                      (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p);
 
-        p += sizeof ("QEnvironment:") - 1;
-        RNBContext& ctx = Context();
-
-        ctx.PushEnvironment (p);
-        return SendPacket ("OK");
-    }
+    p += sizeof ("QEnvironment:") - 1;
+    RNBContext& ctx = Context();
 
-    // Unrecognized Q packet
-    return SendPacket ("");
+    ctx.PushEnvironment (p);
+    return SendPacket ("OK");
 }
 
 void
@@ -2245,7 +2248,9 @@
         InitializeRegisters ();
 
     nub_process_t pid = m_ctx.ProcessID ();
-    nub_thread_t tid = GetCurrentThread();
+    nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p + 1);
+    if (tid == INVALID_NUB_THREAD)
+        return HandlePacket_ILLFORMED ("No thread specified in p packet");
 
     if (m_use_native_regs)
     {
@@ -2291,7 +2296,9 @@
     packet.SetFilePos(1); // Skip the 'G'
     
     nub_process_t pid = m_ctx.ProcessID();
-    nub_thread_t tid = GetCurrentThread();
+    nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
+    if (tid == INVALID_NUB_THREAD)
+        return HandlePacket_ILLFORMED ("No thread specified in p packet");
 
     if (m_use_native_regs)
     {
@@ -2870,6 +2877,30 @@
     return HandlePacket_UNIMPLEMENTED(p);
 }
 
+// Extract the thread number from the thread suffix that might be appended to
+// thread specific packets. This will only be enabled if m_thread_suffix_supported
+// is true.
+nub_thread_t
+RNBRemote::ExtractThreadIDFromThreadSuffix (const char *p)
+{
+    if (m_thread_suffix_supported)
+    {
+        nub_thread_t tid = INVALID_NUB_THREAD;
+        if (p)
+        {
+            const char *tid_cstr = strstr (p, "thread:");
+            if (tid_cstr)
+            {
+                tid_cstr += strlen ("thread:");
+                tid = strtoul(tid_cstr, NULL, 16);
+            }
+            DNBLogThreadedIf (LOG_RNB_PACKETS, "RNBRemote::ExtractThreadIDFromThreadSuffix(%s) got thread 0x%4.4x", p, tid);
+        }
+    }
+    return GetCurrentThread();
+
+}
+
 /* `p XX'
  print the contents of register X */
 
@@ -2889,12 +2920,17 @@
     }
     nub_process_t pid = m_ctx.ProcessID();
     errno = 0;
-    uint32_t reg = strtoul (p + 1, NULL, 16);
+    char *tid_cstr = NULL;
+    uint32_t reg = strtoul (p + 1, &tid_cstr, 16);
     if (errno != 0 && reg == 0)
     {
-        return HandlePacket_ILLFORMED ("Could not parse thread number in p packet");
+        return HandlePacket_ILLFORMED ("Could not parse register number in p packet");
     }
 
+    nub_thread_t tid = ExtractThreadIDFromThreadSuffix (tid_cstr);
+    if (tid == INVALID_NUB_THREAD)
+        return HandlePacket_ILLFORMED ("No thread specified in p packet");
+
     const register_map_entry_t *reg_entry;
 
     if (reg < g_num_reg_entries)
@@ -2925,7 +2961,6 @@
     }
     else
     {
-        nub_thread_t tid = GetCurrentThread();
         register_value_in_hex_fixed_width (ostrm, pid, tid, reg_entry);
     }
     return SendPacket (ostrm.str());
@@ -2985,8 +3020,9 @@
     reg_value.info = reg_entry->nub_info;
     packet.GetHexBytes (reg_value.value.v_sint8, reg_entry->gdb_size, 0xcc);
 
-    nub_thread_t tid;
-    tid = GetCurrentThread ();
+    nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
+    if (tid == INVALID_NUB_THREAD)
+        return HandlePacket_ILLFORMED ("No thread specified in p packet");
 
     if (!DNBThreadSetRegisterValueByID (pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, &reg_value))
     {

Modified: lldb/trunk/tools/debugserver/source/RNBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.h?rev=123762&r1=123761&r2=123762&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBRemote.h (original)
+++ lldb/trunk/tools/debugserver/source/RNBRemote.h Tue Jan 18 13:36:39 2011
@@ -93,6 +93,7 @@
         query_host_info,                // 'qHostInfo'
         pass_signals_to_inferior,       // 'QPassSignals'
         start_noack_mode,               // 'QStartNoAckMode'
+        prefix_reg_packets_with_tid,    // 'QPrefixRegisterPacketsWithThreadID
         set_logging_mode,               // 'QSetLogging:'
         set_max_packet_size,            // 'QSetMaxPacketSize:'
         set_max_payload_size,           // 'QSetMaxPayloadSize:'
@@ -156,7 +157,14 @@
     rnb_err_t HandlePacket_qThreadExtraInfo (const char *p);
     rnb_err_t HandlePacket_qThreadStopInfo (const char *p);
     rnb_err_t HandlePacket_qHostInfo (const char *p);
-    rnb_err_t HandlePacket_Q (const char *p);
+    rnb_err_t HandlePacket_QStartNoAckMode (const char *p);
+    rnb_err_t HandlePacket_QThreadSuffixSupported (const char *p);
+    rnb_err_t HandlePacket_QSetLogging (const char *p);
+    rnb_err_t HandlePacket_QSetDisableASLR (const char *p);
+    rnb_err_t HandlePacket_QSetMaxPayloadSize (const char *p);
+    rnb_err_t HandlePacket_QSetMaxPacketSize (const char *p);
+    rnb_err_t HandlePacket_QEnvironment (const char *p);
+    rnb_err_t HandlePacket_QPrefixRegisterPacketsWithThreadID (const char *p);
     rnb_err_t HandlePacket_last_signal (const char *p);
     rnb_err_t HandlePacket_m (const char *p);
     rnb_err_t HandlePacket_M (const char *p);
@@ -237,6 +245,9 @@
     void CreatePacketTable ();
     rnb_err_t GetPacketPayload (std::string &);
 
+    nub_thread_t
+    ExtractThreadIDFromThreadSuffix (const char *p);
+
     // gdb can send multiple Z/z packets for the same address and
     // these calls must be ref counted.
     struct Breakpoint
@@ -286,7 +297,13 @@
     uint32_t        m_max_payload_size;  // the maximum sized payload we should send to gdb
     bool            m_extended_mode:1,   // are we in extended mode?
                     m_noack_mode:1,      // are we in no-ack mode?
-                    m_use_native_regs:1; // Use native registers by querying DNB layer for register definitions?
+                    m_noack_mode_just_enabled:1, // Did we just enable this and need to compute one more checksum?
+                    m_use_native_regs:1, // Use native registers by querying DNB layer for register definitions?
+                    m_thread_suffix_supported:1; // Set to true if the 'p', 'P', 'g', and 'G' packets should be prefixed with the thread ID and colon:
+                                                                // "$pRR;thread:TTTT;" instead of "$pRR"
+                                                                // "$PRR=VVVVVVVV;thread:TTTT;" instead of "$PRR=VVVVVVVV"
+                                                                // "$g;thread:TTTT" instead of "$g"
+                                                                // "$GVVVVVVVVVVVVVV;thread:TTTT;#00 instead of "$GVVVVVVVVVVVVVV"
 };
 
 /* We translate the /usr/include/mach/exception_types.h exception types





More information about the lldb-commits mailing list