[Lldb-commits] [lldb] r123127 - in /lldb/trunk: include/lldb/Expression/ include/lldb/Target/ source/Core/ source/Expression/ source/Plugins/Process/MacOSX-User/source/ source/Plugins/Process/Utility/ source/Plugins/Process/gdb-remote/ source/Target/

Greg Clayton gclayton at apple.com
Sun Jan 9 13:07:36 PST 2011


Author: gclayton
Date: Sun Jan  9 15:07:35 2011
New Revision: 123127

URL: http://llvm.org/viewvc/llvm-project?rev=123127&view=rev
Log:
Put more smarts into the RegisterContext base class. Now the base class has
a method:

    void RegisterContext::InvalidateIfNeeded (bool force);

Each time this function is called, when "force" is false, it will only call
the pure virtual "virtual void RegisterContext::InvalideAllRegisters()" if
the register context's stop ID doesn't match that of the process. When the
stop ID doesn't match, or "force" is true, the base class will clear its
cached registers and the RegisterContext will update its stop ID to match
that of the process. This helps make it easier to correctly flush the register
context (possibly from multiple locations depending on when and where new
registers are availabe) without inadvertently clearing the register cache 
when it doesn't need to be.

Modified the ProcessGDBRemote plug-in to be much more efficient when it comes
to:
- caching the expedited registers in the stop reply packets (we were ignoring
  these before and it was causing us to read at least three registers every
  time we stopped that were already supplied in the stop reply packet).
- When a thread has no stop reason, don't keep asking for the thread stopped
  info. Prior to this fix we would continually send a qThreadStopInfo packet
  over and over when any thread stop info was requested. We now note the stop
  ID that the stop info was requested for and avoid multiple requests.

Cleaned up some of the expression code to not look for ClangExpressionVariable
objects up by name since they are now shared pointers and we can just look for
the exact pointer match and avoid possible errors.

Fixed an bug in the ValueObject code that would cause children to not be 
displayed.


Modified:
    lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h
    lldb/trunk/include/lldb/Target/RegisterContext.h
    lldb/trunk/source/Core/ValueObject.cpp
    lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
    lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.cpp
    lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.h
    lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.cpp
    lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.h
    lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.cpp
    lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.h
    lldb/trunk/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h
    lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
    lldb/trunk/source/Target/Process.cpp
    lldb/trunk/source/Target/RegisterContext.cpp
    lldb/trunk/source/Target/Target.cpp

Modified: lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h?rev=123127&r1=123126&r2=123127&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h Sun Jan  9 15:07:35 2011
@@ -226,13 +226,13 @@
     //----------------------------------------------------------------------
     /// Implementation of methods in ClangExpressionVariableListBase
     //----------------------------------------------------------------------
-    virtual size_t 
+    size_t 
     GetSize()
     {
         return m_variables.size();
     }
     
-    virtual lldb::ClangExpressionVariableSP
+    lldb::ClangExpressionVariableSP
     GetVariableAtIndex(size_t index)
     {
         lldb::ClangExpressionVariableSP var_sp;
@@ -241,13 +241,25 @@
         return var_sp;
     }
     
-    virtual size_t
+    size_t
     AddVariable (const lldb::ClangExpressionVariableSP &var_sp)
     {
         m_variables.push_back(var_sp);
         return m_variables.size() - 1;
     }
 
+    bool
+    ContainsVariable (const lldb::ClangExpressionVariableSP &var_sp)
+    {
+        const size_t size = m_variables.size();
+        for (size_t index = 0; index < size; ++index)
+        {
+            if (m_variables[index].get() == var_sp.get())
+                return true;
+        }
+        return false;
+    }
+
     //----------------------------------------------------------------------
     /// Finds a variable by name in the list.
     ///

