JDevlieghere updated this revision to Diff 413058.
JDevlieghere added a comment.

- Reduce flickering by not printing the last status message when the the 
progress is complete
- Add `...` as suggested by Adrian offline
- Make ANSI (vt100) escape codes a requirement in order to show progress to 
simplify the code


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D120972/new/

https://reviews.llvm.org/D120972

Files:
  lldb/include/lldb/API/SBCommandInterpreterRunOptions.h
  lldb/include/lldb/Core/Debugger.h
  lldb/include/lldb/Interpreter/CommandInterpreter.h
  lldb/source/API/SBCommandInterpreterRunOptions.cpp
  lldb/source/Core/CoreProperties.td
  lldb/source/Core/Debugger.cpp
  lldb/source/Interpreter/CommandInterpreter.cpp
  lldb/source/Symbol/LocateSymbolFile.cpp
  lldb/tools/driver/Driver.cpp

Index: lldb/tools/driver/Driver.cpp
===================================================================
--- lldb/tools/driver/Driver.cpp
+++ lldb/tools/driver/Driver.cpp
@@ -565,6 +565,7 @@
     m_debugger.SetAsync(false);
 
     SBCommandInterpreterRunOptions options;
+    options.SetShowProgress(true);
     options.SetAutoHandleEvents(true);
     options.SetSpawnThread(false);
     options.SetStopOnError(true);
Index: lldb/source/Symbol/LocateSymbolFile.cpp
===================================================================
--- lldb/source/Symbol/LocateSymbolFile.cpp
+++ lldb/source/Symbol/LocateSymbolFile.cpp
@@ -10,6 +10,7 @@
 
 #include "lldb/Core/ModuleList.h"
 #include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/Progress.h"
 #include "lldb/Host/FileSystem.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Utility/ArchSpec.h"
@@ -262,6 +263,10 @@
       FileSystem::Instance().Exists(symbol_file_spec))
     return symbol_file_spec;
 
+  Progress progress(llvm::formatv(
+      "Locating external symbol file for {0}",
+      module_spec.GetFileSpec().GetFilename().AsCString("<Unknown>")));
+
   FileSpecList debug_file_search_paths = default_search_paths;
 
   // Add module directory.
Index: lldb/source/Interpreter/CommandInterpreter.cpp
===================================================================
--- lldb/source/Interpreter/CommandInterpreter.cpp
+++ lldb/source/Interpreter/CommandInterpreter.cpp
@@ -3283,6 +3283,9 @@
 
 CommandInterpreterRunResult CommandInterpreter::RunCommandInterpreter(
     CommandInterpreterRunOptions &options) {
+  if (options.GetShowProgress())
+    m_debugger.StartProgressHandlerThread();
+
   // Always re-create the command interpreter when we run it in case any file
   // handles have changed.
   bool force_create = true;
Index: lldb/source/Core/Debugger.cpp
===================================================================
--- lldb/source/Core/Debugger.cpp
+++ lldb/source/Core/Debugger.cpp
@@ -378,6 +378,12 @@
   return ret;
 }
 
