This revision was automatically updated to reflect the committed changes.
Closed by commit rL292360: Add a more succinct logging syntax (authored by 
labath).

Changed prior to commit:
  https://reviews.llvm.org/D27459?vs=84690&id=84814#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D27459

Files:
  lldb/trunk/include/lldb/Core/Log.h
  lldb/trunk/source/Commands/CommandObjectLog.cpp
  lldb/trunk/source/Core/Log.cpp
  lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
  lldb/trunk/tools/lldb-server/lldb-gdbserver.cpp
  lldb/trunk/unittests/Core/CMakeLists.txt
  lldb/trunk/unittests/Core/LogTest.cpp

Index: lldb/trunk/include/lldb/Core/Log.h
===================================================================
--- lldb/trunk/include/lldb/Core/Log.h
+++ lldb/trunk/include/lldb/Core/Log.h
@@ -10,22 +10,19 @@
 #ifndef liblldb_Log_h_
 #define liblldb_Log_h_
 
-// C Includes
-#include <signal.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdio.h>
-
-// C++ Includes
-// Other libraries and framework includes
 // Project includes
 #include "lldb/Core/ConstString.h"
 #include "lldb/Core/Flags.h"
 #include "lldb/Core/Logging.h"
 #include "lldb/Core/PluginInterface.h"
 #include "lldb/lldb-private.h"
 
+// Other libraries and framework includes
 #include "llvm/Support/FormatVariadic.h"
+// C++ Includes
+#include <cstdarg>
+#include <cstdint>
+// C Includes
 
 //----------------------------------------------------------------------
 // Logging Options
@@ -39,6 +36,7 @@
 #define LLDB_LOG_OPTION_PREPEND_THREAD_NAME (1U << 6)
 #define LLDB_LOG_OPTION_BACKTRACE (1U << 7)
 #define LLDB_LOG_OPTION_APPEND (1U << 8)
+#define LLDB_LOG_OPTION_PREPEND_FILE_FUNCTION (1U << 9)
 
 //----------------------------------------------------------------------
 // Logging Functions
@@ -109,8 +107,10 @@
   void PutCString(const char *cstr);
   void PutString(llvm::StringRef str);
 
-  template <typename... Args> void Format(const char *fmt, Args &&... args) {
-    PutString(llvm::formatv(fmt, std::forward<Args>(args)...).str());
+  template <typename... Args>
+  void Format(llvm::StringRef file, llvm::StringRef function,
+              const char *format, Args &&... args) {
+    Format(file, function, llvm::formatv(format, std::forward<Args>(args)...));
   }
 
   // CLEANUP: Add llvm::raw_ostream &Stream() function.
@@ -155,6 +155,13 @@
 
 private:
   DISALLOW_COPY_AND_ASSIGN(Log);
+
+  void WriteHeader(llvm::raw_ostream &OS, llvm::StringRef file,
+                   llvm::StringRef function);
+  void WriteMessage(const std::string &message);
+
+  void Format(llvm::StringRef file, llvm::StringRef function,
+              const llvm::formatv_object_base &payload);
 };
 
 class LogChannel : public PluginInterface {
@@ -186,4 +193,11 @@
 
 } // namespace lldb_private
 
+#define LLDB_LOG(log, ...)                                                     \
+  do {                                                                         \
+    ::lldb_private::Log *log_private = (log);                                  \
+    if (log_private)                                                           \
+      log_private->Format(__FILE__, __FUNCTION__, __VA_ARGS__);                \
+  } while (0)
+
 #endif // liblldb_Log_h_
Index: lldb/trunk/unittests/Core/LogTest.cpp
===================================================================
--- lldb/trunk/unittests/Core/LogTest.cpp
+++ lldb/trunk/unittests/Core/LogTest.cpp
@@ -0,0 +1,56 @@
+//===-- LogTest.cpp ---------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Core/Log.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Host/Host.h"
+#include "gtest/gtest.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+static std::string GetLogString(uint32_t log_options, const char *format,
+                                int arg) {
+  std::shared_ptr<StreamString> stream_sp(new StreamString());
+  Log log_(stream_sp);
+  log_.GetOptions().Reset(log_options);
+  Log *log = &log_;
+  LLDB_LOG(log, format, arg);
+  return stream_sp->GetString();
+}
+
+TEST(LogTest, LLDB_LOG_nullptr) {
+  Log *log = nullptr;
+  LLDB_LOG(log, "{0}", 0); // Shouldn't crash
+}
+
+TEST(LogTest, log_options) {
+  EXPECT_EQ("Hello World 47\n", GetLogString(0, "Hello World {0}", 47));
+  EXPECT_EQ("Hello World 47\n",
+            GetLogString(LLDB_LOG_OPTION_THREADSAFE, "Hello World {0}", 47));
+
+  {
+    std::string msg =
+        GetLogString(LLDB_LOG_OPTION_PREPEND_SEQUENCE, "Hello World {0}", 47);
+    int seq_no;
+    EXPECT_EQ(1, sscanf(msg.c_str(), "%d Hello World 47", &seq_no));
+  }
+
+  EXPECT_EQ(
+      "LogTest.cpp:GetLogString                                     Hello "
+      "World 47\n",
+      GetLogString(LLDB_LOG_OPTION_PREPEND_FILE_FUNCTION, "Hello World {0}", 47));
+
+  EXPECT_EQ(llvm::formatv("[{0}/{1}] Hello World 47\n",
+                          Host::GetCurrentProcessID(),
+                          Host::GetCurrentThreadID())
+                .str(),
+            GetLogString(LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD,
+                         "Hello World {0}", 47));
+}
Index: lldb/trunk/unittests/Core/CMakeLists.txt
===================================================================
--- lldb/trunk/unittests/Core/CMakeLists.txt
+++ lldb/trunk/unittests/Core/CMakeLists.txt
@@ -4,6 +4,7 @@
   DataExtractorTest.cpp
   ErrorTest.cpp
   ListenerTest.cpp
