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