[Lldb-commits] [lldb] r154701 - in /lldb/branches/lldb-platform-work: ./ include/lldb/Target/ThreadPlanCallFunction.h source/Target/Memory.cpp source/Target/ThreadPlanCallFunction.cpp test/types/AbstractBase.py

Johnny Chen johnny.chen at apple.com
Fri Apr 13 13:47:02 PDT 2012


Author: johnny
Date: Fri Apr 13 15:47:02 2012
New Revision: 154701

URL: http://llvm.org/viewvc/llvm-project?rev=154701&view=rev
Log:
Merge changes from ToT:

svn merge -r 154683:154699 https://johnny@llvm.org/svn/llvm-project/lldb/trunk .

Modified:
    lldb/branches/lldb-platform-work/   (props changed)
    lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanCallFunction.h
    lldb/branches/lldb-platform-work/source/Target/Memory.cpp
    lldb/branches/lldb-platform-work/source/Target/ThreadPlanCallFunction.cpp
    lldb/branches/lldb-platform-work/test/types/AbstractBase.py

Propchange: lldb/branches/lldb-platform-work/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Apr 13 15:47:02 2012
@@ -1 +1 @@
-/lldb/trunk:154224-154683
+/lldb/trunk:154224-154699

Modified: lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanCallFunction.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanCallFunction.h?rev=154701&r1=154700&r2=154701&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanCallFunction.h (original)
+++ lldb/branches/lldb-platform-work/include/lldb/Target/ThreadPlanCallFunction.h Fri Apr 13 15:47:02 2012
@@ -130,6 +130,14 @@
 protected:
     void ReportRegisterState (const char *message);
 private:
+
+    bool
+    ConstructorSetup (Thread &thread,
+                      bool discard_on_error,
+                      ABI *& abi,
+                      lldb::addr_t &start_load_addr,
+                      lldb::addr_t &function_load_addr);
+
     void
     DoTakedown ();
     