Modified: lldb/trunk/include/lldb/Target/RegisterContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/RegisterContext.h?rev=123127&r1=123126&r2=123127&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/RegisterContext.h (original)
+++ lldb/trunk/include/lldb/Target/RegisterContext.h Sun Jan  9 15:07:35 2011
@@ -31,11 +31,14 @@
     virtual
     ~RegisterContext ();
 
+    void
+    InvalidateIfNeeded (bool force);
+
     //------------------------------------------------------------------
     // Subclasses must override these functions
     //------------------------------------------------------------------
     virtual void
-    Invalidate () = 0;
+    InvalidateAllRegisters () = 0;
 
     virtual size_t
     GetRegisterCount () = 0;
@@ -163,12 +166,25 @@
     virtual void
     CalculateExecutionContext (ExecutionContext &exe_ctx);
 
+    uint32_t
+    GetStopID () const
+    {
+        return m_stop_id;
+    }
+
+    void
+    SetStopID (uint32_t stop_id)
+    {
+        m_stop_id = stop_id;
+    }
+
 protected:
     //------------------------------------------------------------------
     // Classes that inherit from RegisterContext can see and modify these
     //------------------------------------------------------------------
     Thread &m_thread;               // The thread that this register context belongs to.
     uint32_t m_concrete_frame_idx;    // The concrete frame index for this register context
+    uint32_t m_stop_id;             // The stop ID that any data in this context is valid for
 private:
     //------------------------------------------------------------------
     // For RegisterContext only

Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=123127&r1=123126&r2=123127&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Sun Jan  9 15:07:35 2011
@@ -1245,7 +1245,7 @@
                                                                       child_bitfield_bit_size,
                                                                       child_bitfield_bit_offset,
                                                                       child_is_base_class);
-        if (child_clang_type && child_byte_offset)
+        if (child_clang_type && child_byte_size)
         {
             ConstString child_name;
             if (!child_name_str.empty())

Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=123127&r1=123126&r2=123127&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Sun Jan  9 15:07:35 2011
@@ -713,13 +713,9 @@
     {
         ClangExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(member_index));
         
-        ClangExpressionVariableSP entity_sp (m_found_entities.GetVariable(member_sp->GetName()));
-         
-        ClangExpressionVariableSP persistent_var_sp (persistent_vars.GetVariable(member_sp->GetName()));
-        
-        if (entity_sp)
+        if (m_found_entities.ContainsVariable (member_sp))
         {
-            RegisterInfo *reg_info = entity_sp->GetRegisterInfo ();
+            RegisterInfo *reg_info = member_sp->GetRegisterInfo ();
             if (reg_info)
             {
                 // This is a register variable
@@ -752,34 +748,36 @@
                     return false;
             }
         }
-        else if (persistent_var_sp)
+        else
         {
-            if (member_sp->GetName() == m_struct_vars->m_result_name)
+            // No need to look for presistent variables if the name doesn't start 
+            // with with a '$' character...
+            if (member_sp->GetName().AsCString ("!")[0] == '$' && persistent_vars.ContainsVariable(member_sp))
             {
-                if (!dematerialize)
-                    continue;
-                
-                if (log)
-                    log->PutCString("Found result member in the struct");
-                
-                if (result_sp_ptr)
-                    *result_sp_ptr = member_sp;
+                if (member_sp->GetName() == m_struct_vars->m_result_name)
+                {
+                    if (!dematerialize)
+                        continue;
+                    
+                    if (log)
+                        log->PutCString("Found result member in the struct");
+                    
+                    if (result_sp_ptr)
+                        *result_sp_ptr = member_sp;
+                }
+
+                if (!DoMaterializeOnePersistentVariable (dematerialize, 
+                                                         exe_ctx, 
+                                                         member_sp, 
+                                                         m_material_vars->m_materialized_location + member_sp->m_jit_vars->m_offset, 
+                                                         err))
+                    return false;
             }
-            
-            if (log)
-                log->Printf("Searched for persistent variable %s and found %s", member_sp->GetName().GetCString(), persistent_var_sp->GetName().GetCString());
-            
-            if (!DoMaterializeOnePersistentVariable (dematerialize, 
-                                                     exe_ctx, 
-                                                     persistent_var_sp, 
-                                                     m_material_vars->m_materialized_location + member_sp->m_jit_vars->m_offset, 
-                                                     err))
+            else
+            {
+                err.SetErrorStringWithFormat("Unexpected variable %s", member_sp->GetName().GetCString());
                 return false;
-        }
-        else
-        {
-            err.SetErrorStringWithFormat("Unexpected variable %s", member_sp->GetName().GetCString());
-            return false;
+            }
         }
     }
     

