[Lldb-commits] [lldb] r118879 - in /lldb/trunk: include/lldb/Target/ThreadPlanTracer.h source/Target/ThreadPlanTracer.cpp

Sean Callanan scallanan at apple.com
Thu Nov 11 19:22:22 PST 2010


Author: spyffe
Date: Thu Nov 11 21:22:21 2010
New Revision: 118879

URL: http://llvm.org/viewvc/llvm-project?rev=118879&view=rev
Log:
Added a thread plan tracer that prints lines of
assembly as well as registers that changed.

Modified:
    lldb/trunk/include/lldb/Target/ThreadPlanTracer.h
    lldb/trunk/source/Target/ThreadPlanTracer.cpp

Modified: lldb/trunk/include/lldb/Target/ThreadPlanTracer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanTracer.h?rev=118879&r1=118878&r2=118879&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanTracer.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanTracer.h Thu Nov 11 21:22:21 2010
@@ -15,6 +15,7 @@
 // Other libraries and framework includes
 // Project includes
 #include "lldb/lldb-private.h"
+#include "lldb/Symbol/TaggedASTType.h"
 #include "lldb/Target/Thread.h"
 
 namespace lldb_private {
@@ -98,6 +99,24 @@
     bool m_enabled;
     lldb::StreamSP m_stream_sp;
 };
+    
+class ThreadPlanAssemblyTracer : public ThreadPlanTracer
+{
+public:
+    ThreadPlanAssemblyTracer (Thread &thread, lldb::StreamSP &stream_sp);    
+    virtual ~ThreadPlanAssemblyTracer ();
+    virtual void TracingStarted ();
+    virtual void TracingEnded ();
+    virtual void Log();
+private:
+    Process                &m_process;
+    Target                 &m_target;
+    Disassembler           *m_disassembler;
+    const ABI              *m_abi;
+    TypeFromUser            m_intptr_type;
+    std::vector<uint64_t>   m_register_values;
+    lldb::DataBufferSP      m_buffer_sp;
+};
 
 } // namespace lldb_private
 

Modified: lldb/trunk/source/Target/ThreadPlanTracer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanTracer.cpp?rev=118879&r1=118878&r2=118879&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanTracer.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanTracer.cpp Thu Nov 11 21:22:21 2010
@@ -10,12 +10,18 @@
 #include "lldb/Target/ThreadPlan.h"
 
 // C Includes
+#include <string.h>
 // C++ Includes
 // Other libraries and framework includes
 // Project includes
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/Debugger.h"
+#include "lldb/Core/Disassembler.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/State.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Symbol/TypeList.h"
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/Thread.h"
 #include "lldb/Target/Process.h"
@@ -24,6 +30,8 @@
 using namespace lldb;
 using namespace lldb_private;
 
+#pragma mark ThreadPlanTracer
+
 ThreadPlanTracer::ThreadPlanTracer (Thread &thread, lldb::StreamSP &stream_sp) :
     m_single_step(true),
     m_enabled (false),
@@ -75,3 +83,200 @@
     else
         return false;
 }
