xref: /freebsd/contrib/llvm-project/compiler-rt/lib/memprof/memprof_descriptions.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 
MemprofThreadIdAndName(MemprofThreadContext * t)22 MemprofThreadIdAndName::MemprofThreadIdAndName(MemprofThreadContext *t) {
23   Init(t->tid, t->name);
24 }
25 
MemprofThreadIdAndName(u32 tid)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 
Init(u32 tid,const char * tname)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 
DescribeThread(MemprofThreadContext * context)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.Append(" 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