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