+
+#pragma mark ThreadPlanAssemblyTracer
+
+ThreadPlanAssemblyTracer::ThreadPlanAssemblyTracer (Thread &thread, lldb::StreamSP &stream_sp) :
+    ThreadPlanTracer (thread, stream_sp),
+    m_process(thread.GetProcess()),
+    m_target(thread.GetProcess().GetTarget())
+{
+    Process &process = thread.GetProcess();
+    Target &target = process.GetTarget();
+    
+    ArchSpec arch(target.GetArchitecture());
+    
+    m_disassembler = Disassembler::FindPlugin(arch);
+    
+    m_abi = process.GetABI();
+    
+    ModuleSP executableModuleSP (target.GetExecutableModule());
+    TypeList *type_list = executableModuleSP->GetTypeList();
+    
+    if (type_list)
+    {
+        m_intptr_type = TypeFromUser(type_list->GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, arch.GetAddressByteSize() * 8),
+                                     type_list->GetClangASTContext().getASTContext());
+    }
+    
+    const unsigned int buf_size = 32;
+    
+    m_buffer_sp.reset(new DataBufferHeap(buf_size, 0));
+}
+
+ThreadPlanAssemblyTracer::~ThreadPlanAssemblyTracer()
+{
+}
+
+void ThreadPlanAssemblyTracer::TracingStarted ()
+{
+    RegisterContext *reg_ctx = m_thread.GetRegisterContext();
+    
+    if (m_register_values.size() == 0)
+    {
+        for (uint32_t reg_index = 0, num_registers = reg_ctx->GetRegisterCount();
+             reg_index < num_registers;
+             ++reg_index)
+            m_register_values.push_back(0);
+    }
+}
+
+void ThreadPlanAssemblyTracer::TracingEnded ()
+{
+    for (uint32_t reg_index = 0, num_registers = m_register_values.size();
+         reg_index < num_registers;
+         ++reg_index)
+        m_register_values[reg_index] = 0;
+}
+
+static const char *Padding(int length)
+{
+    const int padding_size = 256;
+
+    static char* padding = NULL;
+    static int prev_length = 256;
+
+    if (!padding) {
+        padding = new char[padding_size];
+        memset(padding, ' ', padding_size);
+    }
+
+    if (length > 255)
+        length = 255;
+
+    if (prev_length < 256)
+        padding[prev_length] = ' ';
+
+    padding[length] = '\0';
+
+    prev_length = length;
+
+    return padding;
+}
+
+static void PadOutTo(StreamString &stream, int target)
+{
+    stream.Flush();
+
+    int length = stream.GetString().length();
+
+    if (length + 1 < target)
+        stream.PutCString(Padding(target - (length + 1)));
+
+    stream.PutCString(" ");
+}
+
+void ThreadPlanAssemblyTracer::Log ()
+{
+    Stream *stream = GetLogStream ();
+    
+    if (!stream)
+        return;
+            
+    RegisterContext *reg_ctx = m_thread.GetRegisterContext();
+    
+    lldb::addr_t pc = reg_ctx->GetPC();
+    Address pc_addr;
+    bool addr_valid = false;
+    
+    StreamString desc;
+    
+    int desired_width = 0;
+    
+    addr_valid = m_process.GetTarget().GetSectionLoadList().ResolveLoadAddress (pc, pc_addr);
+    
+    pc_addr.Dump(&desc, &m_thread, Address::DumpStyleResolvedDescription, Address::DumpStyleModuleWithFileAddress);
+    
+    desired_width += 64;
+    PadOutTo(desc, desired_width);
+    
+    if (m_disassembler)
+    {        
+        bzero(m_buffer_sp->GetBytes(), m_buffer_sp->GetByteSize());
+        
+        Error err;
+        m_process.ReadMemory(pc, m_buffer_sp->GetBytes(), m_buffer_sp->GetByteSize(), err);
+        
+        if (err.Success())
+        {
+            DataExtractor extractor(m_buffer_sp,
+                                    m_process.GetByteOrder(),
+                                    m_process.GetAddressByteSize());
+            
+            if (addr_valid)
+                m_disassembler->DecodeInstructions (pc_addr, extractor, 0, 1);
+            else
+                m_disassembler->DecodeInstructions (Address (NULL, pc), extractor, 0, 1);
+            
+            InstructionList &instruction_list = m_disassembler->GetInstructionList();
+            
+            if (instruction_list.GetSize())
+            {
+                Instruction *instruction = instruction_list.GetInstructionAtIndex(0).get();
+                instruction->Dump (&desc,
+                                   false,
+                                   NULL, 
+                                   0, 
+                                   NULL, 
+                                   true);
+            }
+        }
+        
+        desired_width += 32;
+        PadOutTo(desc, desired_width);
+    }
+    
+    if (m_abi && m_intptr_type.GetOpaqueQualType())
+    {
+        ValueList value_list;
+        const int num_args = 1;
+        
+        for (int arg_index = 0; arg_index < num_args; ++arg_index)
+        {
+            Value value;
+            value.SetValueType (Value::eValueTypeScalar);
+            value.SetContext (Value::eContextTypeOpaqueClangQualType, m_intptr_type.GetOpaqueQualType());
+            value_list.PushValue (value);
+        }
+        
+        if (m_abi->GetArgumentValues (m_thread, value_list))
+        {                
+            for (int arg_index = 0; arg_index < num_args; ++arg_index)
+            {
+                desc.Printf("arg[%d]=%llx", arg_index, value_list.GetValueAtIndex(arg_index)->GetScalar().ULongLong());
+                
+                if (arg_index + 1 < num_args)
+                    desc.Printf(", ");
+            }
+        }
+    }
+    
+    desired_width += 20;
+    PadOutTo(desc, desired_width);
+    
+    for (uint32_t reg_index = 0, num_registers = reg_ctx->GetRegisterCount();
+         reg_index < num_registers;
+         ++reg_index)
+    {
+        uint64_t reg_value = reg_ctx->ReadRegisterAsUnsigned(reg_index, 0x0);
+        
+        if (reg_value != m_register_values[reg_index])
+        {
+            desc.Printf ("%s:0x%llx->0x%llx ", reg_ctx->GetRegisterName(reg_index), m_register_values[reg_index], reg_value);
+            
+            m_register_values[reg_index] = reg_value;
+        }
+    }
+    
+    stream->Printf ("Single-step: %s", desc.GetString().c_str());
+}





More information about the lldb-commits mailing list