+bool Debugger::GetShowProgress() const {
+  const uint32_t idx = ePropertyShowProgress;
+  return m_collection_sp->GetPropertyAtIndexAsBoolean(
+      nullptr, idx, g_debugger_properties[idx].default_uint_value != 0);
+}
+
 bool Debugger::GetUseAutosuggestion() const {
   const uint32_t idx = ePropertyShowAutosuggestion;
   return m_collection_sp->GetPropertyAtIndexAsBoolean(
@@ -1719,6 +1725,75 @@
   return {};
 }
 
+lldb::thread_result_t Debugger::ProgressHandlerThread() {
+  // Only report progress if nobody else is listening for it.
+  if (GetBroadcaster().EventTypeHasListeners(Debugger::eBroadcastBitProgress))
+    return {};
+
+  ListenerSP listener_sp = Listener::MakeListener("lldb.progress.listener");
+  listener_sp->StartListeningForEvents(&m_broadcaster,
+                                       Debugger::eBroadcastBitProgress);
+
+  // Only handle one kind of event at the same time. Ignore events that come in
+  // in while the current event hasn't completed
+  llvm::Optional<uint64_t> CurrentEventID;
+  while (true) {
+    lldb::EventSP event_sp;
+    if (listener_sp->GetEvent(event_sp, llvm::None)) {
+      if (!event_sp)
+        continue;
+
+      auto *data =
+          Debugger::ProgressEventData::GetEventDataFromEvent(event_sp.get());
+      if (!data)
+        continue;
+
+      // Do some bookkeeping for the current event, regardless of whether we're
+      // going to show the progress.
+      uint64_t id = data->GetID();
+      if (CurrentEventID) {
+        if (id != *CurrentEventID)
+          continue;
+        if (data->GetCompleted())
+          CurrentEventID.reset();
+      } else {
+        CurrentEventID = id;
+      }
+
+      // Decide whether we actually are going to show the progress. This
+      // decision can change between iterations so check it inside the loop.
+      File &output = GetOutputFile();
+      if (!output.GetIsTerminalWithColors() || !GetShowProgress())
+        continue;
+
+      // If we're done, just clear the current line.
+      if (data->GetCompleted()) {
+        output.Printf("\33[2K\r");
+        continue;
+      }
+
+      // Print over previous line, if any.
+      output.Printf("\r");
+
+      // Print the progress message.
+      std::string message = data->GetMessage();
+      if (data->GetTotal() != UINT64_MAX) {
+        output.Printf("[%llu/%llu] %s...", data->GetCompleted(),
+                      data->GetTotal(), message.c_str());
+      } else {
+        output.Printf("%s...", message.c_str());
+      }
+
+      // Clear until the end of the line.
+      output.Printf("\x1B[K");
+
+      // Flush the output.
+      output.Flush();
+    }
+  }
+  return {};
+}
+
 bool Debugger::HasIOHandlerThread() { return m_io_handler_thread.IsJoinable(); }
 
 bool Debugger::StartIOHandlerThread() {
@@ -1751,6 +1826,29 @@
   }
 }
 
