labath updated this revision to Diff 84108.
labath added a comment.
- Several people expressed wishes to have this off by default, so I have done
that.
- Renamed the log option to --file-function (Note I am deliberately not
printing the line numbers -- they tend to change all the time and it's more
consistent with what the code is currently doing)
- I am planning to submit the core changes only, the refactors are here just
for illustration, and I'll handle them separately.
https://reviews.llvm.org/D27459
Files:
include/lldb/Core/Log.h
source/Commands/CommandObjectLog.cpp
source/Core/Log.cpp
source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
source/Plugins/Process/Linux/NativeProcessLinux.cpp
source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp
tools/lldb-server/lldb-gdbserver.cpp
unittests/Core/CMakeLists.txt
unittests/Core/LogTest.cpp
Index: unittests/Core/LogTest.cpp
===================================================================
--- /dev/null
+++ 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: unittests/Core/CMakeLists.txt
===================================================================
--- unittests/Core/CMakeLists.txt
+++ unittests/Core/CMakeLists.txt
@@ -4,6 +4,7 @@
DataExtractorTest.cpp
ErrorTest.cpp
ListenerTest.cpp
+ LogTest.cpp
ScalarTest.cpp
StructuredDataTest.cpp
TimerTest.cpp
Index: tools/lldb-server/lldb-gdbserver.cpp
===================================================================
--- tools/lldb-server/lldb-gdbserver.cpp
+++ 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));
Index: source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp
===================================================================
--- source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp
+++ source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp
@@ -176,6 +176,7 @@
bool RegisterContextWindows_x86::ReadRegister(const RegisterInfo *reg_info,
RegisterValue ®_value) {
+ Log *log = ProcessWindowsLog::GetLogIfAllCategoriesSet(WINDOWS_LOG_REGISTERS);
if (!CacheAllRegisterValues())
return false;
@@ -203,7 +204,7 @@
return ReadRegisterHelper(CONTEXT_CONTROL, "EFLAGS", m_context.EFlags,
reg_value);
default:
- WINWARN_IFALL(WINDOWS_LOG_REGISTERS, "Requested unknown register %u", reg);
+ LLDB_LOG(log, "Requested unknown register %u", reg);
break;
}
return false;
@@ -219,62 +220,52 @@
if (!CacheAllRegisterValues())
return false;
+ Log *log = ProcessWindowsLog::GetLogIfAllCategoriesSet(WINDOWS_LOG_REGISTERS);
uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
switch (reg) {
case lldb_eax_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EAX",
- reg_value.GetAsUInt32());
+ LLDB_LOG(log, "Write value {0:x} to EAX", reg_value.GetAsUInt32());
m_context.Eax = reg_value.GetAsUInt32();
break;
case lldb_ebx_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EBX",
- reg_value.GetAsUInt32());
+ LLDB_LOG(log, "Write value {0:x} to EBX", reg_value.GetAsUInt32());
m_context.Ebx = reg_value.GetAsUInt32();
break;
case lldb_ecx_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ECX",
- reg_value.GetAsUInt32());
+ LLDB_LOG("Write value {0:x} to ECX", reg_value.GetAsUInt32());
m_context.Ecx = reg_value.GetAsUInt32();
break;
case lldb_edx_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EDX",
- reg_value.GetAsUInt32());
+ LLDB_LOG(log, "Write value {0:x} to EDX", reg_value.GetAsUInt32());
m_context.Edx = reg_value.GetAsUInt32();
break;
case lldb_edi_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EDI",
- reg_value.GetAsUInt32());
+ LLDB_LOG(log, "Write value {0:x} to EDI", reg_value.GetAsUInt32());
m_context.Edi = reg_value.GetAsUInt32();
break;
case lldb_esi_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ESI",
- reg_value.GetAsUInt32());
+ LLDB_LOG(log, "Write value {0:x} to ESI", reg_value.GetAsUInt32());
m_context.Esi = reg_value.GetAsUInt32();
break;
case lldb_ebp_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EBP",
- reg_value.GetAsUInt32());
+ LLDB_LOG(log, "Write value {0:x} to EBP", reg_value.GetAsUInt32());
m_context.Ebp = reg_value.GetAsUInt32();
break;
case lldb_esp_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to ESP",
- reg_value.GetAsUInt32());
+ LLDB_LOG(log, "Write value {0:x} to ESP", reg_value.GetAsUInt32());
m_context.Esp = reg_value.GetAsUInt32();
break;
case lldb_eip_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EIP",
- reg_value.GetAsUInt32());
+ LLDB_LOG(log, "Write value {0:x} to EIP", reg_value.GetAsUInt32());
m_context.Eip = reg_value.GetAsUInt32();
break;
case lldb_eflags_i386:
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Write value 0x%x to EFLAGS",
- reg_value.GetAsUInt32());
+ LLDB_LOG(log, "Write value {0:x} to EFLAGS", reg_value.GetAsUInt32());
m_context.EFlags = reg_value.GetAsUInt32();
break;
default:
- WINWARN_IFALL(WINDOWS_LOG_REGISTERS,
- "Write value 0x%x to unknown register %u",
- reg_value.GetAsUInt32(), reg);
+ LLDB_LOG(log, "Write value {0:x} to unknown register {1}",
+ reg_value.GetAsUInt32(), reg);
}
// Physically update the registers in the target process.
@@ -286,13 +277,12 @@
bool RegisterContextWindows_x86::ReadRegisterHelper(
DWORD flags_required, const char *reg_name, DWORD value,
RegisterValue ®_value) const {
+ Log *log = ProcessWindowsLog::GetLogIfAllCategoriesSet(WINDOWS_LOG_REGISTERS);
if ((m_context.ContextFlags & flags_required) != flags_required) {
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Thread context doesn't have %s",
- reg_name);
+ LLDB_LOG(log, "Thread context doesn't have {0}", reg_name);
return false;
}
- WINLOG_IFALL(WINDOWS_LOG_REGISTERS, "Read value 0x%lx from %s", value,
- reg_name);
+ LLDB_LOG(log, "Read value {0:x} from {1}", value, reg_name);
reg_value.SetUInt32(value);
return true;
}
Index: source/Plugins/Process/Linux/NativeProcessLinux.cpp
===================================================================
--- source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -92,16 +92,13 @@
// value from our own process.
ssize_t res = process_vm_readv(getpid(), &local, 1, &remote, 1, 0);
is_supported = (res == sizeof(source) && source == dest);
- if (log) {
- if (is_supported)
- log->Printf("%s: Detected kernel support for process_vm_readv syscall. "
- "Fast memory reads enabled.",
- __FUNCTION__);
- else
- log->Printf("%s: syscall process_vm_readv failed (error: %s). Fast "
- "memory reads disabled.",
- __FUNCTION__, strerror(errno));
- }
+ if (is_supported)
+ LLDB_LOG(log, "Detected kernel support for process_vm_readv syscall. "
+ "Fast memory reads enabled.");
+ else
+ LLDB_LOG(log, "syscall process_vm_readv failed (error: {0}). Fast memory "
+ "reads disabled.",
+ strerror(errno));
});
return is_supported;
@@ -114,28 +111,24 @@
return;
if (const FileAction *action = info.GetFileActionForFD(STDIN_FILENO))
- log->Printf("%s: setting STDIN to '%s'", __FUNCTION__,
- action->GetFileSpec().GetCString());
+ LLDB_LOG(log, "setting STDIN to '{0}'", action->GetFileSpec());
else
- log->Printf("%s leaving STDIN as is", __FUNCTION__);
+ LLDB_LOG(log, "leaving STDIN as is");
if (const FileAction *action = info.GetFileActionForFD(STDOUT_FILENO))
- log->Printf("%s setting STDOUT to '%s'", __FUNCTION__,
- action->GetFileSpec().GetCString());
+ LLDB_LOG(log, "setting STDOUT to '{0}'", action->GetFileSpec());
else
- log->Printf("%s leaving STDOUT as is", __FUNCTION__);
+ LLDB_LOG(log, "leaving STDOUT as is");
if (const FileAction *action = info.GetFileActionForFD(STDERR_FILENO))
- log->Printf("%s setting STDERR to '%s'", __FUNCTION__,
- action->GetFileSpec().GetCString());
+ LLDB_LOG(log, "setting STDERR to '{0}'", action->GetFileSpec());
else
- log->Printf("%s leaving STDERR as is", __FUNCTION__);
+ LLDB_LOG(log, "leaving STDERR as is");
int i = 0;
for (const char **args = info.GetArguments().GetConstArgumentVector(); *args;
++args, ++i)
- log->Printf("%s arg %d: \"%s\"", __FUNCTION__, i,
- *args ? *args : "nullptr");
+ LLDB_LOG(log, "arg {0}: '{1}'", i, *args);
}
void DisplayBytes(StreamString &s, void *bytes, uint32_t count) {
@@ -148,50 +141,50 @@
}
void PtraceDisplayBytes(int &req, void *data, size_t data_size) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE |
+ POSIX_LOG_VERBOSE));
+ if (!log)
+ return;
StreamString buf;
- Log *verbose_log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(
- POSIX_LOG_PTRACE | POSIX_LOG_VERBOSE));
-
- if (verbose_log) {
- switch (req) {
- case PTRACE_POKETEXT: {
- DisplayBytes(buf, &data, 8);
- verbose_log->Printf("PTRACE_POKETEXT %s", buf.GetData());
- break;
- }
- case PTRACE_POKEDATA: {
- DisplayBytes(buf, &data, 8);
- verbose_log->Printf("PTRACE_POKEDATA %s", buf.GetData());
- break;
- }
- case PTRACE_POKEUSER: {
- DisplayBytes(buf, &data, 8);
- verbose_log->Printf("PTRACE_POKEUSER %s", buf.GetData());
- break;
- }
- case PTRACE_SETREGS: {
- DisplayBytes(buf, data, data_size);
- verbose_log->Printf("PTRACE_SETREGS %s", buf.GetData());
- break;
- }
- case PTRACE_SETFPREGS: {
- DisplayBytes(buf, data, data_size);
- verbose_log->Printf("PTRACE_SETFPREGS %s", buf.GetData());
- break;
- }
- case PTRACE_SETSIGINFO: {
- DisplayBytes(buf, data, sizeof(siginfo_t));
- verbose_log->Printf("PTRACE_SETSIGINFO %s", buf.GetData());
- break;
- }
- case PTRACE_SETREGSET: {
- // Extract iov_base from data, which is a pointer to the struct IOVEC
- DisplayBytes(buf, *(void **)data, data_size);
- verbose_log->Printf("PTRACE_SETREGSET %s", buf.GetData());
- break;
- }
- default: {}
- }
+
+ switch (req) {
+ case PTRACE_POKETEXT: {
+ DisplayBytes(buf, &data, 8);
+ LLDB_LOG(log, "PTRACE_POKETEXT {0}", buf.GetData());
+ break;
+ }
+ case PTRACE_POKEDATA: {
+ DisplayBytes(buf, &data, 8);
+ LLDB_LOG(log, "PTRACE_POKEDATA {0}", buf.GetData());
+ break;
+ }
+ case PTRACE_POKEUSER: {
+ DisplayBytes(buf, &data, 8);
+ LLDB_LOG(log, "PTRACE_POKEUSER {0}", buf.GetData());
+ break;
+ }
+ case PTRACE_SETREGS: {
+ DisplayBytes(buf, data, data_size);
+ LLDB_LOG(log, "PTRACE_SETREGS {0}", buf.GetData());
+ break;
+ }
+ case PTRACE_SETFPREGS: {
+ DisplayBytes(buf, data, data_size);
+ LLDB_LOG(log, "PTRACE_SETFPREGS {0}", buf.GetData());
+ break;
+ }
+ case PTRACE_SETSIGINFO: {
+ DisplayBytes(buf, data, sizeof(siginfo_t));
+ LLDB_LOG(log, "PTRACE_SETSIGINFO {0}", buf.GetData());
+ break;
+ }
+ case PTRACE_SETREGSET: {
+ // Extract iov_base from data, which is a pointer to the struct IOVEC
+ DisplayBytes(buf, *(void **)data, data_size);
+ LLDB_LOG(log, "PTRACE_SETREGSET {0}", buf.GetData());
+ break;
+ }
+ default: {}
}
}
@@ -255,9 +248,7 @@
if (error.Fail()) {
native_process_sp.reset();
- if (log)
- log->Printf("NativeProcessLinux::%s failed to launch process: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOG(log, "failed to launch process: {0}", error);
return error;
}
@@ -270,8 +261,7 @@
lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
MainLoop &mainloop, NativeProcessProtocolSP &native_process_sp) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
- log->Printf("NativeProcessLinux::%s(pid = %" PRIi64 ")", __FUNCTION__, pid);
+ LLDB_LOG(log, "pid = {0:x}", pid);
// Retrieve the architecture for the running process.
ArchSpec process_arch;
@@ -307,9 +297,7 @@
void NativeProcessLinux::AttachToInferior(MainLoop &mainloop, lldb::pid_t pid,
Error &error) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("NativeProcessLinux::%s (pid = %" PRIi64 ")", __FUNCTION__,
- pid);
+ LLDB_LOG(log, "pid = {0:x}", pid);
m_sigchld_handle = mainloop.RegisterSignal(
SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, error);
@@ -321,11 +309,8 @@
return;
// Set the architecture to the exe architecture.
- if (log)
- log->Printf("NativeProcessLinux::%s (pid = %" PRIi64
- ") detected architecture %s",
- __FUNCTION__, pid, m_arch.GetArchitectureName());
-
+ LLDB_LOG(log, "pid = {0:x}, detected architecture {1}", pid,
+ m_arch.GetArchitectureName());
m_pid = pid;
SetState(eStateAttaching);
@@ -356,9 +341,7 @@
int status;
if ((wpid = waitpid(pid, &status, 0)) < 0) {
error.SetErrorToErrno();
- if (log)
- log->Printf("NativeProcessLinux::%s waitpid for inferior failed with %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOG(log, "waitpid for inferior failed with %s", error);
// Mark the inferior as invalid.
// FIXME this could really use a new state - eStateLaunchFailure. For now,
@@ -370,16 +353,10 @@
assert(WIFSTOPPED(status) && (wpid == static_cast<::pid_t>(pid)) &&
"Could not sync with inferior process.");
- if (log)
- log->Printf("NativeProcessLinux::%s inferior started, now in stopped state",
- __FUNCTION__);
-
+ LLDB_LOG(log, "inferior started, now in stopped state");
error = SetDefaultPtraceOpts(pid);
if (error.Fail()) {
- if (log)
- log->Printf("NativeProcessLinux::%s inferior failed to set default "
- "ptrace options: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOG(log, "failed to set default ptrace options: {0}", error);
// Mark the inferior as invalid.
// FIXME this could really use a new state - eStateLaunchFailure. For now,
@@ -398,10 +375,9 @@
if (m_terminal_fd != -1) {
error = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
if (error.Fail()) {
- if (log)
- log->Printf("NativeProcessLinux::%s inferior EnsureFDFlags failed for "
- "ensuring terminal O_NONBLOCK setting: %s",
- __FUNCTION__, error.AsCString());
+ LLDB_LOG(log, "inferior EnsureFDFlags failed for ensuring terminal "
+ "O_NONBLOCK setting: {0}",
+ error);
// Mark the inferior as invalid.
// FIXME this could really use a new state - eStateLaunchFailure. For
@@ -412,10 +388,7 @@
}
}
- if (log)
- log->Printf("NativeProcessLinux::%s() adding pid = %" PRIu64, __FUNCTION__,
- uint64_t(pid));
-
+ LLDB_LOG(log, "adding pid = {0}", pid);
ResolveProcessArchitecture(m_pid, m_arch);
NativeThreadLinuxSP thread_sp = AddThread(pid);
assert(thread_sp && "AddThread() returned a nullptr thread");
@@ -426,14 +399,8 @@
SetCurrentThreadID(thread_sp->GetID());
SetState(StateType::eStateStopped);
- if (log) {
- if (error.Success())
- log->Printf("NativeProcessLinux::%s inferior launching succeeded",
- __FUNCTION__);
- else
- log->Printf("NativeProcessLinux::%s inferior launching failed: %s",
- __FUNCTION__, error.AsCString());
- }
+ if (error.Fail())
+ LLDB_LOG(log, "inferior launching failed {0}", error);
return error;
}
@@ -487,10 +454,7 @@
if (error.Fail())
return -1;
- if (log)
- log->Printf("NativeProcessLinux::%s() adding tid = %" PRIu64,
- __FUNCTION__, tid);
-
+ LLDB_LOG(log, "adding tid = {0}", tid);
it->second = true;
// Create the thread, mark it as stopped.
@@ -578,11 +542,8 @@
// Handle when the thread exits.
if (exited) {
- if (log)
- log->Printf(
- "NativeProcessLinux::%s() got exit signal(%d) , tid = %" PRIu64
- " (%s main thread)",
- __FUNCTION__, signal, pid, is_main_thread ? "is" : "is not");
+ LLDB_LOG(log, "got exit signal({0}) , tid = {1} ({2} main thread)", signal,
+ pid, is_main_thread ? "is" : "is not");
// This is a thread that exited. Ensure we're not tracking it anymore.
const bool thread_found = StopTrackingThread(pid);
@@ -596,41 +557,32 @@
const bool already_notified = (GetState() == StateType::eStateExited) ||
(GetState() == StateType::eStateCrashed);
if (!already_notified) {
- if (log)
- log->Printf("NativeProcessLinux::%s() tid = %" PRIu64
- " handling main thread exit (%s), expected exit state "
- "already set but state was %s instead, setting exit "
- "state now",
- __FUNCTION__, pid,
- thread_found ? "stopped tracking thread metadata"
- : "thread metadata not found",
- StateAsCString(GetState()));
+ LLDB_LOG(
+ log,
+ "tid = {0} handling main thread exit ({1}), expected exit state "
+ "already set but state was {2} instead, setting exit state now",
+ pid,
+ thread_found ? "stopped tracking thread metadata"
+ : "thread metadata not found",
+ StateAsCString(GetState()));
// The main thread exited. We're done monitoring. Report to delegate.
SetExitStatus(convert_pid_status_to_exit_type(status),
convert_pid_status_to_return_code(status), nullptr, true);
// Notify delegate that our process has exited.
SetState(StateType::eStateExited, true);
- } else {
- if (log)
- log->Printf("NativeProcessLinux::%s() tid = %" PRIu64
- " main thread now exited (%s)",
- __FUNCTION__, pid,
- thread_found ? "stopped tracking thread metadata"
- : "thread metadata not found");
- }
+ } else
+ LLDB_LOG(log, "tid = {0} main thread now exited (%s)", pid,
+ thread_found ? "stopped tracking thread metadata"
+ : "thread metadata not found");
} else {
// Do we want to report to the delegate in this case? I think not. If
- // this was an orderly
- // thread exit, we would already have received the SIGTRAP |
- // (PTRACE_EVENT_EXIT << 8) signal,
- // and we would have done an all-stop then.
- if (log)
- log->Printf("NativeProcessLinux::%s() tid = %" PRIu64
- " handling non-main thread exit (%s)",
- __FUNCTION__, pid,
- thread_found ? "stopped tracking thread metadata"
- : "thread metadata not found");
+ // this was an orderly thread exit, we would already have received the
+ // SIGTRAP | (PTRACE_EVENT_EXIT << 8) signal, and we would have done an
+ // all-stop then.
+ LLDB_LOG(log, "tid = {0} handling non-main thread exit (%s)", pid,
+ thread_found ? "stopped tracking thread metadata"
+ : "thread metadata not found");
}
return;
}
Index: source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
===================================================================
--- source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
+++ 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: source/Core/Log.cpp
===================================================================
--- source/Core/Log.cpp
+++ 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, "", "");
- // 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");
+ char *text;
+ vasprintf(&text, format, args);
+ message << text;
+ free(text);
- 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());
}
//----------------------------------------------------------------------
@@ -368,6 +329,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: source/Commands/CommandObjectLog.cpp
===================================================================
--- source/Commands/CommandObjectLog.cpp
+++ 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: include/lldb/Core/Log.h
===================================================================
--- include/lldb/Core/Log.h
+++ 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_
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits