From 3a18e319450a1fd9031f9879a2c3894d17338b95 Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Mon, 8 Oct 2012 22:41:53 +0000 Subject: [PATCH] Added a new "module" log channel which covers module creation, deletion, and common module list actions. Also added a new option for "log enable" which is "--stack" which will print out a stack backtrace for each log line. This was used to track down the leaking module issue I fixed last week. llvm-svn: 165438 --- lldb/include/lldb/Core/Log.h | 1 + lldb/include/lldb/Interpreter/CommandObject.h | 2 +- .../lldb/Interpreter/CommandObjectMultiword.h | 2 +- lldb/include/lldb/lldb-private-log.h | 1 + lldb/source/API/SBCommandInterpreter.cpp | 2 +- .../source/Commands/CommandObjectCommands.cpp | 2 +- lldb/source/Commands/CommandObjectLog.cpp | 2 + lldb/source/Core/Log.cpp | 3 ++ lldb/source/Core/Module.cpp | 12 +++--- lldb/source/Core/ModuleList.cpp | 5 +++ lldb/source/lldb-log.cpp | 41 ++++++++++--------- 11 files changed, 44 insertions(+), 29 deletions(-) diff --git a/lldb/include/lldb/Core/Log.h b/lldb/include/lldb/Core/Log.h index 1f808874b7ef..32b0287e954b 100644 --- a/lldb/include/lldb/Core/Log.h +++ b/lldb/include/lldb/Core/Log.h @@ -46,6 +46,7 @@ #define LLDB_LOG_OPTION_PREPEND_TIMESTAMP (1u << 4) #define LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD (1u << 5) #define LLDB_LOG_OPTION_PREPEND_THREAD_NAME (1U << 6) +#define LLDB_LOG_OPTION_BACKTRACE (1U << 7) //---------------------------------------------------------------------- // Logging Functions diff --git a/lldb/include/lldb/Interpreter/CommandObject.h b/lldb/include/lldb/Interpreter/CommandObject.h index c9ffd520146e..eb99d9946898 100644 --- a/lldb/include/lldb/Interpreter/CommandObject.h +++ b/lldb/include/lldb/Interpreter/CommandObject.h @@ -133,7 +133,7 @@ public: // the Command object from the Command dictionary (aliases have their own // deletion scheme, so they do not need to care about this) virtual bool - IsRemovable() { return false; } + IsRemovable() const { return false; } bool IsAlias () { return m_is_alias; } diff --git a/lldb/include/lldb/Interpreter/CommandObjectMultiword.h b/lldb/include/lldb/Interpreter/CommandObjectMultiword.h index eb41326a5bbe..3d9b2738c26a 100644 --- a/lldb/include/lldb/Interpreter/CommandObjectMultiword.h +++ b/lldb/include/lldb/Interpreter/CommandObjectMultiword.h @@ -74,7 +74,7 @@ public: CommandReturnObject &result); virtual bool - IsRemovable() { return m_can_be_removed; } + IsRemovable() const { return m_can_be_removed; } void SetRemovable (bool removable) diff --git a/lldb/include/lldb/lldb-private-log.h b/lldb/include/lldb/lldb-private-log.h index 1df6d57c336f..907a25f32d72 100644 --- a/lldb/include/lldb/lldb-private-log.h +++ b/lldb/include/lldb/lldb-private-log.h @@ -40,6 +40,7 @@ #define LIBLLDB_LOG_COMMANDS (1U << 18) #define LIBLLDB_LOG_TYPES (1u << 19) #define LIBLLDB_LOG_SYMBOLS (1u << 20) +#define LIBLLDB_LOG_MODULES (1u << 21) #define LIBLLDB_LOG_ALL (UINT32_MAX) #define LIBLLDB_LOG_DEFAULT (LIBLLDB_LOG_PROCESS |\ LIBLLDB_LOG_THREAD |\ diff --git a/lldb/source/API/SBCommandInterpreter.cpp b/lldb/source/API/SBCommandInterpreter.cpp index f125f55e7a0e..3f22a177a72a 100644 --- a/lldb/source/API/SBCommandInterpreter.cpp +++ b/lldb/source/API/SBCommandInterpreter.cpp @@ -40,7 +40,7 @@ public: m_backend(backend) {} virtual bool - IsRemovable() { return true; } + IsRemovable() const { return true; } protected: virtual bool diff --git a/lldb/source/Commands/CommandObjectCommands.cpp b/lldb/source/Commands/CommandObjectCommands.cpp index 64f80a0f51da..364c6f52c230 100644 --- a/lldb/source/Commands/CommandObjectCommands.cpp +++ b/lldb/source/Commands/CommandObjectCommands.cpp @@ -1186,7 +1186,7 @@ public: } virtual bool - IsRemovable () + IsRemovable () const { return true; } diff --git a/lldb/source/Commands/CommandObjectLog.cpp b/lldb/source/Commands/CommandObjectLog.cpp index 7c77e6999b1f..fb982972d267 100644 --- a/lldb/source/Commands/CommandObjectLog.cpp +++ b/lldb/source/Commands/CommandObjectLog.cpp @@ -144,6 +144,7 @@ public: case 'T': log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP; break; case 'p': log_options |= LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD;break; case 'n': log_options |= LLDB_LOG_OPTION_PREPEND_THREAD_NAME; break; + case 'S': log_options |= LLDB_LOG_OPTION_BACKTRACE; break; default: error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); break; @@ -215,6 +216,7 @@ CommandObjectLogEnable::CommandOptions::g_option_table[] = { LLDB_OPT_SET_1, false, "timestamp", 'T', no_argument, NULL, 0, eArgTypeNone, "Prepend all log lines with a timestamp." }, { LLDB_OPT_SET_1, false, "pid-tid", 'p', no_argument, NULL, 0, eArgTypeNone, "Prepend all log lines with the process and thread ID that generates the log line." }, { LLDB_OPT_SET_1, false, "thread-name",'n', no_argument, NULL, 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', no_argument, NULL, 0, eArgTypeNone, "Append a stack backtrace to each log line." }, { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } }; diff --git a/lldb/source/Core/Log.cpp b/lldb/source/Core/Log.cpp index 0b163fb04f54..17281c03fd03 100644 --- a/lldb/source/Core/Log.cpp +++ b/lldb/source/Core/Log.cpp @@ -118,6 +118,9 @@ Log::PrintfWithFlagsVarArg (uint32_t flags, const char *format, va_list args) header.PrintfVarArg (format, args); m_stream_sp->Printf("%s\n", header.GetData()); + + if (m_options.Test (LLDB_LOG_OPTION_BACKTRACE)) + Host::Backtrace (*m_stream_sp, 1024); m_stream_sp->Flush(); } } diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp index 64a5ebdb722a..0c82b6686abc 100644 --- a/lldb/source/Core/Module.cpp +++ b/lldb/source/Core/Module.cpp @@ -117,7 +117,7 @@ namespace lldb { } #endif - + Module::Module (const ModuleSpec &module_spec) : m_mutex (Mutex::eMutexTypeRecursive), m_mod_time (module_spec.GetFileSpec().GetModificationTime()), @@ -146,7 +146,7 @@ Module::Module (const ModuleSpec &module_spec) : GetModuleCollection().push_back(this); } - LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); + LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_OBJECT|LIBLLDB_LOG_MODULES)); if (log) log->Printf ("%p Module::Module((%s) '%s/%s%s%s%s')", this, @@ -191,7 +191,7 @@ Module::Module(const FileSpec& file_spec, if (object_name) m_object_name = *object_name; - LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); + LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_OBJECT|LIBLLDB_LOG_MODULES)); if (log) log->Printf ("%p Module::Module((%s) '%s/%s%s%s%s')", this, @@ -211,10 +211,10 @@ Module::~Module() ModuleCollection &modules = GetModuleCollection(); ModuleCollection::iterator end = modules.end(); ModuleCollection::iterator pos = std::find(modules.begin(), end, this); - if (pos != end) - modules.erase(pos); + assert (pos != end); + modules.erase(pos); } - LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); + LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_OBJECT|LIBLLDB_LOG_MODULES)); if (log) log->Printf ("%p Module::~Module((%s) '%s/%s%s%s%s')", this, diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp index 5adffa1e6799..338482b3ff73 100644 --- a/lldb/source/Core/ModuleList.cpp +++ b/lldb/source/Core/ModuleList.cpp @@ -724,6 +724,11 @@ ModuleList::GetSharedModule { if (old_module_sp_ptr && !old_module_sp_ptr->get()) *old_module_sp_ptr = module_sp; + + LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_MODULES)); + if (log) + log->Printf("module changed: %p, removing from global module list", module_sp.get()); + shared_module_list.Remove (module_sp); module_sp.reset(); } diff --git a/lldb/source/lldb-log.cpp b/lldb/source/lldb-log.cpp index 5510631b8d34..71c5460a6c43 100644 --- a/lldb/source/lldb-log.cpp +++ b/lldb/source/lldb-log.cpp @@ -135,6 +135,7 @@ lldb_private::DisableLog (const char **categories, Stream *feedback_strm) else if (0 == ::strncasecmp(arg, "unwind", 6)) flag_bits &= ~LIBLLDB_LOG_UNWIND; else if (0 == ::strncasecmp(arg, "types", 5)) flag_bits &= ~LIBLLDB_LOG_TYPES; else if (0 == ::strncasecmp(arg, "symbol", 6)) flag_bits &= ~LIBLLDB_LOG_SYMBOLS; + else if (0 == ::strncasecmp(arg, "module", 6)) flag_bits &= ~LIBLLDB_LOG_MODULES; else { feedback_strm->Printf ("error: unrecognized log category '%s'\n", arg); @@ -201,6 +202,7 @@ lldb_private::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const ch else if (0 == ::strncasecmp(arg, "unwind", 6)) flag_bits |= LIBLLDB_LOG_UNWIND; else if (0 == ::strncasecmp(arg, "types", 5)) flag_bits |= LIBLLDB_LOG_TYPES; else if (0 == ::strncasecmp(arg, "symbol", 6)) flag_bits |= LIBLLDB_LOG_SYMBOLS; + else if (0 == ::strncasecmp(arg, "module", 6)) flag_bits |= LIBLLDB_LOG_MODULES; else { feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); @@ -220,23 +222,24 @@ void lldb_private::ListLogCategories (Stream *strm) { strm->Printf("Logging categories for 'lldb':\n" - " all - turn on all available logging categories\n" - " api - enable logging of API calls and return values\n" - " command - log command argument parsing\n" - " default - enable the default set of logging categories for liblldb\n" - " break - log breakpoints\n" - " events - log broadcaster, listener and event queue activities\n" - " expr - log expressions\n" - " object - log object construction/destruction for important objects\n" - " process - log process events and activities\n" - " thread - log thread events and activities\n" - " script - log events about the script interpreter\n" - " dyld - log shared library related activities\n" - " state - log private and public process state changes\n" - " step - log step related activities\n" - " unwind - log stack unwind activities\n" - " verbose - enable verbose logging\n" - " symbol - log symbol related issues and warnings\n" - " watch - log watchpoint related activities\n" - " types - log type system related activities\n"); + " all - turn on all available logging categories\n" + " api - enable logging of API calls and return values\n" + " break - log breakpoints\n" + " command - log command argument parsing\n" + " default - enable the default set of logging categories for liblldb\n" + " dyld - log shared library related activities\n" + " events - log broadcaster, listener and event queue activities\n" + " expr - log expressions\n" + " object - log object construction/destruction for important objects\n" + " module - log module activities such as when modules are created, detroyed, replaced, and more\n" + " process - log process events and activities\n" + " script - log events about the script interpreter\n" + " state - log private and public process state changes\n" + " step - log step related activities\n" + " symbol - log symbol related issues and warnings\n" + " thread - log thread events and activities\n" + " types - log type system related activities\n" + " unwind - log stack unwind activities\n" + " verbose - enable verbose logging\n" + " watch - log watchpoint related activities\n"); }