This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rL330043: [Command] Implement `statistics` command. (authored 
by davide, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D45547?vs=142301&id=142439#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D45547

Files:
  lldb/trunk/include/lldb/Target/Target.h
  lldb/trunk/include/lldb/lldb-private-enumerations.h
  lldb/trunk/packages/Python/lldbsuite/test/functionalities/stats/Makefile
  lldb/trunk/packages/Python/lldbsuite/test/functionalities/stats/TestStats.py
  lldb/trunk/packages/Python/lldbsuite/test/functionalities/stats/main.c
  lldb/trunk/source/Commands/CommandObjectExpression.cpp
  lldb/trunk/source/Commands/CommandObjectFrame.cpp
  lldb/trunk/source/Commands/CommandObjectStats.cpp
  lldb/trunk/source/Commands/CommandObjectStats.h
  lldb/trunk/source/Interpreter/CommandInterpreter.cpp
  lldb/trunk/source/Target/Target.cpp

Index: lldb/trunk/packages/Python/lldbsuite/test/functionalities/stats/Makefile
===================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/stats/Makefile
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/stats/Makefile
@@ -0,0 +1,3 @@
+LEVEL = ../../make
+C_SOURCES := main.c
+include $(LEVEL)/Makefile.rules
Index: lldb/trunk/packages/Python/lldbsuite/test/functionalities/stats/main.c
===================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/stats/main.c
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/stats/main.c
@@ -0,0 +1,18 @@
+// Test that the lldb command `statistics` works.
+
+int main(void) {
+  int patatino = 27;
+  //%self.expect("statistics disable", substrs=['need to enable statistics before disabling'], error=True)
+  //%self.expect("statistics enable")
+  //%self.expect("statistics enable", substrs=['already enabled'], error=True)
+  //%self.expect("expr patatino", substrs=['27'])
+  //%self.expect("statistics disable")
+  //%self.expect("statistics dump", substrs=['expr evaluation successes : 1', 'expr evaluation failures : 0'])
+  //%self.expect("frame var", substrs=['27'])
+  //%self.expect("statistics enable")
+  //%self.expect("frame var", substrs=['27'])
+  //%self.expect("statistics disable")
+  //%self.expect("statistics dump", substrs=['frame var successes : 1', 'frame var failures : 0'])
+
+  return 0;
+}
Index: lldb/trunk/packages/Python/lldbsuite/test/functionalities/stats/TestStats.py
===================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/stats/TestStats.py
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/stats/TestStats.py
@@ -0,0 +1,5 @@
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
+
+lldbinline.MakeInlineTest(
+    __file__, globals(), [])
Index: lldb/trunk/source/Target/Target.cpp
===================================================================
--- lldb/trunk/source/Target/Target.cpp
+++ lldb/trunk/source/Target/Target.cpp
@@ -87,13 +87,14 @@
       Broadcaster(debugger.GetBroadcasterManager(),
                   Target::GetStaticBroadcasterClass().AsCString()),
       ExecutionContextScope(), m_debugger(debugger), m_platform_sp(platform_sp),
-      m_mutex(), m_arch(target_arch),
-      m_images(this), m_section_load_history(), m_breakpoint_list(false),
-      m_internal_breakpoint_list(true), m_watchpoint_list(), m_process_sp(),
-      m_search_filter_sp(), m_image_search_paths(ImageSearchPathsChanged, this),
-      m_ast_importer_sp(), m_source_manager_ap(), m_stop_hooks(),
-      m_stop_hook_next_id(0), m_valid(true), m_suppress_stop_hooks(false),
-      m_is_dummy_target(is_dummy_target)
+      m_mutex(), m_arch(target_arch), m_images(this), m_section_load_history(),
+      m_breakpoint_list(false), m_internal_breakpoint_list(true),
+      m_watchpoint_list(), m_process_sp(), m_search_filter_sp(),
+      m_image_search_paths(ImageSearchPathsChanged, this), m_ast_importer_sp(),
+      m_source_manager_ap(), m_stop_hooks(), m_stop_hook_next_id(0),
+      m_valid(true), m_suppress_stop_hooks(false),
+      m_is_dummy_target(is_dummy_target),
+      m_stats_storage(static_cast<int>(StatisticKind::StatisticMax))
 
 {
   SetEventName(eBroadcastBitBreakpointChanged, "breakpoint-changed");
Index: lldb/trunk/source/Interpreter/CommandInterpreter.cpp
===================================================================
--- lldb/trunk/source/Interpreter/CommandInterpreter.cpp
+++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp
@@ -425,7 +425,7 @@
       CommandObjectSP(new CommandObjectMultiwordSettings(*this));
   m_command_dict["source"] =
       CommandObjectSP(new CommandObjectMultiwordSource(*this));
-  m_command_dict["stats"] = CommandObjectSP(new CommandObjectStats(*this));
+  m_command_dict["statistics"] = CommandObjectSP(new CommandObjectStats(*this));
   m_command_dict["target"] =
       CommandObjectSP(new CommandObjectMultiwordTarget(*this));
   m_command_dict["thread"] =
Index: lldb/trunk/source/Commands/CommandObjectStats.h
===================================================================
--- lldb/trunk/source/Commands/CommandObjectStats.h
+++ lldb/trunk/source/Commands/CommandObjectStats.h
@@ -11,16 +11,14 @@
 #define liblldb_CommandObjectStats_h_
 
 #include "lldb/Interpreter/CommandObject.h"
+#include "lldb/Interpreter/CommandObjectMultiword.h"
 
 namespace lldb_private {
-class CommandObjectStats : public CommandObjectParsed {
+class CommandObjectStats : public CommandObjectMultiword {
 public:
   CommandObjectStats(CommandInterpreter &interpreter);
 
   ~CommandObjectStats() override;
-
-protected:
-  bool DoExecute(Args &command, CommandReturnObject &result) override;
 };
 } // namespace lldb_private
 
Index: lldb/trunk/source/Commands/CommandObjectExpression.cpp
===================================================================
--- lldb/trunk/source/Commands/CommandObjectExpression.cpp
+++ lldb/trunk/source/Commands/CommandObjectExpression.cpp
@@ -623,11 +623,12 @@
   if (expr == nullptr)
     expr = command;
 
+  Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
+  if (!target)
+    target = GetDummyTarget();
+
   if (EvaluateExpression(expr, &(result.GetOutputStream()),
                          &(result.GetErrorStream()), &result)) {
-    Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
-    if (!target)
-        target = GetDummyTarget();
 
     if (!m_fixed_expression.empty() && target->GetEnableNotifyAboutFixIts()) {
       CommandHistory &history = m_interpreter.GetCommandHistory();
@@ -644,9 +645,15 @@
       }
       history.AppendString(fixed_command);
     }
+    // Increment statistics to record this expression evaluation
+    // success.
+    target->IncrementStats(StatisticKind::ExpressionSuccessful);
     return true;
   }
 
+  // Increment statistics to record this expression evaluation
+  // failure.
+  target->IncrementStats(StatisticKind::ExpressionFailure);
   result.SetStatus(eReturnStatusFailed);
   return false;
 }
Index: lldb/trunk/source/Commands/CommandObjectStats.cpp
===================================================================
--- lldb/trunk/source/Commands/CommandObjectStats.cpp
+++ lldb/trunk/source/Commands/CommandObjectStats.cpp
@@ -11,18 +11,114 @@
 #include "lldb/Host/Host.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Target/Target.h"
 
 using namespace lldb;
 using namespace lldb_private;
 
-CommandObjectStats::CommandObjectStats(CommandInterpreter &interpreter)
-    : CommandObjectParsed(
-          interpreter, "stats", "Print statistics about a debugging session",
-          nullptr) {
-}
+class CommandObjectStatsEnable : public CommandObjectParsed {
+public:
+  CommandObjectStatsEnable(CommandInterpreter &interpreter)
+      : CommandObjectParsed(interpreter, "enable",
+                            "Enable statistics collection", nullptr,
+                            eCommandProcessMustBePaused) {}
+
+  ~CommandObjectStatsEnable() override = default;
+
+protected:
+  bool DoExecute(Args &command, CommandReturnObject &result) override {
+    Target *target = GetSelectedOrDummyTarget();
+
+    if (target->GetCollectingStats()) {
+      result.AppendError("statistics already enabled");
+      result.SetStatus(eReturnStatusFailed);
+      return false;
+    }
+
+    target->SetCollectingStats(true);
+    result.SetStatus(eReturnStatusSuccessFinishResult);
+    return true;
+  }
+};
+
+class CommandObjectStatsDisable : public CommandObjectParsed {
+public:
+  CommandObjectStatsDisable(CommandInterpreter &interpreter)
+      : CommandObjectParsed(interpreter, "disable",
+                            "Disable statistics collection", nullptr,
+                            eCommandProcessMustBePaused) {}
+
+  ~CommandObjectStatsDisable() override = default;
+
+protected:
+  bool DoExecute(Args &command, CommandReturnObject &result) override {
+    Target *target = GetSelectedOrDummyTarget();
 
-bool CommandObjectStats::DoExecute(Args &command, CommandReturnObject &result) {
-  return true;
+    if (!target->GetCollectingStats()) {
+      result.AppendError("need to enable statistics before disabling them");
+      result.SetStatus(eReturnStatusFailed);
+      return false;
+    }
+
+    target->SetCollectingStats(false);
+    result.SetStatus(eReturnStatusSuccessFinishResult);
+    return true;
+  }
+};
+
+class CommandObjectStatsDump : public CommandObjectParsed {
+private:
+  std::string GetStatDescription(lldb_private::StatisticKind K) {
+    switch (K) {
+    case StatisticKind::ExpressionSuccessful:
+      return "Number of expr evaluation successes";
+    case StatisticKind::ExpressionFailure:
+      return "Number of expr evaluation failures";
+    case StatisticKind::FrameVarSuccess:
+      return "Number of frame var successes";
+    case StatisticKind::FrameVarFailure:
+      return "Number of frame var failures";
+    case StatisticKind::StatisticMax:
+      return "";
+    }
+    llvm_unreachable("Statistic not registered!");
+  }
+
+public:
+  CommandObjectStatsDump(CommandInterpreter &interpreter)
+      : CommandObjectParsed(interpreter, "dump", "Dump statistics results",
+                            nullptr, eCommandProcessMustBePaused) {}
+
+  ~CommandObjectStatsDump() override = default;
+
+protected:
+  bool DoExecute(Args &command, CommandReturnObject &result) override {
+    Target *target = GetSelectedOrDummyTarget();
+
+    uint32_t i = 0;
+    for (auto &stat : target->GetStatistics()) {
+      result.AppendMessageWithFormat(
+          "%s : %u\n",
+          GetStatDescription(static_cast<lldb_private::StatisticKind>(i))
+              .c_str(),
+          stat);
+      i += 1;
+    }
+    result.SetStatus(eReturnStatusSuccessFinishResult);
+    return true;
+  }
+};
+
+CommandObjectStats::CommandObjectStats(CommandInterpreter &interpreter)
+    : CommandObjectMultiword(interpreter, "statistics",
+                             "Print statistics about a debugging session",
+                             "statistics <subcommand> [<subcommand-options>]") {
+  LoadSubCommand("enable",
+                 CommandObjectSP(new CommandObjectStatsEnable(interpreter)));
+  LoadSubCommand("disable",
+                 CommandObjectSP(new CommandObjectStatsDisable(interpreter)));
+  LoadSubCommand("dump",
+                 CommandObjectSP(new CommandObjectStatsDump(interpreter)));
 }
 
-CommandObjectStats::~CommandObjectStats() {}
+CommandObjectStats::~CommandObjectStats() = default;
Index: lldb/trunk/source/Commands/CommandObjectFrame.cpp
===================================================================
--- lldb/trunk/source/Commands/CommandObjectFrame.cpp
+++ lldb/trunk/source/Commands/CommandObjectFrame.cpp
@@ -720,7 +720,16 @@
       m_interpreter.TruncationWarningGiven();
     }
 
-    return result.Succeeded();
+    // Increment statistics.
+    bool res = result.Succeeded();
+    Target *target = m_exe_ctx.GetTargetPtr();
+    if (!target)
+      target = GetDummyTarget();
+    if (res)
+      target->IncrementStats(StatisticKind::FrameVarSuccess);
+    else
+      target->IncrementStats(StatisticKind::FrameVarFailure);
+    return res;
   }
 
 protected:
