teemperor updated this revision to Diff 162227.
teemperor added a comment.
Herald added a subscriber: emaste.

I added an flag for this to the evaluation options. I also set this flag for 
all utility calls I found.


https://reviews.llvm.org/D50912

Files:
  include/lldb/Core/Debugger.h
  include/lldb/Target/Process.h
  include/lldb/Target/Target.h
  source/Core/Debugger.cpp
  source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
  source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
  source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
  source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
  source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
  source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
  source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
  source/Target/Process.cpp

Index: source/Target/Process.cpp
===================================================================
--- source/Target/Process.cpp
+++ source/Target/Process.cpp
@@ -1729,6 +1729,10 @@
   m_mod_id.SetRunningUserExpression(on);
 }
 
+void Process::SetRunningUtilityFunction(bool on) {
+  m_mod_id.SetRunningUtilityFunction(on);
+}
+
 addr_t Process::GetImageInfoAddress() { return LLDB_INVALID_ADDRESS; }
 
 const lldb::ABISP &Process::GetABI() {
@@ -4685,7 +4689,12 @@
       log->Printf("Process::%s pushing IO handler", __FUNCTION__);
 
     io_handler_sp->SetIsDone(false);
-    GetTarget().GetDebugger().PushIOHandler(io_handler_sp);
+    // If we evaluate an utility function, then we don't cancel the current
+    // IOHandler. Our IOHandler is non-interactive and shouldn't disturb the
+    // existing IOHandler that potentially provides the user interface (e.g.
+    // the IOHandler for Editline).
+    bool cancel_top_handler = m_mod_id.IsRunningUtilityFunction();
+    GetTarget().GetDebugger().PushIOHandler(io_handler_sp, cancel_top_handler);
     return true;
   }
   return false;
@@ -4875,6 +4884,11 @@
   thread_plan_sp->SetIsMasterPlan(true);
   thread_plan_sp->SetOkayToDiscard(false);
 