Modified: lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.cpp?rev=123127&r1=123126&r2=123127&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.cpp Sun Jan  9 15:07:35 2011
@@ -394,7 +394,7 @@
 static size_t k_num_register_infos = (sizeof(g_register_infos)/sizeof(RegisterInfo));
 
 void
-RegisterContextMach_arm::Invalidate ()
+RegisterContextMach_arm::InvalidateAllRegisters ()
 {
     InvalidateAllRegisterStates();
 }

Modified: lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.h?rev=123127&r1=123126&r2=123127&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.h (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_arm.h Sun Jan  9 15:07:35 2011
@@ -60,7 +60,7 @@
     ~RegisterContextMach_arm();
 
     virtual void
-    Invalidate ();
+    InvalidateAllRegisters ();
 
     virtual size_t
     GetRegisterCount ();

Modified: lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.cpp?rev=123127&r1=123126&r2=123127&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.cpp Sun Jan  9 15:07:35 2011
@@ -275,7 +275,7 @@
 static size_t k_num_register_infos = (sizeof(g_register_infos)/sizeof(RegisterInfo));
 
 void
-RegisterContextMach_i386::Invalidate ()
+RegisterContextMach_i386::InvalidateAllRegisters ()
 {
     InvalidateAllRegisterStates();
 }

Modified: lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.h?rev=123127&r1=123126&r2=123127&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.h (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_i386.h Sun Jan  9 15:07:35 2011
@@ -28,7 +28,7 @@
     ~RegisterContextMach_i386();
 
     virtual void
-    Invalidate ();
+    InvalidateAllRegisters ();
 
     virtual size_t
     GetRegisterCount ();

Modified: lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.cpp?rev=123127&r1=123126&r2=123127&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.cpp Sun Jan  9 15:07:35 2011
@@ -311,7 +311,7 @@
 
 
 void
-RegisterContextMach_x86_64::Invalidate ()
+RegisterContextMach_x86_64::InvalidateAllRegisters ()
 {
     InvalidateAllRegisterStates();
 }

Modified: lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.h?rev=123127&r1=123126&r2=123127&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.h (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/RegisterContextMach_x86_64.h Sun Jan  9 15:07:35 2011
@@ -27,7 +27,7 @@
     ~RegisterContextMach_x86_64();
 
     virtual void
-    Invalidate ();
+    InvalidateAllRegisters ();
 
     virtual size_t
     GetRegisterCount ();

Modified: lldb/trunk/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp?rev=123127&r1=123126&r2=123127&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp Sun Jan  9 15:07:35 2011
@@ -198,7 +198,7 @@
 ThreadMacOSX::RefreshStateAfterStop()
 {
     // Invalidate all registers in our register context
-    GetRegisterContext()->Invalidate();
+    GetRegisterContext()->InvalidateIfNeeded (false);
 
     m_context->RefreshStateAfterStop();
 
@@ -650,7 +650,7 @@
 
         // Clear out all stack frames as our world just changed.
         ClearStackFrames();
-        frame_sp->GetRegisterContext()->Invalidate();
+        frame_sp->GetRegisterContext()->InvalidateIfNeeded(true);
 
         return ret;
     }

Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp?rev=123127&r1=123126&r2=123127&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Sun Jan  9 15:07:35 2011
@@ -633,7 +633,7 @@
 
 
 void
-RegisterContextLLDB::Invalidate ()
+RegisterContextLLDB::InvalidateAllRegisters ()
 {
     m_frame_type = eNotAValidFrame;
 }

Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h?rev=123127&r1=123126&r2=123127&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h Sun Jan  9 15:07:35 2011
@@ -33,7 +33,7 @@
     ~RegisterContextLLDB () { }
 
     virtual void
-    Invalidate ();
+    InvalidateAllRegisters ();
 
     virtual size_t
     GetRegisterCount ();

Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp?rev=123127&r1=123126&r2=123127&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp Sun Jan  9 15:07:35 2011
@@ -46,7 +46,7 @@
 }
 
 void
-RegisterContextMacOSXFrameBackchain::Invalidate ()
+RegisterContextMacOSXFrameBackchain::InvalidateAllRegisters ()
 {
     m_cursor_is_valid = false;
 }

Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h?rev=123127&r1=123126&r2=123127&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h Sun Jan  9 15:07:35 2011
@@ -36,7 +36,7 @@
     // Subclasses must override these functions
     //------------------------------------------------------------------
     virtual void
-    Invalidate ();
+    InvalidateAllRegisters ();
 
     virtual size_t
     GetRegisterCount ();

Modified: lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp?rev=123127&r1=123126&r2=123127&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp Sun Jan  9 15:07:35 2011
@@ -35,6 +35,7 @@
     {
 //#define DEBUG_FRAME_SPEED 1
 #if DEBUG_FRAME_SPEED
+#define FRAME_COUNT 10000
         TimeValue time_value (TimeValue::Now());
 #endif
         if (!AddFirstFrame ())
@@ -42,11 +43,15 @@
         while (AddOneMoreFrame ())
         {
 #if DEBUG_FRAME_SPEED
-            if ((m_frames.size() % 10000) == 0)
+            if ((m_frames.size() % FRAME_COUNT) == 0)
             {
                 TimeValue now(TimeValue::Now());
                 uint64_t delta_t = now - time_value;
-                printf ("10000 frames in %llu.%09llu ms\n", delta_t / NSEC_PER_SEC, delta_t % NSEC_PER_SEC);
+                printf ("%u frames in %llu.%09llu ms (%g frames/sec)\n", 
+                        FRAME_COUNT,
+                        delta_t / NSEC_PER_SEC, 
+                        delta_t % NSEC_PER_SEC,
+                        (float)FRAME_COUNT / ((float)delta_t / (float)NSEC_PER_SEC));
                 time_value = now;
             }
 #endif

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=123127&r1=123126&r2=123127&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp Sun Jan  9 15:07:35 2011
@@ -39,7 +39,6 @@
     RegisterContext (thread, concrete_frame_idx),
     m_reg_info (reg_info),
     m_reg_valid (),
-    m_reg_valid_stop_id (),
     m_reg_data (),
     m_read_all_at_once (read_all_at_once)
 {
@@ -74,7 +73,7 @@
 }
 
 void
-GDBRemoteRegisterContext::Invalidate ()
+GDBRemoteRegisterContext::InvalidateAllRegisters ()
 {
     SetAllRegisterValid (false);
 }
@@ -179,25 +178,41 @@
     return false;
 }
 
+void
+GDBRemoteRegisterContext::PrivateSetRegisterValue (uint32_t reg, StringExtractor &response)
+{
+    const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg);
+    assert (reg_info);
+
+    // Invalidate if needed
+    InvalidateIfNeeded(false);
+
+    const uint32_t reg_byte_size = reg_info->byte_size;
+    const size_t bytes_copied = response.GetHexBytes (const_cast<uint8_t*>(m_reg_data.PeekData(reg_info->byte_offset, reg_byte_size)), reg_byte_size, '\xcc');
+    bool success = bytes_copied == reg_byte_size;
+    if (success)
+    {
+        m_reg_valid[reg] = true;
+    }
+    else if (bytes_copied > 0)
+    {
+        // Only set register is valid to false if we copied some bytes, else 
+        // leave it as it was.
+        m_reg_valid[reg] = false;
+    }
+}
+
 
 bool
 GDBRemoteRegisterContext::ReadRegisterBytes (uint32_t reg, DataExtractor &data)
 {
     GDBRemoteCommunication &gdb_comm = GetGDBProcess().GetGDBRemote();
-// FIXME: This check isn't right because IsRunning checks the Public state, but this
-// is work you need to do - for instance in ShouldStop & friends - before the public 
-// state has been changed.
-//    if (gdb_comm.IsRunning())
-//        return false;
 
-    if (m_reg_valid_stop_id != m_thread.GetProcess().GetStopID())
-    {
-        Invalidate();
-        m_reg_valid_stop_id = m_thread.GetProcess().GetStopID();
-    }
+    InvalidateIfNeeded(false);
+
     const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg);
     assert (reg_info);
-    if (m_reg_valid[reg] == false)
+    if (!m_reg_valid[reg])
     {
         Mutex::Locker locker;
         if (gdb_comm.GetSequenceMutex (locker))
@@ -225,28 +240,27 @@
                     packet_len = ::snprintf (packet, sizeof(packet), "p%x", reg);
                     assert (packet_len < (sizeof(packet) - 1));
                     if (gdb_comm.SendPacketAndWaitForResponse(packet, response, 1, false))
-                        if (response.GetHexBytes (const_cast<uint8_t*>(m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size)), reg_info->byte_size, '\xcc') == reg_info->byte_size)
-                            m_reg_valid[reg] = true;
+                        PrivateSetRegisterValue (reg, response);
                 }
             }
         }
