[Lldb-commits] [PATCH] D124922: [lldb] Inject commands into log output when directed to file

Will Hawkins via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Wed May 4 06:44:54 PDT 2022


hawkinsw created this revision.
hawkinsw added reviewers: teemperor, JDevlieghere, labath.
Herald added a project: All.
hawkinsw requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

When logging for the lldb channel is enabled for any category and the
channel output is being directed to a file, inject a copy of every
command entered. This change will make it easier to contextualize the
debugging output with any commands that the user entered.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D124922

Files:
  lldb/include/lldb/Utility/Log.h
  lldb/source/Commands/CommandObjectLog.cpp
  lldb/source/Interpreter/CommandInterpreter.cpp


Index: lldb/source/Interpreter/CommandInterpreter.cpp
===================================================================
--- lldb/source/Interpreter/CommandInterpreter.cpp
+++ lldb/source/Interpreter/CommandInterpreter.cpp
@@ -1838,11 +1838,17 @@
   std::string original_command_string(command_line);
 
   Log *log = GetLog(LLDBLog::Commands);
+  Log *lldb_log = GetChannelLogWhenAnyCategoryEnabled<LLDBLog>();
   llvm::PrettyStackTraceFormat stack_trace("HandleCommand(command = \"%s\")",
                                    command_line);
 
   LLDB_LOGF(log, "Processing command: %s", command_line);
   LLDB_SCOPED_TIMERF("Processing command: %s.", command_line);
+  // If there is logging enabled for any category in the lldb channel that
+  // is being directed to a file, log every command. This functionality will
+  // make it easier for the user reading a log file after the fact to correlate
+  // the debugging output with the commands that may have caused it.
+  LLDB_LOGF_FILE_ONLY(lldb_log, "(lldb) %s\n", command_line);
 
   if (WasInterrupted()) {
     result.AppendError("interrupted");
Index: lldb/source/Commands/CommandObjectLog.cpp
===================================================================
--- lldb/source/Commands/CommandObjectLog.cpp
+++ lldb/source/Commands/CommandObjectLog.cpp
@@ -88,6 +88,7 @@
       case 'f':
         log_file.SetFile(option_arg, FileSpec::Style::native);
         FileSystem::Instance().Resolve(log_file);
+        log_options |= LLDB_LOG_OPTION_LOG_TO_FILE;
         break;
       case 't':
         log_options |= LLDB_LOG_OPTION_THREADSAFE;
Index: lldb/include/lldb/Utility/Log.h
===================================================================
--- lldb/include/lldb/Utility/Log.h
+++ lldb/include/lldb/Utility/Log.h
@@ -24,6 +24,7 @@
 #include <atomic>
 #include <cstdarg>
 #include <cstdint>
+#include <limits>
 #include <memory>
 #include <string>
 #include <type_traits>
@@ -41,6 +42,7 @@
 #define LLDB_LOG_OPTION_BACKTRACE (1U << 7)
 #define LLDB_LOG_OPTION_APPEND (1U << 8)
 #define LLDB_LOG_OPTION_PREPEND_FILE_FUNCTION (1U << 9)
+#define LLDB_LOG_OPTION_LOG_TO_FILE (1U << 10)
 
 // Logging Functions
 namespace lldb_private {
@@ -238,6 +240,18 @@
   return LogChannelFor<Cat>().GetLog(Log::MaskType(mask));
 }
 
+/// Retrieve the Log object for a channel when any of its categories are
+/// enabled.
+///
+/// Returns a valid Log object if any of the categories for a channel are
+/// enabled. Otherwise, returns nullptr.
+template <typename Channel> Log *GetChannelLogWhenAnyCategoryEnabled() {
+  static_assert(
+      std::is_same<Log::MaskType, std::underlying_type_t<Channel>>::value, "");
+  Log::MaskType any_category_flag = std::numeric_limits<Log::MaskType>::max();
+  return LogChannelFor<Channel>().GetLog(any_category_flag);
+}
+
 } // namespace lldb_private
 
 /// The LLDB_LOG* macros defined below are the way to emit log messages.
@@ -274,6 +288,15 @@
       log_private->Printf(__VA_ARGS__);                                        \
   } while (0)
 
+// Write a message to the log only if that log is sending its output to a file.
+#define LLDB_LOGF_FILE_ONLY(log, ...)                                          \
+  do {                                                                         \
+    ::lldb_private::Log *log_private = (log);                                  \
+    if (log_private &&                                                         \
+        log_private->GetOptions().Test(LLDB_LOG_OPTION_LOG_TO_FILE))           \
+      log_private->Printf(__VA_ARGS__);                                        \
+  } while (0)
+
 #define LLDB_LOGV(log, ...)                                                    \
   do {                                                                         \
     ::lldb_private::Log *log_private = (log);                                  \


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D124922.426989.patch
Type: text/x-patch
Size: 3875 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20220504/e082121e/attachment-0001.bin>


More information about the lldb-commits mailing list