+  // If we are running some utility expression for LLDB, we now have to mark
+  // this in the ProcesModID of this process. This RAII takes care of marking
+  // and reverting the mark it once we are done running the expression.
+  UtilityFunctionScope util_scope(options.IsForUtilityExpr() ? this : nullptr);
+
   if (m_private_state.GetValue() != eStateStopped) {
     diagnostic_manager.PutString(
         eDiagnosticSeverityError,
Index: source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
===================================================================
--- source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
+++ source/Plugins/SystemRuntime/MacOSX/AppleGetThreadItemInfoHandler.cpp
@@ -351,6 +351,7 @@
   options.SetStopOthers(true);
   options.SetTimeout(std::chrono::milliseconds(500));
   options.SetTryAllThreads(false);
+  options.SetIsForUtilityExpr(true);
   thread.CalculateExecutionContext(exe_ctx);
 
   if (!m_get_thread_item_info_impl_code) {
Index: source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
===================================================================
--- source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
+++ source/Plugins/SystemRuntime/MacOSX/AppleGetQueuesHandler.cpp
@@ -354,6 +354,7 @@
   options.SetStopOthers(true);
   options.SetTimeout(std::chrono::milliseconds(500));
   options.SetTryAllThreads(false);
+  options.SetIsForUtilityExpr(true);
   thread.CalculateExecutionContext(exe_ctx);
 
   ExpressionResults func_call_ret;
Index: source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
===================================================================
--- source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
+++ source/Plugins/SystemRuntime/MacOSX/AppleGetPendingItemsHandler.cpp
@@ -349,6 +349,7 @@
   options.SetStopOthers(true);
   options.SetTimeout(std::chrono::milliseconds(500));
   options.SetTryAllThreads(false);
+  options.SetIsForUtilityExpr(true);
   thread.CalculateExecutionContext(exe_ctx);
 
   if (get_pending_items_caller == NULL) {
Index: source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
===================================================================
--- source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
+++ source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
@@ -340,6 +340,7 @@
   options.SetStopOthers(true);
   options.SetTimeout(std::chrono::milliseconds(500));
   options.SetTryAllThreads(false);
+  options.SetIsForUtilityExpr(true);
   thread.CalculateExecutionContext(exe_ctx);
 
   if (!m_get_item_info_impl_code) {
Index: source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
===================================================================
--- source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
@@ -1244,7 +1244,8 @@
   options.SetTrapExceptions(false); // dlopen can't throw exceptions, so
                                     // don't do the work to trap them.
   options.SetTimeout(std::chrono::seconds(2));
-  
+  options.SetIsForUtilityExpr(true);
+
   Value return_value;
   // Fetch the clang types we will need:
   ClangASTContext *ast = process->GetTarget().GetScratchClangASTContext();
Index: source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
===================================================================
--- source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -1409,6 +1409,7 @@
     options.SetStopOthers(true);
     options.SetIgnoreBreakpoints(true);
     options.SetTimeout(g_utility_function_timeout);
+    options.SetIsForUtilityExpr(true);
 
     Value return_value;
     return_value.SetValueType(Value::eValueTypeScalar);
@@ -1659,6 +1660,7 @@
     options.SetStopOthers(true);
     options.SetIgnoreBreakpoints(true);
     options.SetTimeout(g_utility_function_timeout);
+    options.SetIsForUtilityExpr(true);
 
     Value return_value;
     return_value.SetValueType(Value::eValueTypeScalar);
Index: source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
===================================================================
--- source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
+++ source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
@@ -167,6 +167,7 @@
   options.SetStopOthers(true);
   options.SetIgnoreBreakpoints(true);
   options.SetTimeout(g_po_function_timeout);
+  options.SetIsForUtilityExpr(true);
 
   ExpressionResults results = m_print_object_caller_up->ExecuteFunction(
       exe_ctx, &wrapper_struct_addr, options, diagnostics, ret);
Index: source/Core/Debugger.cpp
===================================================================
--- source/Core/Debugger.cpp
+++ source/Core/Debugger.cpp
@@ -1077,7 +1077,8 @@
   }
 }
 
-void Debugger::PushIOHandler(const IOHandlerSP &reader_sp) {
+void Debugger::PushIOHandler(const IOHandlerSP &reader_sp,
+                             bool cancel_top_handler) {
   if (!reader_sp)
     return;
 
@@ -1098,7 +1099,8 @@
   // this new input reader take over
   if (top_reader_sp) {
     top_reader_sp->Deactivate();
-    top_reader_sp->Cancel();
+    if (cancel_top_handler)
+      top_reader_sp->Cancel();
   }
 }
 
Index: include/lldb/Target/Target.h
===================================================================
--- include/lldb/Target/Target.h
+++ include/lldb/Target/Target.h
@@ -375,6 +375,10 @@
 
   bool GetAutoApplyFixIts() const { return m_auto_apply_fixits; }
 
+  bool IsForUtilityExpr() const { return m_running_utility_expression; }
+
+  void SetIsForUtilityExpr(bool b) { m_running_utility_expression = b; }
+
 private:
   ExecutionPolicy m_execution_policy = default_execution_policy;
   lldb::LanguageType m_language = lldb::eLanguageTypeUnknown;
@@ -392,6 +396,10 @@
   bool m_ansi_color_errors = false;
   bool m_result_is_internal = false;
   bool m_auto_apply_fixits = true;
+  /// True if the executed code should be treated as utility code that is only
+  /// used by LLDB internally.
+  bool m_running_utility_expression = false;
+
   lldb::DynamicValueType m_use_dynamic = lldb::eNoDynamicValues;
   Timeout<std::micro> m_timeout = default_timeout;
   Timeout<std::micro> m_one_thread_timeout = llvm::None;
Index: include/lldb/Target/Process.h
===================================================================
--- include/lldb/Target/Process.h
+++ include/lldb/Target/Process.h
@@ -402,7 +402,8 @@
 public:
   ProcessModID()
       : m_stop_id(0), m_last_natural_stop_id(0), m_resume_id(0), m_memory_id(0),
-        m_last_user_expression_resume(0), m_running_user_expression(false) {}
+        m_last_user_expression_resume(0), m_running_user_expression(false),
+        m_running_utility_function(0) {}
 
   ProcessModID(const ProcessModID &rhs)
       : m_stop_id(rhs.m_stop_id), m_memory_id(rhs.m_memory_id) {}
@@ -431,6 +432,10 @@
       m_last_user_expression_resume = m_resume_id;
   }
 
+  bool IsRunningUtilityFunction() const {
+    return m_running_utility_function > 0;
+  }
+
   uint32_t GetStopID() const { return m_stop_id; }
   uint32_t GetLastNaturalStopID() const { return m_last_natural_stop_id; }
   uint32_t GetMemoryID() const { return m_memory_id; }
@@ -467,6 +472,13 @@
       m_running_user_expression--;
   }
 
+  void SetRunningUtilityFunction(bool on) {
+    if (on)
+      m_running_utility_function++;
+    else
+      m_running_utility_function--;
+  }
+
   void SetStopEventForLastNaturalStopID(lldb::EventSP event_sp) {
     m_last_natural_stop_event = event_sp;
   }
@@ -484,6 +496,7 @@
   uint32_t m_memory_id;
   uint32_t m_last_user_expression_resume;
   uint32_t m_running_user_expression;
+  uint32_t m_running_utility_function;
   lldb::EventSP m_last_natural_stop_event;
 };
 
@@ -2554,6 +2567,7 @@
   virtual bool StopNoticingNewThreads() { return true; }
 
   void SetRunningUserExpression(bool on);
+  void SetRunningUtilityFunction(bool on);
 
   //------------------------------------------------------------------
   // lldb::ExecutionContextScope pure virtual functions
@@ -3225,6 +3239,24 @@
   DISALLOW_COPY_AND_ASSIGN(Process);
 };
 
+//------------------------------------------------------------------
+/// RAII guard that should be aquired when an utility function is called within
+/// a given process.
+//------------------------------------------------------------------
+class UtilityFunctionScope {
+  Process *m_process;
+
+public:
+  UtilityFunctionScope(Process *p) : m_process(p) {
+    if (m_process)
+      m_process->SetRunningUtilityFunction(true);
+  }
+  ~UtilityFunctionScope() {
+    if (m_process)
+      m_process->SetRunningUtilityFunction(false);
+  }
+};
+
 } // namespace lldb_private
 
 #endif // liblldb_Process_h_
Index: include/lldb/Core/Debugger.h
===================================================================
--- include/lldb/Core/Debugger.h
+++ include/lldb/Core/Debugger.h
@@ -192,7 +192,8 @@
                                        lldb::StreamFileSP &out,
                                        lldb::StreamFileSP &err);
 
-  void PushIOHandler(const lldb::IOHandlerSP &reader_sp);
+  void PushIOHandler(const lldb::IOHandlerSP &reader_sp,
+                     bool cancel_top_handler = true);
 
   bool PopIOHandler(const lldb::IOHandlerSP &reader_sp);
 
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to