+
+        // Make sure we got a valid register value after reading it
+        if (!m_reg_valid[reg])
+            return false;
     }
 
-    bool reg_is_valid = m_reg_valid[reg];
-    if (reg_is_valid)
+    if (&data != &m_reg_data)
     {
-        if (&data != &m_reg_data)
-        {
-            // If we aren't extracting into our own buffer (which
-            // only happens when this function is called from
-            // ReadRegisterValue(uint32_t, Scalar&)) then
-            // we transfer bytes from our buffer into the data
-            // buffer that was passed in
-            data.SetByteOrder (m_reg_data.GetByteOrder());
-            data.SetData (m_reg_data, reg_info->byte_offset, reg_info->byte_size);
-        }
+        // If we aren't extracting into our own buffer (which
+        // only happens when this function is called from
+        // ReadRegisterValue(uint32_t, Scalar&)) then
+        // we transfer bytes from our buffer into the data
+        // buffer that was passed in
+        data.SetByteOrder (m_reg_data.GetByteOrder());
+        data.SetData (m_reg_data, reg_info->byte_offset, reg_info->byte_size);
     }
-    return reg_is_valid;
+    return true;
 }
 
 
@@ -323,8 +337,8 @@
                                               eByteOrderHost);
                     
                     // Invalidate all register values
