1 /* 2 * Copyright (c) 2021 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 #ifndef SEGMENT_ANALYSIS_TWOLAYERS_H 16 #define SEGMENT_ANALYSIS_TWOLAYERS_H 17 #include <functional> 18 #include <unordered_map> 19 20 #include "segment_analysis.h" 21 namespace OHOS { 22 namespace HiviewDFX { 23 namespace { 24 static const std::string SEGMENT_STATUS = "segStatus"; 25 static const std::string SEGMENT_PARENT_ID = "parentId"; 26 static const std::string SEGMENT_EXTRACTED = "extracted"; 27 static const std::string SEGMENT_IPC_INFO = "ipcInfo"; 28 static const std::string SEGMENT_IPC_THREAD = "Binder:"; 29 static const std::string SEGMENT_DEFAULT_THD_NAME = "main"; 30 static const std::string SEGMENT_CMD_LAYER_TWO = "LayerTwoCmd"; 31 static const std::string SEGMENT_CMD_IPC = "IpcCmd"; 32 static const std::string SEGMENT_WAIT_OTHER = "segWaitOther"; 33 static const std::string SEGMENT_IPC_TRANS = "segIpcTrans"; 34 static const std::string SEGMENT_IPC_FULL = "segIpcFull"; 35 static const std::string REASON_THREAD_TIMEOUT = "THREAD_TIMEOUT"; 36 static const std::string REASON_IPC_TIMEOUT = "IPC_TIMEOUT"; 37 static const std::string REASON_IPC_FULL = "IPC_FULL"; 38 static const std::string REASON_DEAD_LOCK = "DEAD_LOCK"; 39 static const std::string DEFAULT_LAYER_TWO_STACK_MATCH = "^\\s+at\\s+|^\\s+-\\s\\w"; 40 } 41 // analyze two-layers segments, such as appfreeze 42 using NextHandle = std::function<bool(int, UniqSegment&, UniqSegment&)>; 43 struct PairHash { 44 template<class T1, class T2> operatorPairHash45 std::size_t operator() (const std::pair<T1, T2>& p) const 46 { 47 auto h1 = std::hash<T1>()(p.first); 48 auto h2 = std::hash<T2>()(p.second); 49 return h1 ^ h2; 50 } 51 }; 52 class SegmentAnalysisTwoLayers : public SegmentAnalysis { 53 public: 54 SegmentAnalysisTwoLayers(); ~SegmentAnalysisTwoLayers()55 ~SegmentAnalysisTwoLayers() override {} 56 SegmentAnalysisTwoLayers(const SegmentAnalysisTwoLayers&) = delete; 57 SegmentAnalysisTwoLayers& operator=(const SegmentAnalysisTwoLayers&) = delete; 58 SegmentAnalysisTwoLayers(SegmentAnalysisTwoLayers&&) = delete; 59 SegmentAnalysisTwoLayers& operator=(SegmentAnalysisTwoLayers&&) = delete; 60 61 protected: 62 bool CheckParam(const ParamFeature& feature, const std::vector<std::string>& startSeg) const override; 63 void RecordOtherSegment(const ParamFeature& feature, 64 int layerOneId, ParamFeatureIter begin, ParamFeatureIter end) override; 65 bool GetStartSegment(const std::vector<std::string>& startSeg) override; NeedAnalyzeBlockedChain(void)66 bool NeedAnalyzeBlockedChain(void) const override 67 { 68 return true; 69 } 70 void AnalyzeBlockedChain() override; 71 void GetBlockedChain(void) override; 72 void GetEndStack(const std::vector<std::string>& segStack) override; 73 74 private: SetCurLayerOneSegmentId(int id)75 void SetCurLayerOneSegmentId(int id) 76 { 77 curLayerOneSegId_ = id; 78 } 79 void AddSegment(UniqSegment& seg); 80 bool GetSegment(const std::pair<std::string, std::string>& key, UniqSegment& seg); // key: pair(pname, tname) 81 bool GetSegment(const std::pair<int, int>& key, UniqSegment& seg); // key: pair(pid, tid) 82 bool GetSegmentBySysTid(const std::pair<int, int>& key, UniqSegment& seg); // key: pair(pid, sysTid) 83 void RecordLayerTwoSegment(const ParamFeature& feature, ParamFeatureIter begin, ParamFeatureIter end); 84 void RecordIpcSegment(const ParamFeature& feature); 85 bool HasNextSegment(const UniqSegment& seg) const; 86 bool GetNextSegWaitOther(int pid, const UniqSegment& seg, UniqSegment& nextSeg); 87 bool GetNextSegIpcTrans(int pid, UniqSegment& seg, UniqSegment& nextSeg); 88 void ExtractSegment(UniqSegment& seg); 89 bool GetFirstBlockedIpcSeg(int pid, UniqSegment& seg); 90 bool GetNextSegIpcFull(int pid, const UniqSegment& seg, UniqSegment& nextSeg); 91 bool GetNextSegment(UniqSegment& seg, UniqSegment& nextSeg); 92 bool NextSegHasAnalyzed(const UniqSegment& seg, Segment*& retSeg) const; 93 std::string GetOriginalInfo(int cursor); 94 95 int curLayerOneSegId_ {-1}; 96 bool isIpcBuilded_ {false}; 97 UniqSegment ipcSeg_; 98 std::unordered_map<std::pair<int, int>, UniqSegment, PairHash> pairMap_; // key: pair(pid, tid) 99 // tuple: pid pname tid tname systid, store segment info by their order in log file 100 std::vector<std::tuple<int, std::string, int, std::string, int>> segInfoVec_; 101 std::vector<std::pair<std::string, NextHandle>> nextHandleVec_; 102 std::vector<UniqSegment> blockedSegVec_; 103 static constexpr int LAYER_TWO_CMD_PARAM_NUM = 3; 104 static constexpr int TUPLE_IDX_PID = 0; 105 static constexpr int TUPLE_IDX_PNAME = 1; 106 static constexpr int TUPLE_IDX_TID = 2; 107 static constexpr int TUPLE_IDX_TNAME = 3; 108 static constexpr int TUPLE_IDX_SYSTID = 4; 109 static constexpr size_t SEGMENT_MAX_BLOCKED_NUM = 16; 110 }; 111 } // namespace HiviewDFX 112 } // namespace OHOS 113 #endif /* SEGMENT_ANALYSIS_TWOLAYERS_H */ 114