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 DECORATIVE_DUMP_INFO_H 17 #define DECORATIVE_DUMP_INFO_H 18 #include <cinttypes> 19 #include <memory> 20 #include <set> 21 #include <vector> 22 #include "dfx_dump_request.h" 23 #include "dfx_process.h" 24 #include "dump_info.h" 25 #include "dump_info_factory.h" 26 #include "unwinder.h" 27 namespace OHOS { 28 namespace HiviewDFX { 29 #if defined(__arm__) 30 const uint64_t STEP = 4; 31 #define PRINT_FORMAT "%08x" 32 #elif defined(__aarch64__) 33 const uint64_t STEP = 8; 34 #define PRINT_FORMAT "%016llx" 35 #else 36 const uint64_t STEP = 8; 37 #define PRINT_FORMAT "%016llx" 38 #endif 39 class DecorativeDumpInfo : public DumpInfo { 40 public: SetDumpInfo(const std::shared_ptr<DumpInfo> & dumpInfo)41 void SetDumpInfo(const std::shared_ptr<DumpInfo>& dumpInfo) override 42 { 43 dumpInfo_ = dumpInfo; 44 } 45 Print(DfxProcess & process,const ProcessDumpRequest & request,Unwinder & unwinder)46 void Print(DfxProcess& process, const ProcessDumpRequest& request, Unwinder& unwinder) override 47 { 48 if (dumpInfo_ != nullptr) { 49 dumpInfo_->Print(process, request, unwinder); 50 } 51 } 52 UnwindStack(DfxProcess & process,const ProcessDumpRequest & request,Unwinder & unwinder)53 int UnwindStack(DfxProcess& process, const ProcessDumpRequest& request, Unwinder& unwinder) override 54 { 55 if (dumpInfo_ != nullptr) { 56 return dumpInfo_->UnwindStack(process, request, unwinder); 57 } 58 return 0; 59 } 60 Symbolize(DfxProcess & process,Unwinder & unwinder)61 void Symbolize(DfxProcess& process, Unwinder& unwinder) override 62 { 63 if (dumpInfo_ != nullptr) { 64 dumpInfo_->Symbolize(process, unwinder); 65 } 66 } 67 GetMemoryValues(std::set<uintptr_t> & memoryValues)68 void GetMemoryValues(std::set<uintptr_t>& memoryValues) override 69 { 70 if (dumpInfo_ != nullptr) { 71 return dumpInfo_->GetMemoryValues(memoryValues); 72 } 73 } 74 protected: 75 std::shared_ptr<DumpInfo> dumpInfo_ = nullptr; 76 }; 77 78 class DumpInfoHeader : public DecorativeDumpInfo { 79 public: 80 void Print(DfxProcess& process, const ProcessDumpRequest& request, Unwinder& unwinder) override; CreateInstance()81 static std::shared_ptr<DumpInfo> CreateInstance() { return std::make_shared<DumpInfoHeader>(); } 82 private: 83 std::string GetReasonInfo(const ProcessDumpRequest& request, DfxProcess& process, DfxMaps& maps); 84 std::string GetCrashLogConfigInfo(const ProcessDumpRequest& request, DfxProcess& process); 85 std::string GetLastFatalMsg(DfxProcess& process, const ProcessDumpRequest& request); 86 std::string UpdateFatalMessageWhenDebugSignal(DfxProcess& process, const ProcessDumpRequest& request); 87 std::string ReadCrashObjString(const ProcessDumpRequest& request) const; 88 }; 89 90 class SubmitterStack : public DecorativeDumpInfo { 91 public: 92 void Print(DfxProcess& process, const ProcessDumpRequest& request, Unwinder& unwinder) override; CreateInstance()93 static std::shared_ptr<DumpInfo> CreateInstance() { return std::make_shared<SubmitterStack>(); } 94 private: 95 void GetSubmitterStack(pid_t tid, uint64_t stackId, Unwinder& unwinder, 96 std::vector<DfxFrame>& submitterFrames); 97 }; 98 99 class Registers : public DecorativeDumpInfo { 100 public: 101 void Print(DfxProcess& process, const ProcessDumpRequest& request, Unwinder& unwinder) override; CreateInstance()102 static std::shared_ptr<DumpInfo> CreateInstance() { return std::make_shared<Registers>(); } 103 }; 104 105 class ExtraCrashInfo : public DecorativeDumpInfo { 106 public: 107 void Print(DfxProcess& process, const ProcessDumpRequest& request, Unwinder& unwinder) override; CreateInstance()108 static std::shared_ptr<DumpInfo> CreateInstance() { return std::make_shared<ExtraCrashInfo>(); } 109 private: 110 std::string GetCrashObjContent(DfxProcess& process, const ProcessDumpRequest& request); 111 std::string ReadCrashObjMemory(pid_t tid, uintptr_t addr, size_t length) const; 112 }; 113 114 class OtherThreadDumpInfo : public DecorativeDumpInfo { 115 public: 116 int UnwindStack(DfxProcess& process, const ProcessDumpRequest& request, Unwinder& unwinder) override; 117 void Print(DfxProcess& process, const ProcessDumpRequest& request, Unwinder& unwinder) override; 118 void Symbolize(DfxProcess& process, Unwinder& unwinder) override; CreateInstance()119 static std::shared_ptr<DumpInfo> CreateInstance() { return std::make_shared<OtherThreadDumpInfo>(); } 120 }; 121 122 struct MemoryBlockInfo { 123 uintptr_t startAddr; 124 uintptr_t nameAddr; 125 uintptr_t size; 126 std::vector<uintptr_t> content; 127 std::string name; 128 }; 129 130 class MemoryNearRegister : public DecorativeDumpInfo { 131 public: 132 void Print(DfxProcess& process, const ProcessDumpRequest& request, Unwinder& unwinder) override; CreateInstance()133 static std::shared_ptr<DumpInfo> CreateInstance() { return std::make_shared<MemoryNearRegister>(); } 134 void GetMemoryValues(std::set<uintptr_t>& memoryValues) override; 135 private: 136 void CollectRegistersBlock(pid_t tid, std::shared_ptr<DfxRegs> regs, 137 std::shared_ptr<DfxMaps> maps, bool extendPcLrPrinting); 138 void CreateMemoryBlock(pid_t tid, MemoryBlockInfo& blockInfo) const; 139 std::vector<MemoryBlockInfo> registerBlocks_; 140 }; 141 142 class FaultStack : public DecorativeDumpInfo { 143 public: 144 void Print(DfxProcess& process, const ProcessDumpRequest& request, Unwinder& unwinder) override; 145 void CollectStackInfo(pid_t tid, const std::vector<DfxFrame>& frames, bool needParseStack = false); CreateInstance()146 static std::shared_ptr<DumpInfo> CreateInstance() { return std::make_shared<FaultStack>(); } 147 const std::vector<uintptr_t>& GetStackValues(); 148 void GetMemoryValues(std::set<uintptr_t>& memoryValues) override; 149 private: 150 bool CreateBlockForCorruptedStack(pid_t tid, const std::vector<DfxFrame>& frames, 151 uintptr_t prevEndAddr, uintptr_t size); 152 uintptr_t AdjustAndCreateMemoryBlock(pid_t tid, size_t index, uintptr_t prevSp, 153 uintptr_t prevEndAddr, uintptr_t size); 154 uintptr_t PrintMemoryBlock(const MemoryBlockInfo& info, uintptr_t stackStartAddr) const; 155 void CreateMemoryBlock(pid_t tid, MemoryBlockInfo& blockInfo) const; 156 std::vector<MemoryBlockInfo> blocks_; 157 std::vector<uintptr_t> stackValues_; 158 }; 159 160 class Maps : public DecorativeDumpInfo { 161 public: 162 void Print(DfxProcess& process, const ProcessDumpRequest& request, Unwinder& unwinder) override; CreateInstance()163 static std::shared_ptr<DumpInfo> CreateInstance() { return std::make_shared<Maps>(); } 164 private: 165 void SimplifyVma(DfxProcess& process, const ProcessDumpRequest& request, 166 const std::shared_ptr<DfxMaps>& maps, std::set<DfxMap>& mapSet); 167 }; 168 169 struct FDInfo { 170 std::string path; 171 uint64_t fdsanOwner; 172 }; 173 using OpenFilesList = std::map<int, FDInfo>; 174 class OpenFiles : public DecorativeDumpInfo { 175 public: 176 void Print(DfxProcess& process, const ProcessDumpRequest& request, Unwinder& unwinder) override; CreateInstance()177 static std::shared_ptr<DumpInfo> CreateInstance() { return std::make_shared<OpenFiles>(); } 178 private: 179 bool ReadLink(std::string &src, std::string &dst); 180 void CollectOpenFiles(OpenFilesList &list, pid_t pid); 181 void FillFdsaninfo(OpenFilesList &list, pid_t nsPid, uint64_t fdTableAddr); 182 std::string DumpOpenFiles(OpenFilesList files); 183 }; 184 } // namespace HiviewDFX 185 } // namespace OHOS 186 #endif 187