diff --git a/lldb/source/Host/common/Host.cpp b/lldb/source/Host/common/Host.cpp index 14fcce3804c1..e92d824aa36f 100644 --- a/lldb/source/Host/common/Host.cpp +++ b/lldb/source/Host/common/Host.cpp @@ -629,40 +629,6 @@ Host::ThreadJoin (lldb::thread_t thread, thread_result_t *thread_result_ptr, Err return err == 0; } - -std::string -Host::GetThreadName (lldb::pid_t pid, lldb::tid_t tid) -{ - 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()) - { - char pthread_name[1024]; - if (::pthread_getname_np (::pthread_from_mach_thread_np (tid), pthread_name, sizeof(pthread_name)) == 0) - { - if (pthread_name[0]) - { - 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 thread_name; -} - bool Host::SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name) { diff --git a/lldb/source/Host/linux/Host.cpp b/lldb/source/Host/linux/Host.cpp index 47b455099569..f6266e67878b 100644 --- a/lldb/source/Host/linux/Host.cpp +++ b/lldb/source/Host/linux/Host.cpp @@ -104,6 +104,13 @@ ReadProcPseudoFile (lldb::pid_t pid, const char *name) return buf_sp; } +lldb::DataBufferSP +ReadProcPseudoFile (lldb::pid_t pid, lldb::tid_t tid, const char *name) +{ + std::string process_thread_pseudo_file = "task/" + std::to_string(tid) + "/" + name; + return ReadProcPseudoFile(pid, process_thread_pseudo_file.c_str()); +} + } // anonymous namespace static bool @@ -472,6 +479,33 @@ Host::ThreadCreated (const char *thread_name) } } +std::string +Host::GetThreadName (lldb::pid_t pid, lldb::tid_t tid) +{ + const size_t thread_name_max_size = 16; + char pthread_name[thread_name_max_size]; + std::string thread_name; + // Read the /proc/$PID/stat file. + lldb::DataBufferSP buf_sp = ReadProcPseudoFile (pid, tid, "stat"); + + // The file/thread name of the executable is stored in parenthesis. Search for the first + // '(' and last ')' and copy everything in between. + const char *filename_start = ::strchr ((const char *)buf_sp->GetBytes(), '('); + const char *filename_end = ::strrchr ((const char *)buf_sp->GetBytes(), ')'); + + if (filename_start && filename_end) + { + ++filename_start; + size_t length = filename_end - filename_start; + if (length > thread_name_max_size) + length = thread_name_max_size; + strncpy(pthread_name, filename_start, length); + thread_name = std::string(pthread_name, length); + } + + return thread_name; +} + void Host::Backtrace (Stream &strm, uint32_t max_frames) { diff --git a/lldb/source/Host/macosx/Host.mm b/lldb/source/Host/macosx/Host.mm index 6cc6027c65e1..7642a3e847d8 100644 --- a/lldb/source/Host/macosx/Host.mm +++ b/lldb/source/Host/macosx/Host.mm @@ -148,6 +148,39 @@ Host::ThreadCreated (const char *thread_name) } } +std::string +Host::GetThreadName (lldb::pid_t pid, lldb::tid_t tid) +{ + std::string thread_name; +#if 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()) + { + char pthread_name[1024]; + if (::pthread_getname_np (::pthread_from_mach_thread_np (tid), pthread_name, sizeof(pthread_name)) == 0) + { + if (pthread_name[0]) + { + 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 thread_name; +} + bool Host::GetBundleDirectory (const FileSpec &file, FileSpec &bundle_directory) { diff --git a/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp b/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp index fe617987baa9..ee5c35be0288 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp +++ b/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp @@ -1098,6 +1098,7 @@ ProcessMonitor::Launch(LaunchArgs *args) lldb::pid_t pid; lldb::ThreadSP inferior; + POSIXThread *thread; Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); // Propagate the environment if one is not supplied. @@ -1232,6 +1233,10 @@ ProcessMonitor::Launch(LaunchArgs *args) // FIXME: should we be letting UpdateThreadList handle this? // FIXME: by using pids instead of tids, we can only support one thread. inferior.reset(new POSIXThread(process, pid)); + + thread = static_cast(inferior.get()); + thread->SetName(Host::GetThreadName(pid, pid).c_str()); + if (log) log->Printf ("ProcessMonitor::%s() adding pid = %" PRIu64, __FUNCTION__, pid); process.GetThreadList().AddThread(inferior); @@ -1292,6 +1297,7 @@ ProcessMonitor::Attach(AttachArgs *args) ProcessMonitor *monitor = args->m_monitor; ProcessLinux &process = monitor->GetProcess(); lldb::ThreadSP inferior; + POSIXThread *thread; Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); // Use a map to keep track of the threads which we have attached/need to attach. @@ -1357,6 +1363,10 @@ ProcessMonitor::Attach(AttachArgs *args) // Update the process thread list with the attached thread. inferior.reset(new POSIXThread(process, tid)); + + thread = static_cast(inferior.get()); + thread->SetName(Host::GetThreadName(pid, tid).c_str()); + if (log) log->Printf ("ProcessMonitor::%s() adding tid = %" PRIu64, __FUNCTION__, tid); process.GetThreadList().AddThread(inferior); diff --git a/lldb/source/Plugins/Process/POSIX/POSIXThread.cpp b/lldb/source/Plugins/Process/POSIX/POSIXThread.cpp index 09f0525c63a3..e55ba265d89e 100644 --- a/lldb/source/Plugins/Process/POSIX/POSIXThread.cpp +++ b/lldb/source/Plugins/Process/POSIX/POSIXThread.cpp @@ -41,7 +41,9 @@ using namespace lldb_private; POSIXThread::POSIXThread(Process &process, lldb::tid_t tid) : Thread(process, tid), - m_frame_ap() + m_frame_ap (), + m_breakpoint (), + m_thread_name () { Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) @@ -104,6 +106,23 @@ POSIXThread::GetInfo() return NULL; } +void +POSIXThread::SetName (const char *name) +{ + if (name && name[0]) + m_thread_name.assign (name); + else + m_thread_name.clear(); +} + +const char * +POSIXThread::GetName () +{ + if (m_thread_name.empty()) + return NULL; + return m_thread_name.c_str(); +} + lldb::RegisterContextSP POSIXThread::GetRegisterContext() { diff --git a/lldb/source/Plugins/Process/POSIX/POSIXThread.h b/lldb/source/Plugins/Process/POSIX/POSIXThread.h index d0c081fcf4f4..59b02a75f06d 100644 --- a/lldb/source/Plugins/Process/POSIX/POSIXThread.h +++ b/lldb/source/Plugins/Process/POSIX/POSIXThread.h @@ -13,6 +13,7 @@ // C Includes // C++ Includes #include +#include // Other libraries and framework includes #include "lldb/Target/Thread.h" @@ -46,6 +47,12 @@ public: const char * GetInfo(); + void + SetName (const char *name); + + const char * + GetName (); + virtual lldb::RegisterContextSP GetRegisterContext(); @@ -100,6 +107,8 @@ private: lldb::BreakpointSiteSP m_breakpoint; + std::string m_thread_name; + ProcessMonitor & GetMonitor(); diff --git a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp index e09bfcaf4181..d55609a7b872 100644 --- a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp +++ b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp @@ -491,8 +491,13 @@ ProcessPOSIX::RefreshStateAfterStop() { if (log) log->Printf ("ProcessPOSIX::%s() adding thread, tid = %" PRIi64, __FUNCTION__, message.GetChildTID()); + lldb::tid_t child_tid = message.GetChildTID(); ThreadSP thread_sp; - thread_sp.reset(new POSIXThread(*this, message.GetChildTID())); + thread_sp.reset(new POSIXThread(*this, child_tid)); + + POSIXThread *thread = static_cast(thread_sp.get()); + thread->SetName(Host::GetThreadName(GetID(), child_tid).c_str()); + m_thread_list.AddThread(thread_sp); }