Index: lldb/trunk/include/lldb/Target/Target.h
===================================================================
--- lldb/trunk/include/lldb/Target/Target.h
+++ lldb/trunk/include/lldb/Target/Target.h
@@ -35,6 +35,7 @@
 #include "lldb/Target/ProcessLaunchInfo.h"
 #include "lldb/Target/SectionLoadHistory.h"
 #include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/LLDBAssert.h"
 #include "lldb/Utility/Timeout.h"
 #include "lldb/lldb-public.h"
 
@@ -1284,6 +1285,28 @@
   static void ImageSearchPathsChanged(const PathMappingList &path_list,
                                       void *baton);
 
+  //------------------------------------------------------------------
+  // Utilities for `statistics` command.
+  //------------------------------------------------------------------
+private:
+  std::vector<uint32_t> m_stats_storage;
+  bool m_collecting_stats = false;
+
+public:
+  void SetCollectingStats(bool v) { m_collecting_stats = v; }
+
+  bool GetCollectingStats() { return m_collecting_stats; }
+
+  void IncrementStats(lldb_private::StatisticKind key) {
+    if (!GetCollectingStats())
+      return;
+    lldbassert(key < lldb_private::StatisticKind::StatisticMax &&
+               "invalid statistics!");
+    m_stats_storage[key] += 1;
+  }
+
+  std::vector<uint32_t> GetStatistics() { return m_stats_storage; }
+
 private:
   //------------------------------------------------------------------
   /// Construct with optional file and arch.
Index: lldb/trunk/include/lldb/lldb-private-enumerations.h
===================================================================
--- lldb/trunk/include/lldb/lldb-private-enumerations.h
+++ lldb/trunk/include/lldb/lldb-private-enumerations.h
@@ -234,6 +234,18 @@
   Typedef
 };
 
+//----------------------------------------------------------------------
+// Enumerations that can be used to specify the kind of metric we're
+// looking at when collecting stats.
+//----------------------------------------------------------------------
+enum StatisticKind {
+  ExpressionSuccessful = 0,
+  ExpressionFailure = 1,
+  FrameVarSuccess = 2,
+  FrameVarFailure = 3,
+  StatisticMax = 4
+};
+
 } // namespace lldb_private
 
 namespace llvm {
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to