[Lldb-commits] [lldb] r154230 - in /lldb/trunk: include/lldb/Host/ include/lldb/Target/ lldb.xcodeproj/xcshareddata/xcschemes/ source/Host/common/ source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/ source/Plugins/Process/gdb-remote/ source/Target/

Jim Ingham jingham at apple.com
Fri Apr 6 17:00:41 PDT 2012


Author: jingham
Date: Fri Apr  6 19:00:41 2012
New Revision: 154230

URL: http://llvm.org/viewvc/llvm-project?rev=154230&view=rev
Log:
We sometimes need to be able to call functions (via Process::RunThreadPlan) from code run on the private state thread.  To do that we have to 
spin up a temporary "private state thread" that will respond to events from the lower level process plugins.  This check-in should work to do
that, but it is still buggy.  However, if you don't call functions on the private state thread, these changes make no difference.

This patch also moves the code in the AppleObjCRuntime step-through-trampoline handler that might call functions (in the case where the debug
server doesn't support the memory allocate/deallocate packet) out to a safe place to do that call.

Modified:
    lldb/trunk/include/lldb/Host/Host.h
    lldb/trunk/include/lldb/Target/Process.h
    lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme
    lldb/trunk/source/Host/common/Host.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
    lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
    lldb/trunk/source/Target/Process.cpp

Modified: lldb/trunk/include/lldb/Host/Host.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/Host.h?rev=154230&r1=154229&r2=154230&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/Host.h (original)
+++ lldb/trunk/include/lldb/Host/Host.h Fri Apr  6 19:00:41 2012
@@ -205,6 +205,16 @@
     static lldb::tid_t
     GetCurrentThreadID ();
 
+    //------------------------------------------------------------------
+    /// Get the thread token (the one returned by ThreadCreate when the thread was created) for the
+    /// calling thread in the current process.
+    ///
+    /// @return
+    ///     The thread token for the calling thread in the current process.
+    //------------------------------------------------------------------
+    static lldb::thread_t
+    GetCurrentThread ();
+
     static const char *
     GetSignalAsCString (int signo);
 

Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=154230&r1=154229&r2=154230&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Fri Apr  6 19:00:41 2012
@@ -3143,7 +3143,27 @@
     //------------------------------------------------------------------
     bool
     RemoveInvalidMemoryRange (const LoadRange &region);
-                         
+    
+    //------------------------------------------------------------------
+    // If the setup code of a thread plan needs to do work that might involve 
+    // calling a function in the target, it should not do that work directly
+    // in one of the thread plan functions (DidPush/WillResume) because
+    // such work needs to be handled carefully.  Instead, put that work in
+    // a PreResumeAction callback, and register it with the process.  It will
+    // get done before the actual "DoResume" gets called.
+    //------------------------------------------------------------------
+    
+    typedef bool (PreResumeActionCallback)(void *);
+
+    void
+    AddPreResumeAction (PreResumeActionCallback callback, void *baton);
+    
+    bool
+    RunPreResumeActions ();
+    
+    void
+    ClearPreResumeActions ();
+                              
     ReadWriteLock &
     GetRunLock ()
     {
@@ -3227,7 +3247,7 @@
     bool
     PrivateStateThreadIsValid () const
     {
-        return m_private_state_thread != LLDB_INVALID_HOST_THREAD;
+        return IS_VALID_LLDB_HOST_THREAD(m_private_state_thread);
     }
 
     //------------------------------------------------------------------
@@ -3270,6 +3290,19 @@
     bool                        m_should_detach;   /// Should we detach if the process object goes away with an explicit call to Kill or Detach?
     LanguageRuntimeCollection 	m_language_runtimes;
     std::auto_ptr<NextEventAction> m_next_event_action_ap;
+    
+    struct PreResumeCallbackAndBaton
+    {
+        bool (*callback) (void *);
+        void *baton;
+        PreResumeCallbackAndBaton (PreResumeActionCallback in_callback, void *in_baton) :
+            callback (in_callback),
+            baton (in_baton)
+        {
+        }
+    };
+    
+    std::vector<PreResumeCallbackAndBaton> m_pre_resume_actions;
     ReadWriteLock               m_run_lock;
 
     enum {
@@ -3291,7 +3324,7 @@
     SetPrivateState (lldb::StateType state);
 
     bool
-    StartPrivateStateThread ();
+    StartPrivateStateThread (bool force = false);
 
     void
     StopPrivateStateThread ();

Modified: lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme?rev=154230&r1=154229&r2=154230&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme (original)
+++ lldb/trunk/lldb.xcodeproj/xcshareddata/xcschemes/lldb-tool.xcscheme Fri Apr  6 19:00:41 2012
@@ -91,10 +91,7 @@
       ignoresPersistentStateOnLaunch = "YES"
       debugDocumentVersioning = "YES"
       allowLocationSimulation = "YES">
-      <PathRunnable
-         FilePath = "/System/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python">
-      </PathRunnable>
-      <MacroExpansion>
+      <BuildableProductRunnable>
          <BuildableReference
             BuildableIdentifier = "primary"
             BlueprintIdentifier = "26F5C26910F3D9A4009D5894"
@@ -102,7 +99,7 @@
             BlueprintName = "lldb-tool"
             ReferencedContainer = "container:lldb.xcodeproj">
          </BuildableReference>
-      </MacroExpansion>
+      </BuildableProductRunnable>
       <EnvironmentVariables>
          <EnvironmentVariable
             key = "LLDB_LAUNCH_FLAG_DISABLE_ASLR"

Modified: lldb/trunk/source/Host/common/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Host.cpp?rev=154230&r1=154229&r2=154230&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/Host.cpp (original)
+++ lldb/trunk/source/Host/common/Host.cpp Fri Apr  6 19:00:41 2012
@@ -442,6 +442,12 @@
 #endif
 }
 
+lldb::thread_t
+Host::GetCurrentThread ()
+{
+    return lldb::thread_t(pthread_self());
+}
+
 const char *
 Host::GetSignalAsCString (int signo)
 {

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp?rev=154230&r1=154229&r2=154230&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp Fri Apr  6 19:00:41 2012
@@ -582,6 +582,113 @@
         m_vtables_ap->ReadRegions();        
 }
 
+lldb::addr_t
+AppleObjCTrampolineHandler::SetupDispatchFunction (Thread &thread, ValueList &dispatch_values)
+{
+    ExecutionContext exe_ctx (thread.shared_from_this());
+    Address impl_code_address;
+    StreamString errors;
+    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
+
+    // Scope for mutex locker:
+    {
+        Mutex::Locker locker(m_impl_function_mutex);
+        
+        // First stage is to make the ClangUtility to hold our injected function:
+
+    #define USE_BUILTIN_FUNCTION 0  // Define this to 1 and we will use the get_implementation function found in the target.
+                        // This is useful for debugging additions to the get_impl function 'cause you don't have
+                        // to bother with string-ifying the code into g_lookup_implementation_function_code.
+        
+        if (USE_BUILTIN_FUNCTION)
+        {
+            ConstString our_utility_function_name("__lldb_objc_find_implementation_for_selector");
+            SymbolContextList sc_list;
+            
+            exe_ctx.GetTargetRef().GetImages().FindSymbolsWithNameAndType (our_utility_function_name, eSymbolTypeCode, sc_list);
+            if (sc_list.GetSize() == 1)
+            {
+                SymbolContext sc;
+                sc_list.GetContextAtIndex(0, sc);
+                if (sc.symbol != NULL)
+                    impl_code_address = sc.symbol->GetAddress();
+                    
+                //lldb::addr_t addr = impl_code_address.GetOpcodeLoadAddress (exe_ctx.GetTargetPtr());
+                //printf ("Getting address for our_utility_function: 0x%llx.\n", addr);
+            }
+            else
+            {
+                //printf ("Could not find implementation function address.\n");
+                return args_addr;
+            }
+        }
+        else if (!m_impl_code.get())
+        {
+            m_impl_code.reset (new ClangUtilityFunction (g_lookup_implementation_function_code,
+                                                         g_lookup_implementation_function_name));
+            if (!m_impl_code->Install(errors, exe_ctx))
+            {
+                if (log)
+                    log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
+                m_impl_code.reset();
+                return args_addr;
+            }
+            impl_code_address.Clear();
+            impl_code_address.SetOffset(m_impl_code->StartAddress());
+        }
+        else
+        {
+            impl_code_address.Clear();
+            impl_code_address.SetOffset(m_impl_code->StartAddress());
+        }
+
+        // Next make the runner function for our implementation utility function.
+        if (!m_impl_function.get())
+        {
+             ClangASTContext *clang_ast_context = thread.GetProcess()->GetTarget().GetScratchClangASTContext();
+            lldb::clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
+             m_impl_function.reset(new ClangFunction (thread,
+                                                      clang_ast_context, 
+                                                      clang_void_ptr_type, 
+                                                      impl_code_address, 
+                                                      dispatch_values));
+            
+            errors.Clear();        
+            unsigned num_errors = m_impl_function->CompileFunction(errors);
+            if (num_errors)
+            {
+                if (log)
+                    log->Printf ("Error compiling function: \"%s\".", errors.GetData());
+                return args_addr;
+            }
+            
+            errors.Clear();
+            if (!m_impl_function->WriteFunctionWrapper(exe_ctx, errors))
+            {
+                if (log)
+                    log->Printf ("Error Inserting function: \"%s\".", errors.GetData());
+                return args_addr;
+            }
+        }
+    }
+    
+    errors.Clear();
+    
+    // Now write down the argument values for this particular call.  This looks like it might be a race condition
+    // if other threads were calling into here, but actually it isn't because we allocate a new args structure for
+    // this call by passing args_addr = LLDB_INVALID_ADDRESS...
+
+    if (!m_impl_function->WriteFunctionArguments (exe_ctx, args_addr, impl_code_address, dispatch_values, errors))
+    {
+        if (log)
+            log->Printf ("Error writing function arguments: \"%s\".", errors.GetData());
+        return args_addr;
+    }
+        
+    return args_addr;
+}
+
 ThreadPlanSP
 AppleObjCTrampolineHandler::GetStepThroughDispatchPlan (Thread &thread, bool stop_others)
 {
@@ -864,104 +971,13 @@
             else
                 flag_value.GetScalar() = 0;  // FIXME - Set to 0 when debugging is done.
             dispatch_values.PushValue (flag_value);
-
-            // Now, if we haven't already, make and insert the function as a ClangUtilityFunction, and make and insert 
-            // it's runner ClangFunction.
-            { 
-                // Scope for mutex locker:
-                Mutex::Locker locker(m_impl_function_mutex);
-                
-                // First stage is to make the ClangUtility to hold our injected function:
-
-#define USE_BUILTIN_FUNCTION 0  // Define this to 1 and we will use the get_implementation function found in the target.
-                                // This is useful for debugging additions to the get_impl function 'cause you don't have
-                                // to bother with string-ifying the code into g_lookup_implementation_function_code.
-                
-                if (USE_BUILTIN_FUNCTION)
-                {
-                    ConstString our_utility_function_name("__lldb_objc_find_implementation_for_selector");
-                    SymbolContextList sc_list;
-                    
-                    exe_ctx.GetTargetRef().GetImages().FindSymbolsWithNameAndType (our_utility_function_name, eSymbolTypeCode, sc_list);
-                    if (sc_list.GetSize() == 1)
-                    {
-                        SymbolContext sc;
-                        sc_list.GetContextAtIndex(0, sc);
-                        if (sc.symbol != NULL)
-                            impl_code_address = sc.symbol->GetAddress();
-                            
-                        //lldb::addr_t addr = impl_code_address.GetOpcodeLoadAddress (exe_ctx.GetTargetPtr());
-                        //printf ("Getting address for our_utility_function: 0x%llx.\n", addr);
-                    }
-                    else
-                    {
-                        //printf ("Could not find implementation function address.\n");
-                        return ret_plan_sp;
-                    }
-                }
-                else if (!m_impl_code.get())
-                {
-                    m_impl_code.reset (new ClangUtilityFunction (g_lookup_implementation_function_code,
-                                                                 g_lookup_implementation_function_name));
-                    if (!m_impl_code->Install(errors, exe_ctx))
-                    {
-                        if (log)
-                            log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
-                        m_impl_code.reset();
-                        return ret_plan_sp;
-                    }
-                    impl_code_address.Clear();
-                    impl_code_address.SetOffset(m_impl_code->StartAddress());
-                }
-                else
-                {
-                    impl_code_address.Clear();
-                    impl_code_address.SetOffset(m_impl_code->StartAddress());
-                }
-
-                // Next make the runner function for our implementation utility function.
-                if (!m_impl_function.get())
-                {
-                     m_impl_function.reset(new ClangFunction (thread,
-                                                              clang_ast_context, 
-                                                              clang_void_ptr_type, 
-                                                              impl_code_address, 
-                                                              dispatch_values));
-                    
-                    errors.Clear();        
-                    unsigned num_errors = m_impl_function->CompileFunction(errors);
-                    if (num_errors)
-                    {
-                        if (log)
-                            log->Printf ("Error compiling function: \"%s\".", errors.GetData());
-                        return ret_plan_sp;
-                    }
-                    
-                    errors.Clear();
-                    if (!m_impl_function->WriteFunctionWrapper(exe_ctx, errors))
-                    {
-                        if (log)
-                            log->Printf ("Error Inserting function: \"%s\".", errors.GetData());
-                        return ret_plan_sp;
-                    }
-                }
-                
-            } 
-            
-            errors.Clear();
             
-            // Now write down the argument values for this particular call.  This looks like it might be a race condition
-            // if other threads were calling into here, but actually it isn't because we allocate a new args structure for
-            // this call by passing args_addr = LLDB_INVALID_ADDRESS...
-
-            lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
-            if (!m_impl_function->WriteFunctionArguments (exe_ctx, args_addr, impl_code_address, dispatch_values, errors))
-                return ret_plan_sp;
-        
-            ret_plan_sp.reset (new AppleThreadPlanStepThroughObjCTrampoline (thread, this, args_addr,
-                                                                        dispatch_values.GetValueAtIndex(0)->GetScalar().ULongLong(),
-                                                                        isa_addr, sel_addr,
-                                                                        stop_others));
+            ret_plan_sp.reset (new AppleThreadPlanStepThroughObjCTrampoline (thread,
+                                                                             this,
+                                                                             dispatch_values,
+                                                                             isa_addr,
+                                                                             sel_addr,
+                                                                             stop_others));
             if (log)
             {
                 StreamString s;

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h?rev=154230&r1=154229&r2=154230&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h Fri Apr  6 19:00:41 2012
@@ -60,7 +60,10 @@
         bool is_super2;
         FixUpState fixedup;
     };
-    
+
+    lldb::addr_t
+    SetupDispatchFunction (Thread &thread, ValueList &dispatch_values);
+
 private:
     static const char *g_lookup_implementation_function_name;
     static const char *g_lookup_implementation_function_code;

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp?rev=154230&r1=154229&r2=154230&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp Fri Apr  6 19:00:41 2012
@@ -33,9 +33,8 @@
 AppleThreadPlanStepThroughObjCTrampoline::AppleThreadPlanStepThroughObjCTrampoline
 (
     Thread &thread, 
-    AppleObjCTrampolineHandler *trampoline_handler, 
-    lldb::addr_t args_addr, 
-    lldb::addr_t object_addr,
+    AppleObjCTrampolineHandler *trampoline_handler,
+    ValueList &input_values,
     lldb::addr_t isa_addr,
     lldb::addr_t sel_addr,
     bool stop_others
@@ -46,11 +45,11 @@
                 eVoteNoOpinion, 
                 eVoteNoOpinion),
     m_trampoline_handler (trampoline_handler),
-    m_args_addr (args_addr),
-    m_object_addr (object_addr),
+    m_args_addr (LLDB_INVALID_ADDRESS),
+    m_input_values (input_values),
     m_isa_addr(isa_addr),
     m_sel_addr(sel_addr),
-    m_impl_function (trampoline_handler->GetLookupImplementationWrapperFunction()),
+    m_impl_function (NULL),
     m_stop_others (stop_others)
 {
     
@@ -66,12 +65,42 @@
 void
 AppleThreadPlanStepThroughObjCTrampoline::DidPush ()
 {
-    StreamString errors;
-    ExecutionContext exc_ctx;
-    m_thread.CalculateExecutionContext(exc_ctx);
-    m_func_sp.reset(m_impl_function->GetThreadPlanToCallFunction (exc_ctx, m_args_addr, errors, m_stop_others));
-    m_func_sp->SetPrivate(true);
-    m_thread.QueueThreadPlan (m_func_sp, false);
+//    StreamString errors;
+//    ExecutionContext exc_ctx;
+//    m_thread.CalculateExecutionContext(exc_ctx);
+//    m_func_sp.reset(m_impl_function->GetThreadPlanToCallFunction (exc_ctx, m_args_addr, errors, m_stop_others));
+//    m_func_sp->SetPrivate(true);
+//    m_thread.QueueThreadPlan (m_func_sp, false);
+    m_thread.GetProcess()->AddPreResumeAction (PreResumeInitializeClangFunction, (void *) this);
+}
+
+bool
+AppleThreadPlanStepThroughObjCTrampoline::InitializeClangFunction ()
+{
+    if (!m_func_sp)
+    {
+        StreamString errors;
+        m_args_addr = m_trampoline_handler->SetupDispatchFunction(m_thread, m_input_values);
+        
+        if (m_args_addr == LLDB_INVALID_ADDRESS)
+        {
+            return false;
+        }
+        m_impl_function = m_trampoline_handler->GetLookupImplementationWrapperFunction();
+        ExecutionContext exc_ctx;
+        m_thread.CalculateExecutionContext(exc_ctx);
+        m_func_sp.reset(m_impl_function->GetThreadPlanToCallFunction (exc_ctx, m_args_addr, errors, m_stop_others));
+        m_func_sp->SetPrivate(true);
+        m_thread.QueueThreadPlan (m_func_sp, false);
+    }
+    return true;
+}
+
+bool
+AppleThreadPlanStepThroughObjCTrampoline::PreResumeInitializeClangFunction(void *void_myself)
+{
+    AppleThreadPlanStepThroughObjCTrampoline *myself = static_cast<AppleThreadPlanStepThroughObjCTrampoline *>(void_myself);
+    return myself->InitializeClangFunction();
 }
 
 void
@@ -83,7 +112,7 @@
     else
     {
         s->Printf ("Stepping to implementation of ObjC method - obj: 0x%llx, isa: 0x%llx, sel: 0x%llx",
-        m_object_addr, m_isa_addr, m_sel_addr);
+        m_input_values.GetValueAtIndex(0)->GetScalar().ULongLong(), m_isa_addr, m_sel_addr);
     }
 }
                 

Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h?rev=154230&r1=154229&r2=154230&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h Fri Apr  6 19:00:41 2012
@@ -16,6 +16,7 @@
 // Project includes
 #include "lldb/lldb-types.h"
 #include "lldb/lldb-enumerations.h"
+#include "lldb/Core/Value.h"
 #include "lldb/Target/ThreadPlan.h"
 #include "AppleObjCTrampolineHandler.h"
 
@@ -30,8 +31,7 @@
 	//------------------------------------------------------------------
 	AppleThreadPlanStepThroughObjCTrampoline(Thread &thread, 
                                              AppleObjCTrampolineHandler *trampoline_handler, 
-                                             lldb::addr_t args_addr, 
-                                             lldb::addr_t object_addr,
+                                             ValueList &values,
                                              lldb::addr_t isa_addr,
                                              lldb::addr_t sel_addr,
                                              bool stop_others);
@@ -63,6 +63,9 @@
     virtual void
     DidPush();
     
+    static bool
+    PreResumeInitializeClangFunction(void *myself);
+
     virtual bool
     WillStop();
 
@@ -74,12 +77,16 @@
 	//------------------------------------------------------------------
 	
 private:
+    bool
+    InitializeClangFunction ();
+
 	//------------------------------------------------------------------
 	// For AppleThreadPlanStepThroughObjCTrampoline only
 	//------------------------------------------------------------------
     AppleObjCTrampolineHandler *m_trampoline_handler; // FIXME - ensure this doesn't go away on us?  SP maybe?
     lldb::addr_t m_args_addr;     // Stores the address for our step through function result structure.
-    lldb::addr_t m_object_addr;  // This is only for Description.
+    //lldb::addr_t m_object_addr;  // This is only for Description.
+    ValueList    m_input_values;
     lldb::addr_t m_isa_addr;     // isa_addr and sel_addr are the keys we will use to cache the implementation.
     lldb::addr_t m_sel_addr;
     lldb::ThreadPlanSP m_func_sp;       // This is the function call plan.  We fill it at start, then set it

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h?rev=154230&r1=154229&r2=154230&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h Fri Apr  6 19:00:41 2012
@@ -312,8 +312,10 @@
     SetCurrentThreadForRun (int tid);
 
     lldb_private::LazyBool
-    SupportsAllocDeallocMemory () const
+    SupportsAllocDeallocMemory () // const
     {
+        // Uncomment this to have lldb pretend the debug server doesn't respond to alloc/dealloc memory packets.
+        // m_supports_alloc_dealloc_memory = lldb_private::eLazyBoolNo;
         return m_supports_alloc_dealloc_memory;
     }
 

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=154230&r1=154229&r2=154230&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Fri Apr  6 19:00:41 2012
@@ -2793,14 +2793,22 @@
         // to see if they are suppoed to start back up with a signal.
         if (m_thread_list.WillResume())
         {
-            m_mod_id.BumpResumeID();
-            error = DoResume();
-            if (error.Success())
+            // Last thing, do the PreResumeActions.
+            if (!RunPreResumeActions())
             {
-                DidResume();
-                m_thread_list.DidResume();
-                if (log)
-                    log->Printf ("Process thinks the process has resumed.");
+                error.SetErrorStringWithFormat ("Process::Resume PreResumeActions failed, not resuming.");
+            }
+            else
+            {
+                m_mod_id.BumpResumeID();
+                error = DoResume();
+                if (error.Success())
+                {
+                    DidResume();
+                    m_thread_list.DidResume();
+                    if (log)
+                        log->Printf ("Process thinks the process has resumed.");
+                }
             }
         }
         else
@@ -3074,7 +3082,7 @@
 
 
 bool
-Process::StartPrivateStateThread ()
+Process::StartPrivateStateThread (bool force)
 {
     LogSP log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
 
@@ -3082,13 +3090,16 @@
     if (log)
         log->Printf ("Process::%s()%s ", __FUNCTION__, already_running ? " already running" : " starting private state thread");
 
-    if (already_running)
+    if (!force && already_running)
         return true;
 
     // Create a thread that watches our internal state and controls which
     // events make it to clients (into the DCProcess event queue).
     char thread_name[1024];
-    snprintf(thread_name, sizeof(thread_name), "<lldb.process.internal-state(pid=%llu)>", GetID());
+    if (already_running)
+        snprintf(thread_name, sizeof(thread_name), "<lldb.process.internal-state-override(pid=%llu)>", GetID());
+    else
+        snprintf(thread_name, sizeof(thread_name), "<lldb.process.internal-state(pid=%llu)>", GetID());
     m_private_state_thread = Host::ThreadCreate (thread_name, Process::PrivateStateThread, this, NULL);
     return IS_VALID_LLDB_HOST_THREAD(m_private_state_thread);
 }
@@ -3834,7 +3845,7 @@
 
 ExecutionResults
 Process::RunThreadPlan (ExecutionContext &exe_ctx,
-                        lldb::ThreadPlanSP &thread_plan_sp,        
+                        lldb::ThreadPlanSP &thread_plan_sp,
                         bool stop_others,
                         bool try_all_threads,
                         bool discard_on_error,
@@ -3896,7 +3907,20 @@
         selected_tid = LLDB_INVALID_THREAD_ID;
     }
 
-    thread->QueueThreadPlan(thread_plan_sp, true);
+    lldb::thread_t backup_private_state_thread = LLDB_INVALID_HOST_THREAD;
+    
+    if (Host::GetCurrentThread() == m_private_state_thread)
+    {
+        // Yikes, we are running on the private state thread!  So we can't call DoRunThreadPlan on this thread, since
+        // then nobody will be around to fetch internal events.
+        // The simplest thing to do is to spin up a temporary thread to handle private state thread events while
+        // we are doing the RunThreadPlan here.
+        backup_private_state_thread = m_private_state_thread;
+        printf ("Running thread plan on private state thread, spinning up another state thread to handle the events.\n");
+        StartPrivateStateThread(true);
+    }
+    
+    thread->QueueThreadPlan(thread_plan_sp, false); // This used to pass "true" does that make sense?
     
     Listener listener("lldb.process.listener.run-thread-plan");
     
@@ -4253,6 +4277,17 @@
         
     }  // END WAIT LOOP
     
+    // If we had to start up a temporary private state thread to run this thread plan, shut it down now.
+    if (IS_VALID_LLDB_HOST_THREAD(backup_private_state_thread))
+    {
+        StopPrivateStateThread();
+        lldb::thread_result_t thread_result;
+        Error error;
+        // Host::ThreadJoin(m_private_state_thread, &thread_result, &error);
+        m_private_state_thread = backup_private_state_thread;
+    }
+    
+    
     // Now do some processing on the results of the run:
     if (return_value == eExecutionInterrupted)
     {
@@ -4506,6 +4541,31 @@
     return m_memory_cache.RemoveInvalidRange(region.GetRangeBase(), region.GetByteSize());
 }
 
+void
+Process::AddPreResumeAction (PreResumeActionCallback callback, void *baton)
+{
+    m_pre_resume_actions.push_back(PreResumeCallbackAndBaton (callback, baton));
+}
+
+bool
+Process::RunPreResumeActions ()
+{
+    bool result = true;
+    while (!m_pre_resume_actions.empty())
+    {
+        struct PreResumeCallbackAndBaton action = m_pre_resume_actions.back();
+        m_pre_resume_actions.pop_back();
+        bool this_result = action.callback (action.baton);
+        if (result == true) result = this_result;
+    }
+    return result;
+}
+
+void
+Process::ClearPreResumeActions ()
+{
+    m_pre_resume_actions.clear();
+}
 
 //--------------------------------------------------------------
 // class Process::SettingsController





More information about the lldb-commits mailing list