diff options
| author | 2014-10-14 13:12:01 -0700 | |
|---|---|---|
| committer | 2014-10-14 18:12:09 -0700 | |
| commit | e094b87c6f6ea9ebf83aa56a3114ac59556aaf9f (patch) | |
| tree | d6db16b54affbe5304a8155bee3536b982acafd7 | |
| parent | cfd8adec84701752a56ddccf556b8c40142a9e0f (diff) | |
Store exiting thread ids and names while tracing to output later.
Bug: 17909204
(cherry picked from commit fdcbc5c4c7c67bba06e038ac96a2e8bc49b91f84)
Change-Id: Iea087560ba8b983412a6dde2ec166c9e7214f3a1
| -rw-r--r-- | runtime/thread_list.cc | 4 | ||||
| -rw-r--r-- | runtime/trace.cc | 12 | ||||
| -rw-r--r-- | runtime/trace.h | 5 |
3 files changed, 21 insertions, 0 deletions
diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc index 35411e2660..646830acc6 100644 --- a/runtime/thread_list.cc +++ b/runtime/thread_list.cc @@ -34,6 +34,7 @@ #include "monitor.h" #include "scoped_thread_state_change.h" #include "thread.h" +#include "trace.h" #include "utils.h" #include "well_known_classes.h" @@ -877,6 +878,9 @@ void ThreadList::Unregister(Thread* self) { // suspend and so on, must happen at this point, and not in ~Thread. self->Destroy(); + // If tracing, remember thread id and name before thread exits. + Trace::StoreExitingThreadInfo(self); + uint32_t thin_lock_id = self->GetThreadId(); while (self != nullptr) { // Remove and delete the Thread* while holding the thread_list_lock_ and diff --git a/runtime/trace.cc b/runtime/trace.cc index 027f62d880..91a37fddaf 100644 --- a/runtime/trace.cc +++ b/runtime/trace.cc @@ -706,9 +706,21 @@ static void DumpThread(Thread* t, void* arg) { void Trace::DumpThreadList(std::ostream& os) { Thread* self = Thread::Current(); + for (auto it : exited_threads_) { + os << it.first << "\t" << it.second << "\n"; + } Locks::thread_list_lock_->AssertNotHeld(self); MutexLock mu(self, *Locks::thread_list_lock_); Runtime::Current()->GetThreadList()->ForEach(DumpThread, &os); } +void Trace::StoreExitingThreadInfo(Thread* thread) { + MutexLock mu(thread, *Locks::trace_lock_); + if (the_trace_ != nullptr) { + std::string name; + thread->GetThreadName(name); + the_trace_->exited_threads_.Put(thread->GetTid(), name); + } +} + } // namespace art diff --git a/runtime/trace.h b/runtime/trace.h index 45a02dab3c..ead1c29c72 100644 --- a/runtime/trace.h +++ b/runtime/trace.h @@ -104,6 +104,8 @@ class Trace FINAL : public instrumentation::InstrumentationListener { static std::vector<mirror::ArtMethod*>* AllocStackTrace(); // Clear and store an old stack trace for later use. static void FreeStackTrace(std::vector<mirror::ArtMethod*>* stack_trace); + // Save id and name of a thread before it exits. + static void StoreExitingThreadInfo(Thread* thread); private: explicit Trace(File* trace_file, int buffer_size, int flags, bool sampling_enabled); @@ -166,6 +168,9 @@ class Trace FINAL : public instrumentation::InstrumentationListener { // Did we overflow the buffer recording traces? bool overflow_; + // Map of thread ids and names that have already exited. + SafeMap<pid_t, std::string> exited_threads_; + DISALLOW_COPY_AND_ASSIGN(Trace); }; |