Improve the way the ObjC data formatters fetch a valid frame to use for running expre...
authorEnrico Granata <egranata@apple.com>
Wed, 30 Jul 2014 21:07:50 +0000 (21:07 +0000)
committerEnrico Granata <egranata@apple.com>
Wed, 30 Jul 2014 21:07:50 +0000 (21:07 +0000)
This is not bullet-proof, as you might end up running in a thread where you shouldn't, but the previous policy had the same drawback
Also, in cases where code-running formatters were being recursively applied, the previous policy caused deeper levels to fail, whereas this will at least get such scenarios to function
We might eventually want to consider disqualifying certain threads/frames for "viability", but I'd rather keep it simple until complexity is proven to be necessary

llvm-svn: 214337

lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h
lldb/source/DataFormatters/CXXFormatterFunctions.cpp
lldb/source/DataFormatters/NSDictionary.cpp

index e1f7eb1..753ffa1 100644 (file)
@@ -27,6 +27,9 @@
 namespace lldb_private {
     namespace formatters
     {
+        StackFrame*
+        GetViableFrame (ExecutionContext exe_ctx);
+        
         bool
         ExtractValueFromObjCExpression (ValueObject &valobj,
                                         const char* target_type,
index ac535ef..ae5b35f 100644 (file)
@@ -21,6 +21,7 @@
 #include "lldb/Host/Endian.h"
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
 
 #include <algorithm>
 
@@ -28,6 +29,23 @@ using namespace lldb;
 using namespace lldb_private;
 using namespace lldb_private::formatters;
 
+StackFrame*
+lldb_private::formatters::GetViableFrame (ExecutionContext exe_ctx)
+{
+    StackFrame* frame = exe_ctx.GetFramePtr();
+    if (frame)
+        return frame;
+    
+    Process* process = exe_ctx.GetProcessPtr();
+    if (!process)
+        return nullptr;
+    
+    ThreadSP thread_sp(process->GetThreadList().GetSelectedThread());
+    if (thread_sp)
+        return thread_sp->GetSelectedFrame().get();
+    return nullptr;
+}
+
 bool
 lldb_private::formatters::ExtractValueFromObjCExpression (ValueObject &valobj,
                                                           const char* target_type,
@@ -43,7 +61,7 @@ lldb_private::formatters::ExtractValueFromObjCExpression (ValueObject &valobj,
     ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
     lldb::ValueObjectSP result_sp;
     Target* target = exe_ctx.GetTargetPtr();
-    StackFrame* stack_frame = exe_ctx.GetFramePtr();
+    StackFrame* stack_frame = GetViableFrame(exe_ctx);
     if (!target || !stack_frame)
         return false;
     
@@ -77,7 +95,7 @@ lldb_private::formatters::ExtractSummaryFromObjCExpression (ValueObject &valobj,
     ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
     lldb::ValueObjectSP result_sp;
     Target* target = exe_ctx.GetTargetPtr();
-    StackFrame* stack_frame = exe_ctx.GetFramePtr();
+    StackFrame* stack_frame = GetViableFrame(exe_ctx);
     if (!target || !stack_frame)
         return false;
     
@@ -115,7 +133,7 @@ lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj,
     ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
     lldb::ValueObjectSP result_sp;
     Target* target = exe_ctx.GetTargetPtr();
-    StackFrame* stack_frame = exe_ctx.GetFramePtr();
+    StackFrame* stack_frame = GetViableFrame(exe_ctx);
     if (!target || !stack_frame)
         return valobj_sp;
     
@@ -152,7 +170,7 @@ lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj,
     ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
     lldb::ValueObjectSP result_sp;
     Target* target = exe_ctx.GetTargetPtr();
-    StackFrame* stack_frame = exe_ctx.GetFramePtr();
+    StackFrame* stack_frame = GetViableFrame(exe_ctx);
     if (!target || !stack_frame)
         return valobj_sp;
     
index 5ee37f2..ddd1e2e 100644 (file)
@@ -220,7 +220,9 @@ lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::GetChildAtIn
     lldb::ValueObjectSP child_sp;
     EvaluateExpressionOptions options;
     options.SetKeepInMemory(true);
-    m_backend.GetTargetSP()->EvaluateExpression(object_fetcher_expr.GetData(), m_backend.GetFrameSP().get(), child_sp,
+    m_backend.GetTargetSP()->EvaluateExpression(object_fetcher_expr.GetData(),
+                                                GetViableFrame(m_backend.GetTargetSP().get()),
+                                                child_sp,
                                                 options);
     if (child_sp)
         child_sp->SetName(ConstString(idx_name.GetData()));