From 6099d519bb83cc0b97ce8b529743f832de144110 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Tue, 6 Jun 2023 10:37:12 -0700 Subject: [PATCH] [lldb] Support file and function names in LLDB_LOGF macro LLDB's logging machinery supports prepending log messages with the name of the file and function that generates the log. However, currently this functionality is limited to the LLDB_LOG macro. I meant to do this as a follow up to D65128 but never got around to it. Differential revision: https://reviews.llvm.org/D151764 --- lldb/include/lldb/Utility/Log.h | 7 ++++++- lldb/source/Utility/Log.cpp | 15 +++++++++++++++ lldb/unittests/Utility/LogTest.cpp | 22 ++++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/lldb/include/lldb/Utility/Log.h b/lldb/include/lldb/Utility/Log.h index 2984a4bd..1fe28d6 100644 --- a/lldb/include/lldb/Utility/Log.h +++ b/lldb/include/lldb/Utility/Log.h @@ -232,6 +232,9 @@ public: std::forward(args)...)); } + void Formatf(llvm::StringRef file, llvm::StringRef function, + const char *format, ...) __attribute__((format(printf, 4, 5))); + /// Prefer using LLDB_LOGF whenever possible. void Printf(const char *format, ...) __attribute__((format(printf, 2, 3))); @@ -249,6 +252,8 @@ public: void VAPrintf(const char *format, va_list args); void VAError(const char *format, va_list args); + void VAFormatf(llvm::StringRef file, llvm::StringRef function, + const char *format, va_list args); private: Channel &m_channel; @@ -345,7 +350,7 @@ template Log *GetLog(Cat mask) { do { \ ::lldb_private::Log *log_private = (log); \ if (log_private) \ - log_private->Printf(__VA_ARGS__); \ + log_private->Formatf(__FILE__, __func__, __VA_ARGS__); \ } while (0) #define LLDB_LOGV(log, ...) \ diff --git a/lldb/source/Utility/Log.cpp b/lldb/source/Utility/Log.cpp index da8569e..7591268 100644 --- a/lldb/source/Utility/Log.cpp +++ b/lldb/source/Utility/Log.cpp @@ -155,6 +155,21 @@ void Log::VAPrintf(const char *format, va_list args) { PutString(Content); } +void Log::Formatf(llvm::StringRef file, llvm::StringRef function, + const char *format, ...) { + va_list args; + va_start(args, format); + VAFormatf(file, function, format, args); + va_end(args); +} + +void Log::VAFormatf(llvm::StringRef file, llvm::StringRef function, + const char *format, va_list args) { + llvm::SmallString<64> Content; + lldb_private::VASprintf(Content, format, args); + Format(file, function, llvm::formatv("{0}", Content)); +} + // Printing of errors that are not fatal. void Log::Error(const char *format, ...) { va_list args; diff --git a/lldb/unittests/Utility/LogTest.cpp b/lldb/unittests/Utility/LogTest.cpp index 275bd0d..d3c878d 100644 --- a/lldb/unittests/Utility/LogTest.cpp +++ b/lldb/unittests/Utility/LogTest.cpp @@ -100,6 +100,7 @@ protected: Log *getLog() { return m_log; } llvm::StringRef takeOutput(); llvm::StringRef logAndTakeOutput(llvm::StringRef Message); + llvm::StringRef logAndTakeOutputf(llvm::StringRef Message); public: void SetUp() override; @@ -136,6 +137,12 @@ LogChannelEnabledTest::logAndTakeOutput(llvm::StringRef Message) { return takeOutput(); } +llvm::StringRef +LogChannelEnabledTest::logAndTakeOutputf(llvm::StringRef Message) { + LLDB_LOGF(m_log, "%s", Message.str().c_str()); + return takeOutput(); +} + TEST(LogTest, LLDB_LOG_nullptr) { Log *log = nullptr; LLDB_LOG(log, "{0}", 0); // Shouldn't crash @@ -296,6 +303,21 @@ TEST_F(LogChannelEnabledTest, log_options) { EXPECT_STREQ("logAndTakeOutput", Function); } + { + EXPECT_TRUE(EnableChannel(getLogHandler(), + LLDB_LOG_OPTION_PREPEND_FILE_FUNCTION, "chan", {}, + Err)); + llvm::StringRef Msg = logAndTakeOutputf("Hello World"); + char File[12]; + char Function[17]; + + sscanf(Msg.str().c_str(), + "%[^:]:%s Hello World", File, + Function); + EXPECT_STRCASEEQ("LogTest.cpp", File); + EXPECT_STREQ("logAndTakeOutputf", Function); + } + EXPECT_TRUE(EnableChannel(getLogHandler(), LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD, "chan", {}, Err)); -- 2.7.4