From 8571963a7ce63d0d60665c3c33b4122a38b23636 Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Wed, 27 Feb 2013 22:51:58 +0000 Subject: [PATCH] Fixed a case where the result of std::string's c_str() method was being called on a local variable and returned as a const char * incorrectly. We used to cache the thread names for threads in the current host process, but we shoudn't be caching that as the names can change over time, so now a std::string is returned from Host::GetThreadName(). llvm-svn: 176217 --- lldb/include/lldb/Host/Host.h | 8 +-- lldb/source/Core/Log.cpp | 7 +-- lldb/source/Host/common/Host.cpp | 98 ++++++++------------------------ 3 files changed, 31 insertions(+), 82 deletions(-) diff --git a/lldb/include/lldb/Host/Host.h b/lldb/include/lldb/Host/Host.h index 710ad55b6e4f..fad6faa99dfe 100644 --- a/lldb/include/lldb/Host/Host.h +++ b/lldb/include/lldb/Host/Host.h @@ -13,6 +13,8 @@ #include +#include + #include "lldb/lldb-private.h" #include "lldb/Core/StringList.h" @@ -276,11 +278,9 @@ public: /// The thread ID for which we are trying retrieve the name of. /// /// @return - /// A NULL terminate C string name that is owned by a static - /// global string pool, or NULL if there is no matching thread - /// name. This string does not need to be freed. + /// A std::string containing the thread name. //------------------------------------------------------------------ - static const char * + static std::string GetThreadName (lldb::pid_t pid, lldb::tid_t tid); //------------------------------------------------------------------ diff --git a/lldb/source/Core/Log.cpp b/lldb/source/Core/Log.cpp index f8e422e2df79..3743631fbb78 100644 --- a/lldb/source/Core/Log.cpp +++ b/lldb/source/Core/Log.cpp @@ -112,10 +112,9 @@ Log::PrintfWithFlagsVarArg (uint32_t flags, const char *format, va_list args) // Add the process and thread if requested if (m_options.Test (LLDB_LOG_OPTION_PREPEND_THREAD_NAME)) { - const char *thread_name_str = Host::GetThreadName (getpid(), Host::GetCurrentThreadID()); - if (thread_name_str) - header.Printf ("%s ", thread_name_str); - + std::string thread_name (Host::GetThreadName (getpid(), Host::GetCurrentThreadID())); + if (!thread_name.empty()) + header.Printf ("%s ", thread_name.c_str()); } header.PrintfVarArg (format, args); diff --git a/lldb/source/Host/common/Host.cpp b/lldb/source/Host/common/Host.cpp index 18a8fbabee5d..ab7faf54d198 100644 --- a/lldb/source/Host/common/Host.cpp +++ b/lldb/source/Host/common/Host.cpp @@ -615,92 +615,44 @@ Host::ThreadJoin (lldb::thread_t thread, thread_result_t *thread_result_ptr, Err return err == 0; } -// rdar://problem/8153284 -// Fixed a crasher where during shutdown, loggings attempted to access the -// thread name but the static map instance had already been destructed. -// So we are using a ThreadSafeSTLMap POINTER, initializing it with a -// pthread_once action. That map will get leaked. -// -// Another approach is to introduce a static guard object which monitors its -// own destruction and raises a flag, but this incurs more overhead. -static pthread_once_t g_thread_map_once = PTHREAD_ONCE_INIT; -static ThreadSafeSTLMap *g_thread_names_map_ptr; - -static void -InitThreadNamesMap() -{ - g_thread_names_map_ptr = new ThreadSafeSTLMap(); -} - -//------------------------------------------------------------------ -// Control access to a static file thread name map using a single -// static function to avoid a static constructor. -//------------------------------------------------------------------ -static const char * -ThreadNameAccessor (bool get, lldb::pid_t pid, lldb::tid_t tid, const char *name) -{ - int success = ::pthread_once (&g_thread_map_once, InitThreadNamesMap); - if (success != 0) - return NULL; - - uint64_t pid_tid = ((uint64_t)pid << 32) | (uint64_t)tid; - - if (get) - { - // See if the thread name exists in our thread name pool - std::string value; - bool found_it = g_thread_names_map_ptr->GetValueForKey (pid_tid, value); - if (found_it) - return value.c_str(); - else - return NULL; - } - else if (name) - { - // Set the thread name - g_thread_names_map_ptr->SetValueForKey (pid_tid, std::string(name)); - } - return NULL; -} - -const char * +std::string Host::GetThreadName (lldb::pid_t pid, lldb::tid_t tid) { - const char *name = ThreadNameAccessor (true, pid, tid, NULL); - if (name == NULL) - { + std::string thread_name; #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 - // We currently can only get the name of a thread in the current process. - if (pid == Host::GetCurrentProcessID()) + // We currently can only get the name of a thread in the current process. + if (pid == Host::GetCurrentProcessID()) + { + char pthread_name[1024]; + if (::pthread_getname_np (::pthread_from_mach_thread_np (tid), pthread_name, sizeof(pthread_name)) == 0) { - char pthread_name[1024]; - if (::pthread_getname_np (::pthread_from_mach_thread_np (tid), pthread_name, sizeof(pthread_name)) == 0) + if (pthread_name[0]) { - if (pthread_name[0]) - { - // Set the thread in our string pool - ThreadNameAccessor (false, pid, tid, pthread_name); - // Get our copy of the thread name string - name = ThreadNameAccessor (true, pid, tid, NULL); - } - } - - if (name == NULL) - { - dispatch_queue_t current_queue = ::dispatch_get_current_queue (); - if (current_queue != NULL) - name = dispatch_queue_get_label (current_queue); + thread_name = pthread_name; + } + } + else + { + dispatch_queue_t current_queue = ::dispatch_get_current_queue (); + if (current_queue != NULL) + { + const char *queue_name = dispatch_queue_get_label (current_queue); + if (queue_name && queue_name[0]) + { + thread_name = queue_name; + } } } -#endif } - return name; +#endif + return thread_name; } void Host::SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name) { +#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 lldb::pid_t curr_pid = Host::GetCurrentProcessID(); lldb::tid_t curr_tid = Host::GetCurrentThreadID(); if (pid == LLDB_INVALID_PROCESS_ID) @@ -709,14 +661,12 @@ Host::SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name) if (tid == LLDB_INVALID_THREAD_ID) tid = curr_tid; -#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 // Set the pthread name if possible if (pid == curr_pid && tid == curr_tid) { ::pthread_setname_np (name); } #endif - ThreadNameAccessor (false, pid, tid, name); } FileSpec