+  LogTest.cpp
   ScalarTest.cpp
   StructuredDataTest.cpp
   TimerTest.cpp
Index: lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
===================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
@@ -512,11 +512,9 @@
    break;
  default:
    encoding_flags = 0x0600; /* fall back to 0x0600, kCFStringEncodingASCII */
-   if (log) {
-     log->Format("Encountered an Objective-C constant string with unusual "
+   LLDB_LOG(log, "Encountered an Objective-C constant string with unusual "
                  "element size {0}",
-                 string_array->getElementByteSize());
-   }
+            string_array->getElementByteSize());
  }
  Constant *encoding_arg = ConstantInt::get(i32_ty, encoding_flags, false);
  Constant *isExternal_arg =
Index: lldb/trunk/source/Commands/CommandObjectLog.cpp
===================================================================
--- lldb/trunk/source/Commands/CommandObjectLog.cpp
+++ lldb/trunk/source/Commands/CommandObjectLog.cpp
@@ -48,6 +48,7 @@
   { LLDB_OPT_SET_1, false, "thread-name",'n', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,     "Prepend all log lines with the thread name for the thread that generates the log line." },
   { LLDB_OPT_SET_1, false, "stack",      'S', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,     "Append a stack backtrace to each log line." },
   { LLDB_OPT_SET_1, false, "append",     'a', OptionParser::eNoArgument,       nullptr, nullptr, 0, eArgTypeNone,     "Append to the log file instead of overwriting." },
+  { LLDB_OPT_SET_1, false, "file-function",'F',OptionParser::eNoArgument,      nullptr, nullptr, 0, eArgTypeNone,     "Prepend the names of files and function that generate the logs." },
     // clang-format on
 };
 
@@ -130,6 +131,8 @@
       case 'a':
         log_options |= LLDB_LOG_OPTION_APPEND;
         break;
+      case 'F':
+        log_options |= LLDB_LOG_OPTION_PREPEND_FILE_FUNCTION;
       default:
         error.SetErrorStringWithFormat("unrecognized option '%c'",
                                        short_option);
Index: lldb/trunk/source/Core/Log.cpp
===================================================================
--- lldb/trunk/source/Core/Log.cpp
+++ lldb/trunk/source/Core/Log.cpp
@@ -20,6 +20,7 @@
 // Other libraries and framework includes
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/Chrono.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/raw_ostream.h"
 
@@ -69,58 +70,18 @@
 // a valid file handle, we also log to the file.
 //----------------------------------------------------------------------
 void Log::VAPrintf(const char *format, va_list args) {
-  // Make a copy of our stream shared pointer in case someone disables our
-  // log while we are logging and releases the stream
-  StreamSP stream_sp(m_stream_sp);
-  if (stream_sp) {
-    static uint32_t g_sequence_id = 0;
-    StreamString header;
-
-    // Add a sequence ID if requested
-    if (m_options.Test(LLDB_LOG_OPTION_PREPEND_SEQUENCE))
-      header.Printf("%u ", ++g_sequence_id);
-
-    // Timestamp if requested
-    if (m_options.Test(LLDB_LOG_OPTION_PREPEND_TIMESTAMP)) {
-      auto now = std::chrono::duration<double>(
-          std::chrono::system_clock::now().time_since_epoch());
-      header.Printf("%.9f ", now.count());
-    }
+  std::string message_string;
+  llvm::raw_string_ostream message(message_string);
+  WriteHeader(message, "", "");
+
+  char *text;
+  vasprintf(&text, format, args);
+  message << text;
+  free(text);
 
-    // Add the process and thread if requested
-    if (m_options.Test(LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD))
-      header.Printf("[%4.4x/%4.4" PRIx64 "]: ", getpid(),
-                    Host::GetCurrentThreadID());
-
-    // Add the thread name if requested
-    if (m_options.Test(LLDB_LOG_OPTION_PREPEND_THREAD_NAME)) {
-      llvm::SmallString<32> thread_name;
-      ThisThread::GetName(thread_name);
-      if (!thread_name.empty())
-        header.Printf("%s ", thread_name.c_str());
-    }
-
-    header.PrintfVarArg(format, args);
-    header.PutCString("\n");
-
-    if (m_options.Test(LLDB_LOG_OPTION_BACKTRACE)) {
-      std::string back_trace;
-      llvm::raw_string_ostream stream(back_trace);
-      llvm::sys::PrintStackTrace(stream);
-      stream.flush();
-      header.PutCString(back_trace);
-    }
+  message << "\n";
 
-    if (m_options.Test(LLDB_LOG_OPTION_THREADSAFE)) {
-      static std::recursive_mutex g_LogThreadedMutex;
-      std::lock_guard<std::recursive_mutex> guard(g_LogThreadedMutex);
-      stream_sp->PutCString(header.GetString());
-      stream_sp->Flush();
-    } else {
-      stream_sp->PutCString(header.GetString());
-      stream_sp->Flush();
-    }
-  }
+  WriteMessage(message.str());
 }
 
 //----------------------------------------------------------------------