Modified: lldb/branches/lldb-platform-work/source/Target/Memory.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/Memory.cpp?rev=154701&r1=154700&r2=154701&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/Memory.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/Memory.cpp Fri Apr 13 15:47:02 2012
@@ -51,20 +51,31 @@
 {
     if (size == 0)
         return;
-    
-    const uint32_t cache_line_byte_size = m_cache_line_byte_size;
-    const addr_t end_addr = (addr + size - 1);
-    const addr_t flush_start_addr = addr - (addr % cache_line_byte_size);
-    const addr_t flush_end_addr = end_addr - (end_addr % cache_line_byte_size);
-    
+
     Mutex::Locker locker (m_mutex);
     if (m_cache.empty())
         return;
-    
-    assert ((flush_start_addr % cache_line_byte_size) == 0);
-    
-    for (addr_t curr_addr = flush_start_addr; curr_addr <= flush_end_addr; curr_addr += cache_line_byte_size)
+
+    const uint32_t cache_line_byte_size = m_cache_line_byte_size;
+    const addr_t end_addr = (addr + size - 1);
+    const addr_t first_cache_line_addr = addr - (addr % cache_line_byte_size);
+    const addr_t last_cache_line_addr = end_addr - (end_addr % cache_line_byte_size);
+    // Watch for overflow where size will cause us to go off the end of the
+    // 64 bit address space
+    uint32_t num_cache_lines;
+    if (last_cache_line_addr >= first_cache_line_addr)
+        num_cache_lines = ((last_cache_line_addr - first_cache_line_addr)/cache_line_byte_size) + 1;
+    else
+        num_cache_lines = (UINT64_MAX - first_cache_line_addr + 1)/cache_line_byte_size;
+
+    //printf ("MemoryCache::Flush (0x%16.16llx, %zu (0x%zx))\n", addr, size, size);
+
+    uint32_t cache_idx = 0;
+    for (addr_t curr_addr = first_cache_line_addr;
+         cache_idx < num_cache_lines;
+         curr_addr += cache_line_byte_size, ++cache_idx)
     {
+        //printf ("flushing: 0x%16.16llx\n", curr_addr); /// REMOVE THIS PRIOR TO CHECKIN!!!!
         BlockMap::iterator pos = m_cache.find (curr_addr);
         if (pos != m_cache.end())
             m_cache.erase(pos);

Modified: lldb/branches/lldb-platform-work/source/Target/ThreadPlanCallFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/source/Target/ThreadPlanCallFunction.cpp?rev=154701&r1=154700&r2=154701&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/source/Target/ThreadPlanCallFunction.cpp (original)
+++ lldb/branches/lldb-platform-work/source/Target/ThreadPlanCallFunction.cpp Fri Apr 13 15:47:02 2012
@@ -34,23 +34,12 @@
 //----------------------------------------------------------------------
 // ThreadPlanCallFunction: Plan to call a single function
 //----------------------------------------------------------------------
-
-ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
-                                                Address &function,
-                                                const ClangASTType &return_type,
-                                                addr_t arg,
-                                                bool stop_other_threads,
-                                                bool discard_on_error,
-                                                addr_t *this_arg,
-                                                addr_t *cmd_arg) :
-    ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion),
-    m_valid (false),
-    m_stop_other_threads (stop_other_threads),
-    m_function_addr (function),
-    m_function_sp (NULL),
-    m_return_type (return_type),
-    m_takedown_done (false),
-    m_stop_address (LLDB_INVALID_ADDRESS)
+bool
+ThreadPlanCallFunction::ConstructorSetup (Thread &thread,
+                                          bool discard_on_error,
+                                          ABI *& abi,
+                                          lldb::addr_t &start_load_addr,
+                                          lldb::addr_t &function_load_addr)
 {
     // Call function thread plans need to be master plans so that they can potentially stay on the stack when
     // a breakpoint is hit during the function call.
@@ -59,12 +48,12 @@
 
     ProcessSP process_sp (thread.GetProcess());
     if (!process_sp)
-        return;
+        return false;
     
-    const ABI *abi = process_sp->GetABI().get();
+    abi = process_sp->GetABI().get();
     
     if (!abi)
-        return;
+        return false;
     
     TargetSP target_sp (thread.CalculateTarget());
 
@@ -73,6 +62,16 @@
     SetBreakpoints();
     
     m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
+    // If we can't read memory at the point of the process where we are planning to put our function, we're
+    // not going to get any further...
+    Error error;
+    process_sp->ReadUnsignedIntegerFromMemory(m_function_sp, 4, 0, error);
+    if (!error.Success())
+    {
+        if (log)
+            log->Printf ("Trying to put the stack in unreadable memory at: 0x%llx.", m_function_sp);
+        return false;
+    }
     
     Module *exe_module = target_sp->GetExecutableModulePointer();
 
@@ -80,7 +79,7 @@
     {
         if (log)
             log->Printf ("Can't execute code without an executable module.");
-        return;
+        return false;
     }
     else
     {
@@ -90,7 +89,7 @@
             if (log)
                 log->Printf ("Could not find object file for module \"%s\".", 
                              exe_module->GetFileSpec().GetFilename().AsCString());
-            return;
+            return false;
         }
         m_start_addr = objectFile->GetEntryPointAddress();
         if (!m_start_addr.IsValid())
@@ -98,11 +97,11 @@
             if (log)
                 log->Printf ("Could not find entry point address for executable module \"%s\".", 
                              exe_module->GetFileSpec().GetFilename().AsCString());
-            return;
+            return false;
         }
     }
     
-    addr_t start_load_addr = m_start_addr.GetLoadAddress (target_sp.get());
+    start_load_addr = m_start_addr.GetLoadAddress (target_sp.get());
     
     // Checkpoint the thread state so we can restore it later.
     if (log && log->GetVerbose())
