1 /* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef RELIABILITY_STACK_PRINTER_H 17 #define RELIABILITY_STACK_PRINTER_H 18 19 #include <vector> 20 21 #include "unwinder.h" 22 23 namespace OHOS { 24 namespace HiviewDFX { 25 struct TimeStampedPcs { 26 uint64_t snapshotTime {0}; 27 std::vector<uintptr_t> pcVec; 28 }; 29 30 struct SampledFrame { 31 uint32_t indent {0}; // the indent of this frame. 32 int32_t count {0}; // the count of this frame in the serial stacks. 33 uint32_t level {0}; // the level of this frame in its stack call chain. 34 uintptr_t pc {0}; // pc of this stack frame. 35 bool isLeaf {false}; // whether is leaf node in the tree format stack string. 36 std::vector<uint64_t> timestamps; // timestamps of this stack sampled. 37 38 friend std::ostream& operator<<(std::ostream& os, const SampledFrame& frame); 39 friend std::istream& operator>>(std::istream& is, SampledFrame& frame); 40 }; 41 42 class StackPrinter final { 43 public: 44 StackPrinter(); 45 StackPrinter(const StackPrinter& other) = delete; 46 StackPrinter& operator=(const StackPrinter& other) = delete; 47 48 /** 49 * @brief Initialize the unique_stack_table, which used to aggregation the stack pcs. 50 * 51 * @param pid the pid of the process. 52 * @param size the size of unique_stack_table to be initialized. 53 * @param name the name of unique_stack_table to be initialized, default unique_stack_table. 54 * @return return true if success, otherwise return false. 55 */ 56 bool InitUniqueTable(pid_t pid, uint32_t size, std::string name = "unique_stack_table"); 57 58 /** 59 * @brief Put the pcs into unique_stack_table to generate stackId. 60 * 61 * @param pcs the vector of the sampled stack pcs. 62 * @param tid the tid of the sampled thread. 63 * @param snapshotTime the timestamp of the stack sampled. 64 * @return return true if success, otherwise return false. 65 */ 66 bool PutPcsInTable(const std::vector<uintptr_t>& pcs, int tid, uint64_t snapshotTime); 67 68 /** 69 * @brief Set the unwind info to the StackPrinter. 70 * 71 * @param unwinder the shared_ptr of unwinder. 72 * @param maps the shared_ptr of process maps. 73 * @return void. 74 */ 75 void SetUnwindInfo(const std::shared_ptr<Unwinder>& unwinder, const std::shared_ptr<DfxMaps>& maps); 76 77 /** 78 * @brief Get the sampled stack string listed by time order. 79 * 80 * @param timeStampedPcsVec the vector of sampled stack pcs with its timestamp. 81 * @return the string of the sampled stack, listed by time order. 82 */ 83 std::string GetFullStack(const std::vector<TimeStampedPcs>& timeStampedPcsVec); 84 85 /** 86 * @brief Get the SampledFrames with tids into map, which can be serialize to bytes and deserialize back to map. 87 * 88 * @param beginTime the begin time of the time interval to filter the sampled stack, default 0. 89 * @param endTime the end time of the time interval to filter sampled stack, default 0. 90 * @return the map of the SampledFrame vector of each tid. 91 */ 92 std::map<int, std::vector<SampledFrame>> GetThreadSampledFrames(uint64_t beginTime = 0, uint64_t endTime = 0); 93 94 /** 95 * @brief the stack string of the sampled stack in tree format. 96 * 97 * @param tid the tid of sampled thread. 98 * @param printTimes whether to print the timestamps of the stack, default false. 99 * @param beginTime the begin time of the time interval to filter the sampled stack, default 0. 100 * @param endTime the end time of the time interval to filter sampled stack, default 0. 101 * @return the string of the sampled stack, formated in tree style. 102 */ 103 std::string GetTreeStack(int tid, bool printTimes = false, uint64_t beginTime = 0, uint64_t endTime = 0); 104 105 /** 106 * @brief Get the heaviest stack string of the tree format stack. 107 * 108 * @param tid the tid of the sampled thread. 109 * @param beginTime the begin time of the time interval to filter the sampled stack, default 0. 110 * @param endTime the end time of the time interval to filter sampled stack, default 0. 111 * @return the string of the heaviest sampled stack. 112 */ 113 std::string GetHeaviestStack(int tid, uint64_t beginTime = 0, uint64_t endTime = 0); 114 115 /** 116 * @brief Print the sampled stack to tree format string from the vector of struct SampledFrame. 117 * 118 * @param sampledFrameVec the SampledFrame vector of sampled stack. 119 * @param printTimes whether to print the timestamps of the stack, default false. 120 * @param unwinder the unwinder to unwind stacks. 121 * @param maps the maps of the process. 122 * @return the string of the sampled stack, formated in tree style. 123 */ 124 static std::string PrintTreeStackBySampledStack(const std::vector<SampledFrame>& sampledFrameVec, bool printTimes, 125 const std::shared_ptr<Unwinder>& unwinder, 126 const std::shared_ptr<DfxMaps>& maps); 127 128 /** 129 * @brief Serialize the sampled stack frames of each tid map by ostream. 130 * 131 * @param sampledFrameMap the map of the SampledFrame vector of each tid. 132 * @param os the ostream to do serialize. 133 * @return void. 134 */ 135 static void SerializeSampledFrameMap(const std::map<int, std::vector<SampledFrame>>& sampledFrameMap, 136 std::ostream& os); 137 138 /** 139 * @brief Deserialize the sampled stack frames of tid to map by istream. 140 * 141 * @param is the istream to do deserialize 142 * @return the map of the SampledFrame vector of each tid. 143 */ 144 static std::map<int, std::vector<SampledFrame>> DeserializeSampledFrameMap(std::istream& is); 145 146 private: 147 class Impl; 148 std::shared_ptr<Impl> impl_; 149 }; 150 } // end of namespace HiviewDFX 151 } // end of namespace OHOS 152 #endif 153