+bool Debugger::StartProgressHandlerThread() {
+  if (!m_progress_handler_thread.IsJoinable()) {
+    llvm::Expected<HostThread> progress_handler_thread =
+        ThreadLauncher::LaunchThread("lldb.debugger.progress-handler", [this] {
+          return ProgressHandlerThread();
+        });
+    if (progress_handler_thread) {
+      m_progress_handler_thread = *progress_handler_thread;
+    } else {
+      LLDB_LOG(GetLog(LLDBLog::Host), "failed to launch host thread: {}",
+               llvm::toString(progress_handler_thread.takeError()));
+    }
+  }
+
+  return m_io_handler_thread.IsJoinable();
+}
+
+void Debugger::StopProgressHandlerThread() {
+  if (m_progress_handler_thread.IsJoinable()) {
+    m_progress_handler_thread.Join(nullptr);
+  }
+}
+
 Target &Debugger::GetSelectedOrDummyTarget(bool prefer_dummy) {
   if (!prefer_dummy) {
     if (TargetSP target = m_target_list.GetSelectedTarget())
Index: lldb/source/Core/CoreProperties.td
===================================================================
--- lldb/source/Core/CoreProperties.td
+++ lldb/source/Core/CoreProperties.td
@@ -131,6 +131,10 @@
     Global,
     DefaultTrue,
     Desc<"Whether to use Ansi color codes or not.">;
+  def ShowProgress: Property<"show-progress", "Boolean">,
+    Global,
+    DefaultTrue,
+    Desc<"Whether to show progress or not.">;
   def UseSourceCache: Property<"use-source-cache", "Boolean">,
     Global,
     DefaultTrue,
Index: lldb/source/API/SBCommandInterpreterRunOptions.cpp
===================================================================
--- lldb/source/API/SBCommandInterpreterRunOptions.cpp
+++ lldb/source/API/SBCommandInterpreterRunOptions.cpp
@@ -139,6 +139,18 @@
   m_opaque_up->SetAddToHistory(add_to_history);
 }
 
+bool SBCommandInterpreterRunOptions::GetShowProgress() const {
+  LLDB_INSTRUMENT_VA(this);
+
+  return m_opaque_up->GetShowProgress();
+}
+
+void SBCommandInterpreterRunOptions::SetShowProgress(bool spawn_thread) {
+  LLDB_INSTRUMENT_VA(this, spawn_thread);
+
+  m_opaque_up->SetShowProgress(spawn_thread);
+}
+
 bool SBCommandInterpreterRunOptions::GetAutoHandleEvents() const {
   LLDB_INSTRUMENT_VA(this);
 
Index: lldb/include/lldb/Interpreter/CommandInterpreter.h
===================================================================
--- lldb/include/lldb/Interpreter/CommandInterpreter.h
+++ lldb/include/lldb/Interpreter/CommandInterpreter.h
@@ -166,10 +166,14 @@
     m_add_to_history = add_to_history ? eLazyBoolYes : eLazyBoolNo;
   }
 
-  bool GetAutoHandleEvents() const {
-    return DefaultToYes(m_auto_handle_events);
+  bool GetShowProgress() const { return DefaultToYes(m_show_progress); }
+
+  void SetShowProgress(bool show_progress) {
+    m_show_progress = show_progress ? eLazyBoolYes : eLazyBoolNo;
   }
 
+  bool GetAutoHandleEvents() const { return DefaultToNo(m_auto_handle_events); }
+
   void SetAutoHandleEvents(bool auto_handle_events) {
     m_auto_handle_events = auto_handle_events ? eLazyBoolYes : eLazyBoolNo;
   }
@@ -188,6 +192,7 @@
   LazyBool m_print_results = eLazyBoolCalculate;
   LazyBool m_print_errors = eLazyBoolCalculate;
   LazyBool m_add_to_history = eLazyBoolCalculate;
+  LazyBool m_show_progress;
   LazyBool m_auto_handle_events;
   LazyBool m_spawn_thread;
 
Index: lldb/include/lldb/Core/Debugger.h
===================================================================
--- lldb/include/lldb/Core/Debugger.h
+++ lldb/include/lldb/Core/Debugger.h
@@ -329,6 +329,8 @@
 
   bool SetUseColor(bool use_color);
 
+  bool GetShowProgress() const;
+
   bool GetUseAutosuggestion() const;
 
   bool GetUseSourceCache() const;
@@ -435,6 +437,8 @@
                              uint64_t completed, uint64_t total,
                              llvm::Optional<lldb::user_id_t> debugger_id);
 
+  void PrintProgress(const Debugger::ProgressEventData &data);
+
   bool StartEventHandlerThread();
 
   void StopEventHandlerThread();
@@ -452,10 +456,16 @@
 
   void JoinIOHandlerThread();
 
+  bool StartProgressHandlerThread();
+
+  void StopProgressHandlerThread();
+
   lldb::thread_result_t IOHandlerThread();
 
   lldb::thread_result_t DefaultEventHandler();
 
+  lldb::thread_result_t ProgressHandlerThread();
+
   void HandleBreakpointEvent(const lldb::EventSP &event_sp);
 
   void HandleProcessEvent(const lldb::EventSP &event_sp);
@@ -518,6 +528,7 @@
   LoadedPluginsList m_loaded_plugins;
   HostThread m_event_handler_thread;
   HostThread m_io_handler_thread;
+  HostThread m_progress_handler_thread;
   Broadcaster m_sync_broadcaster; ///< Private debugger synchronization.
   Broadcaster m_broadcaster;      ///< Public Debugger event broadcaster.
   lldb::ListenerSP m_forward_listener_sp;
Index: lldb/include/lldb/API/SBCommandInterpreterRunOptions.h
===================================================================
--- lldb/include/lldb/API/SBCommandInterpreterRunOptions.h
+++ lldb/include/lldb/API/SBCommandInterpreterRunOptions.h
@@ -64,6 +64,10 @@
 
   void SetAddToHistory(bool);
 
+  bool GetShowProgress() const;
+
+  void SetShowProgress(bool);
+
   bool GetAutoHandleEvents() const;
 
   void SetAutoHandleEvents(bool);
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to