@@ -112,18 +111,44 @@
     {
         if (log)
             log->Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state.");
-        return;
+        return false;
     }
     // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding...
     thread.SetStopInfoToNothing();
     
-    addr_t FunctionLoadAddr = m_function_addr.GetLoadAddress (target_sp.get());
+    function_load_addr = m_function_addr.GetLoadAddress (target_sp.get());
+    
+    return true;
+}
+
+ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
+                                                Address &function,
+                                                const ClangASTType &return_type,
+                                                addr_t arg,
+                                                bool stop_other_threads,
+                                                bool discard_on_error,
+                                                addr_t *this_arg,
+                                                addr_t *cmd_arg) :
+    ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion),
+    m_valid (false),
+    m_stop_other_threads (stop_other_threads),
+    m_function_addr (function),
+    m_function_sp (NULL),
+    m_return_type (return_type),
+    m_takedown_done (false),
+    m_stop_address (LLDB_INVALID_ADDRESS)
+{
+    lldb::addr_t start_load_addr;
+    ABI *abi;
+    lldb::addr_t function_load_addr;
+    if (!ConstructorSetup (thread, discard_on_error, abi, start_load_addr, function_load_addr))
+        return;
         
     if (this_arg && cmd_arg)
     {
         if (!abi->PrepareTrivialCall (thread, 
                                       m_function_sp, 
-                                      FunctionLoadAddr, 
+                                      function_load_addr, 
                                       start_load_addr, 
                                       this_arg,
                                       cmd_arg,
@@ -134,7 +159,7 @@
     {
         if (!abi->PrepareTrivialCall (thread, 
                                       m_function_sp, 
-                                      FunctionLoadAddr, 
+                                      function_load_addr, 
                                       start_load_addr, 
                                       this_arg,
                                       &arg))
@@ -144,7 +169,7 @@
     {
         if (!abi->PrepareTrivialCall (thread, 
                                       m_function_sp, 
-                                      FunctionLoadAddr, 
+                                      function_load_addr, 
                                       start_load_addr, 
                                       &arg))
             return;
@@ -173,78 +198,18 @@
     m_function_addr (function),
     m_function_sp(NULL),
     m_return_type (return_type),
-    m_takedown_done (false)
+    m_takedown_done (false),
+    m_stop_address (LLDB_INVALID_ADDRESS)
 {
-    // Call function thread plans need to be master plans so that they can potentially stay on the stack when
-    // a breakpoint is hit during the function call.
-    SetIsMasterPlan (true);
-    SetOkayToDiscard (discard_on_error);
-    
-    ProcessSP process_sp (thread.GetProcess());
-    if (!process_sp)
-        return;
-    
-    const ABI *abi = process_sp->GetABI().get();
-    
-    if (!abi)
-        return;
-
-    TargetSP target_sp (thread.CalculateTarget());
-
-    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-    
-    SetBreakpoints();
-    
-    m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
-    
-    Module *exe_module = target_sp->GetExecutableModulePointer();
-    
-    if (exe_module == NULL)
-    {
-        if (log)
-            log->Printf ("Can't execute code without an executable module.");
+    lldb::addr_t start_load_addr;
+    ABI *abi;
+    lldb::addr_t function_load_addr;
+    if (!ConstructorSetup (thread, discard_on_error, abi, start_load_addr, function_load_addr))
         return;
-    }
-    else
-    {
-        ObjectFile *objectFile = exe_module->GetObjectFile();
-        if (!objectFile)
-        {
-            if (log)
-                log->Printf ("Could not find object file for module \"%s\".", 
-                             exe_module->GetFileSpec().GetFilename().AsCString());
-            return;
-        }
-        m_start_addr = objectFile->GetEntryPointAddress();
-        if (!m_start_addr.IsValid())
-        {
-            if (log)
-                log->Printf ("Could not find entry point address for executable module \"%s\".", 
-                             exe_module->GetFileSpec().GetFilename().AsCString());
-            return;
-        }
-    }
-    
-    addr_t start_load_addr = m_start_addr.GetLoadAddress(target_sp.get());
-    
-    // Checkpoint the thread state so we can restore it later.
-    if (log && log->GetVerbose())
-        ReportRegisterState ("About to checkpoint thread before function call.  Original register state was:");
-    
-    if (!thread.CheckpointThreadState (m_stored_thread_state))
-    {
-        if (log)
-            log->Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state.");
-        return;
-    }
-    // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding...
-    thread.SetStopInfoToNothing();
-    
-    addr_t FunctionLoadAddr = m_function_addr.GetLoadAddress(target_sp.get());
     
     if (!abi->PrepareTrivialCall (thread, 
-                                  m_function_sp, 
-                                  FunctionLoadAddr, 
+                                  m_function_sp,
+                                  function_load_addr, 
                                   start_load_addr, 
                                   arg1_ptr,
                                   arg2_ptr,

Modified: lldb/branches/lldb-platform-work/test/types/AbstractBase.py
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/lldb-platform-work/test/types/AbstractBase.py?rev=154701&r1=154700&r2=154701&view=diff
==============================================================================
--- lldb/branches/lldb-platform-work/test/types/AbstractBase.py (original)
+++ lldb/branches/lldb-platform-work/test/types/AbstractBase.py Fri Apr 13 15:47:02 2012
@@ -29,6 +29,12 @@
         # used for all the test cases.
         self.exe_name = self.testMethodName
 
+    def tearDown(self):
+        """Cleanup the test byproducts."""
+        TestBase.tearDown(self)
+        #print "Removing golden-output.txt..."
+        os.remove("golden-output.txt")
+
     #==========================================================================#
     # Functions build_and_run() and build_and_run_expr() are generic functions #
     # which are called from the Test*Types*.py test cases.  The API client is  #
@@ -75,9 +81,14 @@
     def generic_type_tester(self, exe_name, atoms, quotedDisplay=False, blockCaptured=False):
         """Test that variables with basic types are displayed correctly."""
 
+        self.runCmd("file %s" % exe_name, CURRENT_EXECUTABLE_SET)
+
         # First, capture the golden output emitted by the oracle, i.e., the
         # series of printf statements.
-        go = system("./%s" % exe_name, sender=self)[0]
+        self.runCmd("process launch -o golden-output.txt")
+        with open("golden-output.txt") as f:
+            go = f.read()
+
         # This golden list contains a list of (variable, value) pairs extracted
         # from the golden output.
         gl = []
@@ -98,7 +109,6 @@
 
         # Bring the program to the point where we can issue a series of
         # 'frame variable -T' command.
-        self.runCmd("file %s" % exe_name, CURRENT_EXECUTABLE_SET)
         if blockCaptured:
             break_line = line_number ("basic_type.cpp", "// Break here to test block captured variables.")
         else:
@@ -148,9 +158,14 @@
     def generic_type_expr_tester(self, exe_name, atoms, quotedDisplay=False, blockCaptured=False):
         """Test that variable expressions with basic types are evaluated correctly."""
 
+        self.runCmd("file %s" % exe_name, CURRENT_EXECUTABLE_SET)
+
         # First, capture the golden output emitted by the oracle, i.e., the
         # series of printf statements.
-        go = system("./%s" % exe_name, sender=self)[0]
+        self.runCmd("process launch -o golden-output.txt")
+        with open("golden-output.txt") as f:
+            go = f.read()
+
         # This golden list contains a list of (variable, value) pairs extracted
         # from the golden output.
         gl = []
@@ -171,7 +186,6 @@
 
         # Bring the program to the point where we can issue a series of
         # 'expr' command.
-        self.runCmd("file %s" % exe_name, CURRENT_EXECUTABLE_SET)
         if blockCaptured:
             break_line = line_number ("basic_type.cpp", "// Break here to test block captured variables.")
         else:





More information about the lldb-commits mailing list