@@ -353,6 +314,71 @@
   return false;
 }
 
+void Log::WriteHeader(llvm::raw_ostream &OS, llvm::StringRef file,
+                      llvm::StringRef function) {
+  static uint32_t g_sequence_id = 0;
+  // Add a sequence ID if requested
+  if (m_options.Test(LLDB_LOG_OPTION_PREPEND_SEQUENCE))
+    OS << ++g_sequence_id << " ";
+
+  // Timestamp if requested
+  if (m_options.Test(LLDB_LOG_OPTION_PREPEND_TIMESTAMP)) {
+    auto now = std::chrono::duration<double>(
+        std::chrono::system_clock::now().time_since_epoch());
+    OS << llvm::formatv("{0:f9} ", now.count());
+  }
+
+  // Add the process and thread if requested
+  if (m_options.Test(LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD))
+    OS << llvm::formatv("[{0,0+4}/{1,0+4}] ", getpid(),
+                        Host::GetCurrentThreadID());
+
+  // Add the thread name if requested
+  if (m_options.Test(LLDB_LOG_OPTION_PREPEND_THREAD_NAME)) {
+    llvm::SmallString<32> thread_name;
+    ThisThread::GetName(thread_name);
+    if (!thread_name.empty())
+      OS << thread_name;
+  }
+
+  if (m_options.Test(LLDB_LOG_OPTION_BACKTRACE))
+    llvm::sys::PrintStackTrace(OS);
+
+  if (m_options.Test(LLDB_LOG_OPTION_PREPEND_FILE_FUNCTION) &&
+      (!file.empty() || !function.empty())) {
+    file = llvm::sys::path::filename(file).take_front(40);
+    function = function.take_front(40);
+    OS << llvm::formatv("{0,-60:60} ", (file + ":" + function).str());
+  }
+}
+
+void Log::WriteMessage(const std::string &message) {
+  // Make a copy of our stream shared pointer in case someone disables our
+  // log while we are logging and releases the stream
+  StreamSP stream_sp(m_stream_sp);
+  if (!stream_sp)
+    return;
+
+  if (m_options.Test(LLDB_LOG_OPTION_THREADSAFE)) {
+    static std::recursive_mutex g_LogThreadedMutex;
+    std::lock_guard<std::recursive_mutex> guard(g_LogThreadedMutex);
+    stream_sp->PutCString(message.c_str());
+    stream_sp->Flush();
+  } else {
+    stream_sp->PutCString(message.c_str());
+    stream_sp->Flush();
+  }
+}
+
+void Log::Format(llvm::StringRef file, llvm::StringRef function,
+                 const llvm::formatv_object_base &payload) {
+  std::string message_string;
+  llvm::raw_string_ostream message(message_string);
+  WriteHeader(message, file, function);
+  message << payload << "\n";
+  WriteMessage(message.str());
+}
+
 LogChannelSP LogChannel::FindPlugin(const char *plugin_name) {
   LogChannelSP log_channel_sp;
   LogChannelMap &channel_map = GetChannelMap();
Index: lldb/trunk/tools/lldb-server/lldb-gdbserver.cpp
===================================================================
--- lldb/trunk/tools/lldb-server/lldb-gdbserver.cpp
+++ lldb/trunk/tools/lldb-server/lldb-gdbserver.cpp
@@ -424,8 +424,10 @@
     exit(option_error);
   }
 
-  if (!LLDBServerUtilities::SetupLogging(log_file, log_channels,
-                                         LLDB_LOG_OPTION_PREPEND_TIMESTAMP))
+  if (!LLDBServerUtilities::SetupLogging(
+          log_file, log_channels,
+          LLDB_LOG_OPTION_PREPEND_TIMESTAMP |
+              LLDB_LOG_OPTION_PREPEND_FILE_FUNCTION))
     return -1;
 
   Log *log(lldb_private::GetLogIfAnyCategoriesSet(GDBR_LOG_VERBOSE));
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to