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 20namespace __memprof { 21 22MemprofThreadIdAndName::MemprofThreadIdAndName(MemprofThreadContext *t) { 23 Init(t->tid, t->name); 24} 25 26MemprofThreadIdAndName::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 36void 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 43void 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