//===-- memprof_descriptions.cpp -------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file is a part of MemProfiler, a memory profiler. // // MemProf functions for getting information about an address and/or printing // it. //===----------------------------------------------------------------------===// #include "memprof_descriptions.h" #include "memprof_mapping.h" #include "memprof_stack.h" #include "sanitizer_common/sanitizer_stackdepot.h" namespace __memprof { MemprofThreadIdAndName::MemprofThreadIdAndName(MemprofThreadContext *t) { Init(t->tid, t->name); } MemprofThreadIdAndName::MemprofThreadIdAndName(u32 tid) { if (tid == kInvalidTid) { Init(tid, ""); } else { memprofThreadRegistry().CheckLocked(); MemprofThreadContext *t = GetThreadContextByTidLocked(tid); Init(tid, t->name); } } void MemprofThreadIdAndName::Init(u32 tid, const char *tname) { int len = internal_snprintf(name, sizeof(name), "T%d", tid); CHECK(((unsigned int)len) < sizeof(name)); if (tname[0] != '\0') internal_snprintf(&name[len], sizeof(name) - len, " (%s)", tname); } void DescribeThread(MemprofThreadContext *context) { CHECK(context); memprofThreadRegistry().CheckLocked(); // No need to announce the main thread. if (context->tid == kMainTid || context->announced) { return; } context->announced = true; InternalScopedString str; str.append("Thread %s", MemprofThreadIdAndName(context).c_str()); if (context->parent_tid == kInvalidTid) { str.append(" created by unknown thread\n"); Printf("%s", str.data()); return; } str.append(" created by %s here:\n", MemprofThreadIdAndName(context->parent_tid).c_str()); Printf("%s", str.data()); StackDepotGet(context->stack_id).Print(); // Recursively described parent thread if needed. if (flags()->print_full_thread_history) { MemprofThreadContext *parent_context = GetThreadContextByTidLocked(context->parent_tid); DescribeThread(parent_context); } } } // namespace __memprof