-                    Invalidate ();
-                    
+                    InvalidateIfNeeded (true);
+
                     if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
                                                               packet.GetString().size(),
                                                               response,

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h?rev=123127&r1=123126&r2=123127&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h Sun Jan  9 15:07:35 2011
@@ -25,6 +25,7 @@
 
 class ThreadGDBRemote;
 class ProcessGDBRemote;
+class StringExtractor;
 
 class GDBRemoteDynamicRegisterInfo
 {
@@ -189,7 +190,7 @@
     // Subclasses must override these functions
     //------------------------------------------------------------------
     virtual void
-    Invalidate ();
+    InvalidateAllRegisters ();
 
     virtual size_t
     GetRegisterCount ();
@@ -225,8 +226,12 @@
     ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num);
 
 protected:
+    friend class ThreadGDBRemote;
 
     void
+    PrivateSetRegisterValue (uint32_t reg, StringExtractor &response);
+    
+    void
     SetAllRegisterValid (bool b);
 
     ProcessGDBRemote &
@@ -237,7 +242,6 @@
 
     GDBRemoteDynamicRegisterInfo &m_reg_info;
     std::vector<bool> m_reg_valid;
-    uint32_t m_reg_valid_stop_id;
     lldb_private::DataExtractor m_reg_data;
     bool m_read_all_at_once;
 

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=123127&r1=123126&r2=123127&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Sun Jan  9 15:07:35 2011
@@ -975,9 +975,7 @@
                     if (tid != LLDB_INVALID_THREAD_ID)
                     {
                         ThreadSP thread_sp (GetThreadList().FindThreadByID (tid, false));
-                        if (thread_sp)
-                            thread_sp->GetRegisterContext()->Invalidate();
-                        else
+                        if (!thread_sp)
                             thread_sp.reset (new ThreadGDBRemote (*this, tid));
                         curr_thread_list.AddThread(thread_sp);
                     }
