xref: /aosp_15_r20/external/bcc/examples/cpp/pyperf/PyPerfDefaultPrinter.cc (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker /*
2*387f9dfdSAndroid Build Coastguard Worker  * Copyright (c) Facebook, Inc.
3*387f9dfdSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License")
4*387f9dfdSAndroid Build Coastguard Worker  */
5*387f9dfdSAndroid Build Coastguard Worker 
6*387f9dfdSAndroid Build Coastguard Worker #include <map>
7*387f9dfdSAndroid Build Coastguard Worker #include <string>
8*387f9dfdSAndroid Build Coastguard Worker 
9*387f9dfdSAndroid Build Coastguard Worker #include "PyPerfDefaultPrinter.h"
10*387f9dfdSAndroid Build Coastguard Worker #include "PyPerfUtil.h"
11*387f9dfdSAndroid Build Coastguard Worker 
12*387f9dfdSAndroid Build Coastguard Worker namespace ebpf {
13*387f9dfdSAndroid Build Coastguard Worker namespace pyperf {
14*387f9dfdSAndroid Build Coastguard Worker 
15*387f9dfdSAndroid Build Coastguard Worker const static std::string kLostSymbol = "[Lost Symbol]";
16*387f9dfdSAndroid Build Coastguard Worker const static std::string kIncompleteStack = "[Truncated Stack]";
17*387f9dfdSAndroid Build Coastguard Worker const static std::string kErrorStack = "[Stack Error]";
18*387f9dfdSAndroid Build Coastguard Worker const static std::string kNonPythonStack = "[Non-Python Code]";
19*387f9dfdSAndroid Build Coastguard Worker 
20*387f9dfdSAndroid Build Coastguard Worker const static std::map<int, const char*> kGILStateValues = {
21*387f9dfdSAndroid Build Coastguard Worker     {GIL_STATE_NO_INFO, "No GIL Info"},
22*387f9dfdSAndroid Build Coastguard Worker     {GIL_STATE_ERROR, "Error Reading GIL State"},
23*387f9dfdSAndroid Build Coastguard Worker     {GIL_STATE_UNINITIALIZED, "GIL Uninitialized"},
24*387f9dfdSAndroid Build Coastguard Worker     {GIL_STATE_NOT_LOCKED, "GIL Not Locked"},
25*387f9dfdSAndroid Build Coastguard Worker     {GIL_STATE_THIS_THREAD, "GIL on This Thread"},
26*387f9dfdSAndroid Build Coastguard Worker     {GIL_STATE_GLOBAL_CURRENT_THREAD,
27*387f9dfdSAndroid Build Coastguard Worker      "GIL on Global _PyThreadState_Current Thread"},
28*387f9dfdSAndroid Build Coastguard Worker     {GIL_STATE_OTHER_THREAD, "GIL on Unexpected Thread"},
29*387f9dfdSAndroid Build Coastguard Worker     {GIL_STATE_NULL, "GIL State Empty"}};
30*387f9dfdSAndroid Build Coastguard Worker 
31*387f9dfdSAndroid Build Coastguard Worker const static std::map<int, const char*> kThreadStateValues = {
32*387f9dfdSAndroid Build Coastguard Worker     {THREAD_STATE_UNKNOWN, "ThreadState Unknown"},
33*387f9dfdSAndroid Build Coastguard Worker     {THREAD_STATE_MATCH, "TLS ThreadState is Global _PyThreadState_Current"},
34*387f9dfdSAndroid Build Coastguard Worker     {THREAD_STATE_MISMATCH,
35*387f9dfdSAndroid Build Coastguard Worker      "TLS ThreadState is not Global _PyThreadState_Current"},
36*387f9dfdSAndroid Build Coastguard Worker     {THREAD_STATE_THIS_THREAD_NULL, "TLS ThreadState is NULL"},
37*387f9dfdSAndroid Build Coastguard Worker     {THREAD_STATE_GLOBAL_CURRENT_THREAD_NULL,
38*387f9dfdSAndroid Build Coastguard Worker      "Global _PyThreadState_Current is NULL"},
39*387f9dfdSAndroid Build Coastguard Worker     {THREAD_STATE_BOTH_NULL,
40*387f9dfdSAndroid Build Coastguard Worker      "Both TLS ThreadState and Global _PyThreadState_Current is NULL"},
41*387f9dfdSAndroid Build Coastguard Worker };
42*387f9dfdSAndroid Build Coastguard Worker 
43*387f9dfdSAndroid Build Coastguard Worker const static std::map<int, const char*> kPthreadIDStateValues = {
44*387f9dfdSAndroid Build Coastguard Worker     {PTHREAD_ID_UNKNOWN, "Pthread ID Unknown"},
45*387f9dfdSAndroid Build Coastguard Worker     {PTHREAD_ID_MATCH, "System Pthread ID is Python ThreadState Pthread ID"},
46*387f9dfdSAndroid Build Coastguard Worker     {PTHREAD_ID_MISMATCH,
47*387f9dfdSAndroid Build Coastguard Worker      "System Pthread ID is not Python ThreadState Pthread ID"},
48*387f9dfdSAndroid Build Coastguard Worker     {PTHREAD_ID_THREAD_STATE_NULL, "No Pthread ID: TLS ThreadState is NULL"},
49*387f9dfdSAndroid Build Coastguard Worker     {PTHREAD_ID_NULL, "Pthread ID on TLS ThreadState is NULL"},
50*387f9dfdSAndroid Build Coastguard Worker     {PTHREAD_ID_ERROR, "Error Reading System Pthread ID"}};
51*387f9dfdSAndroid Build Coastguard Worker 
processSamples(const std::vector<PyPerfSample> & samples,PyPerfUtil * util)52*387f9dfdSAndroid Build Coastguard Worker void PyPerfDefaultPrinter::processSamples(
53*387f9dfdSAndroid Build Coastguard Worker     const std::vector<PyPerfSample>& samples, PyPerfUtil* util) {
54*387f9dfdSAndroid Build Coastguard Worker   auto symbols = util->getSymbolMapping();
55*387f9dfdSAndroid Build Coastguard Worker   uint32_t lostSymbols = 0;
56*387f9dfdSAndroid Build Coastguard Worker   uint32_t truncatedStack = 0;
57*387f9dfdSAndroid Build Coastguard Worker 
58*387f9dfdSAndroid Build Coastguard Worker   for (auto& sample : samples) {
59*387f9dfdSAndroid Build Coastguard Worker     if (sample.threadStateMatch != THREAD_STATE_THIS_THREAD_NULL &&
60*387f9dfdSAndroid Build Coastguard Worker         sample.threadStateMatch != THREAD_STATE_BOTH_NULL) {
61*387f9dfdSAndroid Build Coastguard Worker       for (const auto stackId : sample.pyStackIds) {
62*387f9dfdSAndroid Build Coastguard Worker         auto symbIt = symbols.find(stackId);
63*387f9dfdSAndroid Build Coastguard Worker         if (symbIt != symbols.end()) {
64*387f9dfdSAndroid Build Coastguard Worker           std::printf("    %s\n", symbIt->second.c_str());
65*387f9dfdSAndroid Build Coastguard Worker         } else {
66*387f9dfdSAndroid Build Coastguard Worker           std::printf("    %s\n", kLostSymbol.c_str());
67*387f9dfdSAndroid Build Coastguard Worker           lostSymbols++;
68*387f9dfdSAndroid Build Coastguard Worker         }
69*387f9dfdSAndroid Build Coastguard Worker       }
70*387f9dfdSAndroid Build Coastguard Worker       switch (sample.stackStatus) {
71*387f9dfdSAndroid Build Coastguard Worker       case STACK_STATUS_TRUNCATED:
72*387f9dfdSAndroid Build Coastguard Worker         std::printf("    %s\n", kIncompleteStack.c_str());
73*387f9dfdSAndroid Build Coastguard Worker         truncatedStack++;
74*387f9dfdSAndroid Build Coastguard Worker         break;
75*387f9dfdSAndroid Build Coastguard Worker       case STACK_STATUS_ERROR:
76*387f9dfdSAndroid Build Coastguard Worker         std::printf("    %s\n", kErrorStack.c_str());
77*387f9dfdSAndroid Build Coastguard Worker         break;
78*387f9dfdSAndroid Build Coastguard Worker       default:
79*387f9dfdSAndroid Build Coastguard Worker         break;
80*387f9dfdSAndroid Build Coastguard Worker       }
81*387f9dfdSAndroid Build Coastguard Worker     } else {
82*387f9dfdSAndroid Build Coastguard Worker       std::printf("    %s\n", kNonPythonStack.c_str());
83*387f9dfdSAndroid Build Coastguard Worker     }
84*387f9dfdSAndroid Build Coastguard Worker 
85*387f9dfdSAndroid Build Coastguard Worker     std::printf("PID: %d TID: %d (%s)\n", sample.pid, sample.tid,
86*387f9dfdSAndroid Build Coastguard Worker                 sample.comm.c_str());
87*387f9dfdSAndroid Build Coastguard Worker     if (showGILState_)
88*387f9dfdSAndroid Build Coastguard Worker       std::printf("GIL State: %s\n", kGILStateValues.at(sample.gilState));
89*387f9dfdSAndroid Build Coastguard Worker     if (showThreadState_)
90*387f9dfdSAndroid Build Coastguard Worker       std::printf("Thread State: %s\n",
91*387f9dfdSAndroid Build Coastguard Worker                   kThreadStateValues.at(sample.threadStateMatch));
92*387f9dfdSAndroid Build Coastguard Worker     if (showPthreadIDState_)
93*387f9dfdSAndroid Build Coastguard Worker       std::printf("Pthread ID State: %s\n",
94*387f9dfdSAndroid Build Coastguard Worker                   kPthreadIDStateValues.at(sample.pthreadIDMatch));
95*387f9dfdSAndroid Build Coastguard Worker 
96*387f9dfdSAndroid Build Coastguard Worker     std::printf("\n");
97*387f9dfdSAndroid Build Coastguard Worker   }
98*387f9dfdSAndroid Build Coastguard Worker 
99*387f9dfdSAndroid Build Coastguard Worker   std::printf("%d samples collected\n", util->getTotalSamples());
100*387f9dfdSAndroid Build Coastguard Worker   std::printf("%d samples lost\n", util->getLostSamples());
101*387f9dfdSAndroid Build Coastguard Worker   std::printf("%d samples with truncated stack\n", truncatedStack);
102*387f9dfdSAndroid Build Coastguard Worker   std::printf("%d times Python symbol lost\n", lostSymbols);
103*387f9dfdSAndroid Build Coastguard Worker }
104*387f9dfdSAndroid Build Coastguard Worker 
105*387f9dfdSAndroid Build Coastguard Worker }  // namespace pyperf
106*387f9dfdSAndroid Build Coastguard Worker }  // namespace ebpf
107