1 //===-- memprof_descriptions.cpp -------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file is a part of MemProfiler, a memory profiler. 10 // 11 // MemProf functions for getting information about an address and/or printing 12 // it. 13 //===----------------------------------------------------------------------===// 14 15 #include "memprof_descriptions.h" 16 #include "memprof_mapping.h" 17 #include "memprof_stack.h" 18 #include "sanitizer_common/sanitizer_stackdepot.h" 19 20 namespace __memprof { 21 22 MemprofThreadIdAndName::MemprofThreadIdAndName(MemprofThreadContext *t) { 23 Init(t->tid, t->name); 24 } 25 26 MemprofThreadIdAndName::MemprofThreadIdAndName(u32 tid) { 27 if (tid == kInvalidTid) { 28 Init(tid, ""); 29 } else { 30 memprofThreadRegistry().CheckLocked(); 31 MemprofThreadContext *t = GetThreadContextByTidLocked(tid); 32 Init(tid, t->name); 33 } 34 } 35 36 void MemprofThreadIdAndName::Init(u32 tid, const char *tname) { 37 int len = internal_snprintf(name, sizeof(name), "T%d", tid); 38 CHECK(((unsigned int)len) < sizeof(name)); 39 if (tname[0] != '\0') 40 internal_snprintf(&name[len], sizeof(name) - len, " (%s)", tname); 41 } 42 43 void DescribeThread(MemprofThreadContext *context) { 44 CHECK(context); 45 memprofThreadRegistry().CheckLocked(); 46 // No need to announce the main thread. 47 if (context->tid == kMainTid || context->announced) { 48 return; 49 } 50 context->announced = true; 51 InternalScopedString str; 52 str.AppendF("Thread %s", MemprofThreadIdAndName(context).c_str()); 53 if (context->parent_tid == kInvalidTid) { 54 str.AppendF(" created by unknown thread\n"); 55 Printf("%s", str.data()); 56 return; 57 } 58 str.AppendF(" created by %s here:\n", 59 MemprofThreadIdAndName(context->parent_tid).c_str()); 60 Printf("%s", str.data()); 61 StackDepotGet(context->stack_id).Print(); 62 // Recursively described parent thread if needed. 63 if (flags()->print_full_thread_history) { 64 MemprofThreadContext *parent_context = 65 GetThreadContextByTidLocked(context->parent_tid); 66 DescribeThread(parent_context); 67 } 68 } 69 70 } // namespace __memprof 71