@@ -1014,6 +1012,8 @@
             uint32_t tid = LLDB_INVALID_THREAD_ID;
             addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS;
             uint32_t exc_data_count = 0;
+            ThreadSP thread_sp;
+
             while (stop_packet.GetNameColonValue(name, value))
             {
                 if (name.compare("metype") == 0)
@@ -1035,6 +1035,7 @@
                 {
                     // thread in big endian hex
                     tid = Args::StringToUInt32 (value.c_str(), 0, 16);
+                    thread_sp = m_thread_list.FindThreadByID(tid, false);
                 }
                 else if (name.compare("hexname") == 0)
                 {
@@ -1053,8 +1054,25 @@
                 {
                     thread_dispatch_qaddr = Args::StringToUInt64 (value.c_str(), 0, 16);
                 }
+                else if (name.size() == 2 && ::isxdigit(name[0]) && ::isxdigit(name[1]))
+                {
+                    // We have a register number that contains an expedited
+                    // register value. Lets supply this register to our thread
+                    // so it won't have to go and read it.
+                    if (thread_sp)
+                    {
+                        uint32_t reg = Args::StringToUInt32 (name.c_str(), UINT32_MAX, 16);
+
+                        if (reg != UINT32_MAX)
+                        {
+                            StringExtractor reg_value_extractor;
+                            // Swap "value" over into "reg_value_extractor"
+                            reg_value_extractor.GetStringRef().swap(value);
+                            static_cast<ThreadGDBRemote *> (thread_sp.get())->PrivateSetRegisterValue (reg, reg_value_extractor);
+                        }
+                    }
+                }
             }
-            ThreadSP thread_sp (m_thread_list.FindThreadByID(tid, false));
 
             if (thread_sp)
             {

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=123127&r1=123126&r2=123127&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp Sun Jan  9 15:07:35 2011
@@ -37,7 +37,8 @@
     Thread(process, tid),
     m_thread_name (),
     m_dispatch_queue_name (),
-    m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS)
+    m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS),
+    m_thread_stop_reason_stop_id (0)
 {
 //    ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD | GDBR_LOG_VERBOSE, "ThreadGDBRemote::ThreadGDBRemote ( pid = %i, tid = 0x%4.4x, )", m_process.GetID(), GetID());
     ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", this, m_process.GetID(), GetID());
@@ -116,14 +117,18 @@
 void
 ThreadGDBRemote::RefreshStateAfterStop()
 {
-    // Invalidate all registers in our register context
-    GetRegisterContext()->Invalidate();
+    // Invalidate all registers in our register context. We don't set "force" to
+    // true because the stop reply packet might have had some register values
+    // that were expedited and these will already be copied into the register
+    // context by the time this function gets called. The GDBRemoteRegisterContext
+    // class has been made smart enough to detect when it needs to invalidate
+    // which registers are valid by putting hooks in the register read and 
+    // register supply functions where they check the process stop ID and do
+    // the right thing.
+    const bool force = false;
+    GetRegisterContext()->InvalidateIfNeeded (force);
 }
 
-// Whether to use the new native unwinder (UnwindLLDB) or the libunwind-remote based unwinder for
-// stack walks on i386/x86_64
-#define USE_NATIVE_UNWINDER
-
 Unwind *
 ThreadGDBRemote::GetUnwinder ()
 {
@@ -132,11 +137,7 @@
         const ArchSpec target_arch (GetProcess().GetTarget().GetArchitecture ());
         if (target_arch == ArchSpec("x86_64") ||  target_arch == ArchSpec("i386"))
         {
-#if defined (USE_NATIVE_UNWINDER)
             m_unwinder_ap.reset (new UnwindLLDB (*this));
-#else
-            m_unwinder_ap.reset (new UnwindLibUnwind (*this, GetGDBProcess().GetLibUnwindAddressSpace()));
-#endif
         }
         else
         {
@@ -198,6 +199,14 @@
     return reg_ctx_sp;
 }
 
+void
+ThreadGDBRemote::PrivateSetRegisterValue (uint32_t reg, StringExtractor &response)
+{
+    GDBRemoteRegisterContext *gdb_reg_ctx = static_cast<GDBRemoteRegisterContext *>(GetRegisterContext ().get());
+    assert (gdb_reg_ctx);
+    gdb_reg_ctx->PrivateSetRegisterValue (reg, response);
+}
+
 bool
 ThreadGDBRemote::SaveFrameZeroState (RegisterCheckpoint &checkpoint)
 {
@@ -217,7 +226,7 @@
     if (frame_sp)
     {
         bool ret = frame_sp->GetRegisterContext()->WriteAllRegisterValues (checkpoint.GetData());
-        frame_sp->GetRegisterContext()->Invalidate();
+        frame_sp->GetRegisterContext()->InvalidateIfNeeded(true);
         ClearStackFrames();
         return ret;
     }
@@ -227,8 +236,19 @@
 lldb::StopInfoSP
 ThreadGDBRemote::GetPrivateStopReason ()
 {
-    if (m_actual_stop_info_sp.get() == NULL || m_actual_stop_info_sp->IsValid() == false)
+    const uint32_t process_stop_id = GetProcess().GetStopID();
+    if (m_thread_stop_reason_stop_id != process_stop_id ||
+        (m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
     {
+        // If GetGDBProcess().SetThreadStopInfo() doesn't find a stop reason
+        // for this thread, then m_actual_stop_info_sp will not ever contain
+        // a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
+        // check will never be able to tell us if we have the correct stop info
+        // for this thread and we will continually send qThreadStopInfo packets
+        // down to the remote GDB server, so we need to keep our own notion
+        // of the stop ID that m_actual_stop_info_sp is valid for (even if it
+        // contains nothing). We use m_thread_stop_reason_stop_id for this below.
+        m_thread_stop_reason_stop_id = process_stop_id;
         m_actual_stop_info_sp.reset();
 
         char packet[256];
@@ -236,7 +256,6 @@
         StringExtractorGDBRemote stop_packet;
         if (GetGDBProcess().GetGDBRemote().SendPacketAndWaitForResponse(packet, stop_packet, 1, false))
         {
-            std::string copy(stop_packet.GetStringRef());
             GetGDBProcess().SetThreadStopInfo (stop_packet);
         }
     }

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h?rev=123127&r1=123126&r2=123127&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h Sun Jan  9 15:07:35 2011
@@ -108,12 +108,20 @@
     }
 
 protected:
+    
+    friend class ProcessGDBRemote;
+
+    void
+    PrivateSetRegisterValue (uint32_t reg, 
+                             StringExtractor &response);
+                             
     //------------------------------------------------------------------
     // Member variables.
     //------------------------------------------------------------------
     std::string m_thread_name;
     std::string m_dispatch_queue_name;
     lldb::addr_t m_thread_dispatch_qaddr;
+    uint32_t m_thread_stop_reason_stop_id;
     //------------------------------------------------------------------
     // Member variables.
     //------------------------------------------------------------------

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=123127&r1=123126&r2=123127&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Sun Jan  9 15:07:35 2011
@@ -234,7 +234,7 @@
     m_addr_byte_size (0),
     m_abi_sp (),
     m_process_input_reader (),
-    m_stdio_communication ("lldb.process.stdio"),
+    m_stdio_communication ("process.stdio"),
     m_stdio_communication_mutex (Mutex::eMutexTypeRecursive),
     m_stdout_data (),
     m_memory_cache ()
@@ -2004,7 +2004,9 @@
 
     // Create a thread that watches our internal state and controls which
     // events make it to clients (into the DCProcess event queue).
-    m_private_state_thread = Host::ThreadCreate ("<lldb.process.internal-state>", Process::PrivateStateThread, this, NULL);
+    char thread_name[1024];
+    snprintf(thread_name, sizeof(thread_name), "<lldb.process.internal-state(pid=%i)>", GetID());
+    m_private_state_thread = Host::ThreadCreate (thread_name, Process::PrivateStateThread, this, NULL);
     return m_private_state_thread != LLDB_INVALID_HOST_THREAD;
 }
 

Modified: lldb/trunk/source/Target/RegisterContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/RegisterContext.cpp?rev=123127&r1=123126&r2=123127&view=diff
==============================================================================
--- lldb/trunk/source/Target/RegisterContext.cpp (original)
+++ lldb/trunk/source/Target/RegisterContext.cpp Sun Jan  9 15:07:35 2011
@@ -16,6 +16,7 @@
 #include "lldb/Core/Scalar.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Process.h"
 #include "lldb/Target/Thread.h"
 
 using namespace lldb;
@@ -23,7 +24,8 @@
 
 RegisterContext::RegisterContext (Thread &thread, uint32_t concrete_frame_idx) :
     m_thread (thread),
-    m_concrete_frame_idx (concrete_frame_idx)
+    m_concrete_frame_idx (concrete_frame_idx),
+    m_stop_id (thread.GetProcess().GetStopID())
 {
 }
 
@@ -34,6 +36,19 @@
 {
 }
 
+void
+RegisterContext::InvalidateIfNeeded (bool force)
+{
+    const uint32_t this_stop_id = GetStopID();
+    const uint32_t process_stop_id = m_thread.GetProcess().GetStopID();    
+    if (force || process_stop_id != this_stop_id)
+    {
+        InvalidateAllRegisters ();
+        SetStopID (process_stop_id);
+    }
+}
+
+
 const RegisterInfo *
 RegisterContext::GetRegisterInfoByName (const char *reg_name, uint32_t start_idx)
 {

Modified: lldb/trunk/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=123127&r1=123126&r2=123127&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Sun Jan  9 15:07:35 2011
@@ -961,7 +961,11 @@
     {
         // Make sure we aren't just trying to see the value of a persistent 
         // variable (something like "$0")
-        lldb::ClangExpressionVariableSP persistent_var_sp (m_persistent_variables.GetVariable (expr_cstr));
+        lldb::ClangExpressionVariableSP persistent_var_sp;
+        // Only check for persistent variables the expression starts with a '$' 
+        if (expr_cstr[0] == '$')
+            persistent_var_sp = m_persistent_variables.GetVariable (expr_cstr);
+
         if (persistent_var_sp)
         {
             result_valobj_sp = persistent_var_sp->GetValueObject ();





More information about the lldb-commits mailing list