From aaed202746b15971fee937f722035644ad7160e7 Mon Sep 17 00:00:00 2001 From: wangqing Date: Mon, 18 Nov 2024 11:09:27 +0800 Subject: [PATCH 01/13] =?UTF-8?q?DfxConfig::ParserConfig=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wangqing Change-Id: I200519b42fa29c2944e2fbec9d1ca13c2266aed4 --- interfaces/innerkits/unwinder/dfx_config.cpp | 102 ++++++------------ .../innerkits/unwinder/include/dfx_config.h | 6 +- services/config/faultlogger.conf | 2 +- 3 files changed, 34 insertions(+), 76 deletions(-) diff --git a/interfaces/innerkits/unwinder/dfx_config.cpp b/interfaces/innerkits/unwinder/dfx_config.cpp index 57c4c7c9..c1ad5325 100644 --- a/interfaces/innerkits/unwinder/dfx_config.cpp +++ b/interfaces/innerkits/unwinder/dfx_config.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -34,6 +35,17 @@ namespace { const char FAULTLOGGER_CONF_PATH[] = "/system/etc/faultlogger.conf"; const int CONF_LINE_SIZE = 256; + +auto boolConfigParser = [](bool* configProp, const std::string& value) { + *configProp = (value != "false"); +}; + +auto uintConfigParser = [](unsigned int* configProp, const std::string& value) { + unsigned int propValue = static_cast(atoi(value.data())); + if (propValue != 0) { + *configProp = propValue; + } +}; } DfxConfigInfo& DfxConfig::GetConfig() @@ -41,87 +53,33 @@ DfxConfigInfo& DfxConfig::GetConfig() static DfxConfigInfo config; static std::once_flag flag; std::call_once(flag, [&] { - ReadConfig(config); + ReadAndParseConfig(config); }); return config; } -void DfxConfig::ParserConfig(DfxConfigInfo& config, const std::string& key, const std::string& value) -{ - do { - if (key.compare("displayRigister") == 0) { - if (value.compare("false") == 0) { - config.displayRegister = false; - } else { - config.displayRegister = true; - } - break; - } - if (key.compare("displayBacktrace") == 0) { - if (value.compare("false") == 0) { - config.displayBacktrace = false; - } else { - config.displayBacktrace = true; - } - break; - } - if (key.compare("displayMaps") == 0) { - if (value.compare("false") == 0) { - config.displayMaps = false; - } else { - config.displayMaps = true; - } - break; - } - if (key.compare("displayFaultStack.switch") == 0) { - if (value.compare("false") == 0) { - config.displayFaultStack = false; - } else { - config.displayFaultStack = true; - } - break; - } - if (key.compare("dumpOtherThreads") == 0) { - if (value.compare("false") == 0) { - config.dumpOtherThreads = false; - } else { - config.dumpOtherThreads = true; - } - break; - } - if (key.compare("displayFaultStack.lowAddressStep") == 0) { - unsigned int lowAddressStep = static_cast(atoi(value.data())); - if (lowAddressStep != 0) { - config.lowAddressStep = lowAddressStep; - } - break; - } - if (key.compare("displayFaultStack.highAddressStep") == 0) { - unsigned int highAddressStep = static_cast(atoi(value.data())); - if (highAddressStep != 0) { - config.highAddressStep = highAddressStep; - } - break; - } - if (key.compare("maxFrameNums") == 0) { - unsigned int maxFrameNums = static_cast(atoi(value.data())); - if (maxFrameNums != 0) { - config.maxFrameNums = maxFrameNums; - } - break; - } - } while (0); -} - -void DfxConfig::ReadConfig(DfxConfigInfo& config) +void DfxConfig::ReadAndParseConfig(DfxConfigInfo& config) { do { FILE *fp = nullptr; char codeBuffer[CONF_LINE_SIZE] = {0}; fp = fopen(FAULTLOGGER_CONF_PATH, "r"); if (fp == nullptr) { + DFXLOGW("Failed to open %{public}s. Reason: %{public}s.", FAULTLOGGER_CONF_PATH, strerror(errno)); break; } + std::map boolConfig = { + {std::string("displayRegister"), &(config.displayRegister)}, + {std::string("displayBacktrace"), &(config.displayBacktrace)}, + {std::string("displayMaps"), &(config.displayMaps)}, + {std::string("displayFaultStack.switch"), &(config.displayFaultStack)}, + {std::string("dumpOtherThreads"), &(config.dumpOtherThreads)}, + }; + std::map uintConfig = { + {std::string("displayFaultStack.lowAddressStep"), &(config.lowAddressStep)}, + {std::string("displayFaultStack.highAddressStep"), &(config.highAddressStep)}, + {std::string("maxFrameNums"), &(config.maxFrameNums)}, + }; while (!feof(fp)) { (void)memset_s(codeBuffer, sizeof(codeBuffer), '\0', sizeof(codeBuffer)); if (fgets(codeBuffer, CONF_LINE_SIZE - 1, fp) == nullptr) { @@ -138,7 +96,11 @@ void DfxConfig::ReadConfig(DfxConfigInfo& config) std::string value = line.substr(equalSignPos + 1); Trim(key); Trim(value); - ParserConfig(config, key, value); + if (boolConfig.find(key) != boolConfig.end()) { + boolConfigParser(boolConfig[key], value); + } else if (uintConfig.find(key) != uintConfig.end()) { + uintConfigParser(uintConfig[key], value); + } } } (void)fclose(fp); diff --git a/interfaces/innerkits/unwinder/include/dfx_config.h b/interfaces/innerkits/unwinder/include/dfx_config.h index 2d2ce514..05cce65b 100644 --- a/interfaces/innerkits/unwinder/include/dfx_config.h +++ b/interfaces/innerkits/unwinder/include/dfx_config.h @@ -15,8 +15,6 @@ #ifndef DFX_CONFIG_H #define DFX_CONFIG_H -#include - namespace OHOS { namespace HiviewDFX { struct DfxConfigInfo { @@ -33,10 +31,8 @@ struct DfxConfigInfo { class DfxConfig { public: static DfxConfigInfo& GetConfig(); - private: - static void ReadConfig(DfxConfigInfo& config); - static void ParserConfig(DfxConfigInfo& config, const std::string& key, const std::string& value); + static void ReadAndParseConfig(DfxConfigInfo& config); private: DfxConfig() = default; ~DfxConfig() = default; diff --git a/services/config/faultlogger.conf b/services/config/faultlogger.conf index 45d72e29..6d7e8bf2 100644 --- a/services/config/faultlogger.conf +++ b/services/config/faultlogger.conf @@ -1,4 +1,4 @@ -displayRigister=true +displayRegister=true displayBacktrace=true displayMaps=true dumpOtherThreads=true -- Gitee From 55ac2fc98641f695a25657456bb5f6ac3e82730f Mon Sep 17 00:00:00 2001 From: wangqing Date: Tue, 29 Oct 2024 11:29:03 +0800 Subject: [PATCH 02/13] =?UTF-8?q?ElfParser::ParseSectionHeaders=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wangqing Change-Id: I8b00dbcb4062b5d697ce82e10ada8939c86435c2 --- .../innerkits/unwinder/dfx_elf_parser.cpp | 55 +++++++++++-------- .../unwinder/include/dfx_elf_parser.h | 2 + 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/interfaces/innerkits/unwinder/dfx_elf_parser.cpp b/interfaces/innerkits/unwinder/dfx_elf_parser.cpp index 5078801a..a1597c2d 100644 --- a/interfaces/innerkits/unwinder/dfx_elf_parser.cpp +++ b/interfaces/innerkits/unwinder/dfx_elf_parser.cpp @@ -169,31 +169,9 @@ std::shared_ptr ElfParser::GetMiniDebugInfo() } template -bool ElfParser::ParseSectionHeaders(const EhdrType& ehdr) +bool ElfParser::ExtractSectionHeadersInfo(const EhdrType& ehdr, ShdrType& shdr) { uint64_t offset = ehdr.e_shoff; - - ShdrType shdr; - //section header string table index. include section header table with section name string table. - if (ehdr.e_shstrndx < ehdr.e_shnum) { - uint64_t secOffset = 0; - uint64_t secSize = 0; - uint64_t shNdxOffset = offset + ehdr.e_shstrndx * ehdr.e_shentsize; - if (!Read((uintptr_t)shNdxOffset, &shdr, sizeof(shdr))) { - DFXLOGE("Read section header string table failed"); - return false; - } - secOffset = shdr.sh_offset; - secSize = shdr.sh_size; - if (!ParseStrTab(sectionNames_, secOffset, secSize)) { - return false; - } - } else { - DFXLOGE("e_shstrndx(%{public}u) cannot greater than or equal e_shnum(%{public}u)", - ehdr.e_shstrndx, ehdr.e_shnum); - return false; - } - offset += ehdr.e_shentsize; for (size_t i = 1; i < ehdr.e_shnum; i++, offset += ehdr.e_shentsize) { if (i == ehdr.e_shstrndx) { @@ -243,6 +221,37 @@ bool ElfParser::ParseSectionHeaders(const EhdrType& ehdr) return true; } +template +bool ElfParser::ParseSectionHeaders(const EhdrType& ehdr) +{ + ShdrType shdr; + //section header string table index. include section header table with section name string table. + if (ehdr.e_shstrndx < ehdr.e_shnum) { + uint64_t secOffset = 0; + uint64_t secSize = 0; + uint64_t shNdxOffset = ehdr.e_shoff + ehdr.e_shstrndx * ehdr.e_shentsize; + if (!Read((uintptr_t)shNdxOffset, &shdr, sizeof(shdr))) { + DFXLOGE("Read section header string table failed"); + return false; + } + secOffset = shdr.sh_offset; + secSize = shdr.sh_size; + if (!ParseStrTab(sectionNames_, secOffset, secSize)) { + return false; + } + } else { + DFXLOGE("e_shstrndx(%{public}u) cannot greater than or equal e_shnum(%{public}u)", + ehdr.e_shstrndx, ehdr.e_shnum); + return false; + } + + if(!ExtractSectionHeadersInfo(ehdr, shdr)) { + return false; + } + + return true; +} + template bool ElfParser::ParseElfDynamic() { diff --git a/interfaces/innerkits/unwinder/include/dfx_elf_parser.h b/interfaces/innerkits/unwinder/include/dfx_elf_parser.h index 43be1c5a..8a7a3fc3 100644 --- a/interfaces/innerkits/unwinder/include/dfx_elf_parser.h +++ b/interfaces/innerkits/unwinder/include/dfx_elf_parser.h @@ -71,6 +71,8 @@ protected: template bool ParseProgramHeaders(const EhdrType& ehdr); template + bool ExtractSectionHeadersInfo(const EhdrType& ehdr, ShdrType& shdr); + template bool ParseSectionHeaders(const EhdrType& ehdr); template bool IsFunc(const SymType sym); -- Gitee From 17a8ded4d7b51fa9d9f81a5f6556fe6f9671e391 Mon Sep 17 00:00:00 2001 From: wangqing Date: Tue, 29 Oct 2024 12:03:33 +0800 Subject: [PATCH 03/13] =?UTF-8?q?ArmExidx::ExtractEntryTab=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wangqing Change-Id: I5f40544eefc0e3f63f5f8de3082804b06add8edd --- interfaces/innerkits/unwinder/arm_exidx.cpp | 27 ++++++++++++------- .../innerkits/unwinder/include/arm_exidx.h | 1 + 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/interfaces/innerkits/unwinder/arm_exidx.cpp b/interfaces/innerkits/unwinder/arm_exidx.cpp index 9be5c52f..b09ac8e8 100644 --- a/interfaces/innerkits/unwinder/arm_exidx.cpp +++ b/interfaces/innerkits/unwinder/arm_exidx.cpp @@ -241,16 +241,8 @@ bool ArmExidx::ExtractEntryData(uintptr_t entryOffset) return ExtractEntryTab(extabAddr); } -bool ArmExidx::ExtractEntryTab(uintptr_t tabOffset) +bool ArmExidx::ExtractEntryTabByPersonality(uintptr_t& tabOffset, uint32_t& data, uint8_t& tableCount) { - uint32_t data = 0; - DFXLOGU("Exidx tabOffset: %{public}llx", (uint64_t)tabOffset); - if (!memory_->ReadU32(tabOffset, &data, false)) { - lastErrorData_.SetAddrAndCode(tabOffset, UNW_ERROR_INVALID_MEMORY); - return false; - } - - uint8_t tableCount = 0; if ((data & ARM_EXIDX_COMPACT) == 0) { DFXLOGU("Arm generic personality, data: %{public}x.", data); #ifndef TEST_ARM_EXIDX @@ -297,6 +289,23 @@ bool ArmExidx::ExtractEntryTab(uintptr_t tabOffset) ops_.push_back((data >> EIGHT_BIT_OFFSET) & 0xff); ops_.push_back(data & 0xff); } + return true; +} + +bool ArmExidx::ExtractEntryTab(uintptr_t tabOffset) +{ + uint32_t data = 0; + DFXLOGU("Exidx tabOffset: %{public}llx", (uint64_t)tabOffset); + if (!memory_->ReadU32(tabOffset, &data, false)) { + lastErrorData_.SetAddrAndCode(tabOffset, UNW_ERROR_INVALID_MEMORY); + return false; + } + + uint8_t tableCount = 0; + if (!ExtractEntryTabByPersonality(tabOffset, data, tableCount)) { + return false; + } + if (tableCount > 5) { // 5 : 5 operators lastErrorData_.SetCode(UNW_ERROR_NOT_SUPPORT); return false; diff --git a/interfaces/innerkits/unwinder/include/arm_exidx.h b/interfaces/innerkits/unwinder/include/arm_exidx.h index 879ae7f4..762db1a7 100644 --- a/interfaces/innerkits/unwinder/include/arm_exidx.h +++ b/interfaces/innerkits/unwinder/include/arm_exidx.h @@ -62,6 +62,7 @@ private: void LogRawData(); bool ExtractEntryData(uintptr_t entryOffset); bool ExtractEntryTab(uintptr_t tabOffset); + bool ExtractEntryTabByPersonality(uintptr_t& tabOffset, uint32_t& data, uint8_t& tableCount); bool GetOpCode(); bool Decode(DecodeTable decodeTable[], size_t size); bool Decode00xxxxxx(); -- Gitee From f016b7d7c4d824fff815b987ba7cfee4af6dcac8 Mon Sep 17 00:00:00 2001 From: wangqing Date: Tue, 12 Nov 2024 11:29:13 +0800 Subject: [PATCH 04/13] =?UTF-8?q?DfxElf::DlPhdrCb=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wangqing Change-Id: I25834c60e1fcb66a21f8a5b61edd28bc80f1d7b2 --- interfaces/innerkits/unwinder/dfx_elf.cpp | 121 +++++++++++------- .../innerkits/unwinder/include/dfx_elf.h | 4 + 2 files changed, 80 insertions(+), 45 deletions(-) diff --git a/interfaces/innerkits/unwinder/dfx_elf.cpp b/interfaces/innerkits/unwinder/dfx_elf.cpp index 975450c7..2b1687ea 100644 --- a/interfaces/innerkits/unwinder/dfx_elf.cpp +++ b/interfaces/innerkits/unwinder/dfx_elf.cpp @@ -865,53 +865,107 @@ bool DfxElf::FindSection(struct dl_phdr_info *info, const std::string secName, S return elf->GetSectionInfo(shdr, secName); } -int DfxElf::DlPhdrCb(struct dl_phdr_info *info, size_t size, void *data) +void DfxElf::ParsePhdr(struct dl_phdr_info *info, std::vector& pHdrSections, const uintptr_t pc) { - struct DlCbData *cbData = (struct DlCbData *)data; - if ((info == nullptr) || (cbData == nullptr)) { - return -1; + for(auto& section : pHdrSections) { + section = nullptr; } - UnwindTableInfo* uti = &cbData->uti; - uintptr_t pc = cbData->pc; - const ElfW(Phdr) *pText = nullptr; - const ElfW(Phdr) *pDynamic = nullptr; -#if defined(__arm__) - const ElfW(Phdr) *pArmExidx = nullptr; -#endif - const ElfW(Phdr) *pEhHdr = nullptr; - const ElfW(Phdr) *phdr = info->dlpi_phdr; - ElfW(Addr) loadBase = info->dlpi_addr; for (size_t i = 0; i < info->dlpi_phnum && phdr != nullptr; i++, phdr++) { switch (phdr->p_type) { case PT_LOAD: { - ElfW(Addr) vaddr = phdr->p_vaddr + loadBase; + ElfW(Addr) vaddr = phdr->p_vaddr + info->dlpi_addr; if (pc >= vaddr && pc < vaddr + phdr->p_memsz) { - pText = phdr; + // .text section + pHdrSections[0] = phdr; } break; } #if defined(__arm__) case PT_ARM_EXIDX: { - pArmExidx = phdr; + // .arm_exidx section + pHdrSections[1] = phdr; break; } #endif case PT_GNU_EH_FRAME: { - pEhHdr = phdr; + // .dynamic section + pHdrSections[2] = phdr; break; } case PT_DYNAMIC: { - pDynamic = phdr; + // .eh_frame_hdr section + pHdrSections[3] = phdr; break; } default: break; } } +} + +bool DfxElf::ProccessDynamic(const ElfW(Phdr) *pDynamic, ElfW(Addr) loadBase, UnwindTableInfo *uti) +{ + ElfW(Dyn) *dyn = (ElfW(Dyn) *)(pDynamic->p_vaddr + loadBase); + if (dyn == nullptr) { + return false; + } + for (; dyn->d_tag != DT_NULL; ++dyn) { + if (dyn->d_tag == DT_PLTGOT) { + uti->gp = dyn->d_un.d_ptr; + break; + } + } + return true; +} + +void DfxElf::InitHdr(struct DwarfEhFrameHdr **hdr, struct DwarfEhFrameHdr& synthHdr, + struct dl_phdr_info *info, ElfW(Addr) loadBase, const ElfW(Phdr) *pEhHdr) +{ + if (pEhHdr) { + INSTR_STATISTIC(InstructionEntriesEhFrame, pEhHdr->p_memsz, 0); + *hdr = (struct DwarfEhFrameHdr *) (pEhHdr->p_vaddr + loadBase); + } else { + ShdrInfo shdr; + if (FindSection(info, EH_FRAME, shdr)) { + DFXLOGW("[%{public}d]: Elf(%{public}s) no found .eh_frame_hdr section, " \ + "using synthetic .eh_frame section", __LINE__, info->dlpi_name); + INSTR_STATISTIC(InstructionEntriesEhFrame, shdr.size, 0); + synthHdr.version = DW_EH_VERSION; + synthHdr.ehFramePtrEnc = DW_EH_PE_absptr | + ((sizeof(ElfW(Addr)) == 4) ? DW_EH_PE_udata4 : DW_EH_PE_udata8); // 4 : four bytes + synthHdr.fdeCountEnc = DW_EH_PE_omit; + synthHdr.tableEnc = DW_EH_PE_omit; + synthHdr.ehFrame = (ElfW(Addr))(shdr.addr + info->dlpi_addr); + *hdr = &synthHdr; + } + } +} + +int DfxElf::DlPhdrCb(struct dl_phdr_info *info, size_t size, void *data) +{ + struct DlCbData *cbData = (struct DlCbData *)data; + if ((info == nullptr) || (cbData == nullptr)) { + return -1; + } + UnwindTableInfo* uti = &cbData->uti; + uintptr_t pc = cbData->pc; + const int numOfPhdrSections = 4; + std::vector pHdrSections(numOfPhdrSections); + ParsePhdr(info, pHdrSections, pc); + + const ElfW(Phdr) *pText = pHdrSections[0]; +#if defined(__arm__) + const ElfW(Phdr) *pArmExidx = pHdrSections[1]; +#endif + const ElfW(Phdr) *pDynamic = pHdrSections[2]; + const ElfW(Phdr) *pEhHdr = pHdrSections[3]; + + if (pText == nullptr) { return 0; } + ElfW(Addr) loadBase = info->dlpi_addr; uti->startPc = pText->p_vaddr + loadBase; uti->endPc = uti->startPc + pText->p_memsz; DFXLOGU("Elf name: %{public}s", info->dlpi_name); @@ -927,40 +981,17 @@ int DfxElf::DlPhdrCb(struct dl_phdr_info *info, size_t size, void *data) #endif if (pDynamic) { - ElfW(Dyn) *dyn = (ElfW(Dyn) *)(pDynamic->p_vaddr + loadBase); - if (dyn == nullptr) { + if(!ProccessDynamic(pDynamic, loadBase, uti)) { return 0; } - for (; dyn->d_tag != DT_NULL; ++dyn) { - if (dyn->d_tag == DT_PLTGOT) { - uti->gp = dyn->d_un.d_ptr; - break; - } - } } else { uti->gp = 0; } struct DwarfEhFrameHdr *hdr = nullptr; struct DwarfEhFrameHdr synthHdr; - if (pEhHdr) { - INSTR_STATISTIC(InstructionEntriesEhFrame, pEhHdr->p_memsz, 0); - hdr = (struct DwarfEhFrameHdr *) (pEhHdr->p_vaddr + loadBase); - } else { - ShdrInfo shdr; - if (FindSection(info, EH_FRAME, shdr)) { - DFXLOGW("[%{public}d]: Elf(%{public}s) no found .eh_frame_hdr section, " \ - "using synthetic .eh_frame section", __LINE__, info->dlpi_name); - INSTR_STATISTIC(InstructionEntriesEhFrame, shdr.size, 0); - synthHdr.version = DW_EH_VERSION; - synthHdr.ehFramePtrEnc = DW_EH_PE_absptr | - ((sizeof(ElfW(Addr)) == 4) ? DW_EH_PE_udata4 : DW_EH_PE_udata8); // 4 : four bytes - synthHdr.fdeCountEnc = DW_EH_PE_omit; - synthHdr.tableEnc = DW_EH_PE_omit; - synthHdr.ehFrame = (ElfW(Addr))(shdr.addr + info->dlpi_addr); - hdr = &synthHdr; - } - } + InitHdr(&hdr, synthHdr, info, loadBase, pEhHdr); + return FillUnwindTableByEhhdrLocal(hdr, uti); } #endif diff --git a/interfaces/innerkits/unwinder/include/dfx_elf.h b/interfaces/innerkits/unwinder/include/dfx_elf.h index 2cf926c1..0b6bfda7 100644 --- a/interfaces/innerkits/unwinder/include/dfx_elf.h +++ b/interfaces/innerkits/unwinder/include/dfx_elf.h @@ -86,6 +86,10 @@ protected: bool InitEmbeddedElf(); #if is_ohos && !is_mingw static int DlPhdrCb(struct dl_phdr_info *info, size_t size, void *data); + static void ParsePhdr(struct dl_phdr_info *info, std::vector& pHdrSections, const uintptr_t pc); + static bool ProccessDynamic(const ElfW(Phdr) *pDynamic, ElfW(Addr) loadBase, UnwindTableInfo *uti); + static void InitHdr(struct DwarfEhFrameHdr **hdr, struct DwarfEhFrameHdr& synthHdr, + struct dl_phdr_info *info, ElfW(Addr) loadBase, const ElfW(Phdr) *pEhHdr); static bool FindSection(struct dl_phdr_info *info, const std::string secName, ShdrInfo& shdr); static bool FillUnwindTableByEhhdrLocal(struct DwarfEhFrameHdr* hdr, struct UnwindTableInfo* uti); #endif -- Gitee From ea70991a2ff17dc7b9d58264b94253422fc16949 Mon Sep 17 00:00:00 2001 From: wangqing Date: Sat, 26 Oct 2024 12:17:53 +0800 Subject: [PATCH 05/13] =?UTF-8?q?multi=5Fthread=5Fcontainer=5Faccess.cpp?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wangqing Change-Id: I208c37c7a7bd4688064b08cc61a223e961ddec67 --- .../faults/multi_thread_container_access.cpp | 75 ++++++++----------- 1 file changed, 32 insertions(+), 43 deletions(-) diff --git a/tools/crasher_cpp/faults/multi_thread_container_access.cpp b/tools/crasher_cpp/faults/multi_thread_container_access.cpp index a78ac655..577d8e87 100644 --- a/tools/crasher_cpp/faults/multi_thread_container_access.cpp +++ b/tools/crasher_cpp/faults/multi_thread_container_access.cpp @@ -30,18 +30,17 @@ static constexpr int MAP_INDEX_LEN = 10; static constexpr int MAX_LOOP_SIZE = 10000; static constexpr int THREAD_SIZE = 10; -int MultiThreadVectorAccess() +using TaskFunction = std::function)>; + +int MultiThreadAccess(const TaskFunction &manipulate) { auto testcase = std::make_shared(); testcase->Print(); std::vector threads; for (int i = 0; i < THREAD_SIZE; i++) { std::thread th( - [testcase] { - for (int i = 0; i < MAX_LOOP_SIZE; i++) { - testcase->ManipulateVector(); - } - testcase->Print(); + [testcase, manipulate] { + manipulate(testcase); }); threads.push_back(std::move(th)); } @@ -52,50 +51,40 @@ int MultiThreadVectorAccess() return 0; } -int MultiThreadMapAccess() +int MultiThreadVectorAccess() { - auto testcase = std::make_shared(); - testcase->Print(); - std::vector threads; - for (int i = 0; i < THREAD_SIZE; i++) { - std::thread th( - [testcase] { - for (int i = 0; i < MAX_LOOP_SIZE; i++) { - testcase->ManipulateMap(); - } - testcase->Print(); - }); - threads.push_back(std::move(th)); - } + auto multiThreadVectorAccess = [](std::shared_ptr testcase) { + for (int i = 0; i < MAX_LOOP_SIZE; i++) { + testcase->ManipulateVector(); + } + testcase->Print(); + }; + return MultiThreadAccess(multiThreadVectorAccess); +} - for (auto& th : threads) { - th.join(); - } - return 0; +int MultiThreadMapAccess() +{ + auto multiThreadMapAccess = [](std::shared_ptr testcase) { + for (int i = 0; i < MAX_LOOP_SIZE; i++) { + testcase->ManipulateMap(); + } + testcase->Print(); + }; + return MultiThreadAccess(multiThreadMapAccess); } int MultiThreadListAccess() { - auto testcase = std::make_shared(); - testcase->Print(); - std::vector threads; - for (int i = 0; i < THREAD_SIZE; i++) { - std::thread th( - [testcase] { - for (int i = 0; i < MAX_LOOP_SIZE; i++) { - // may crash inside loop - testcase->ManipulateList(); - testcase->Print(); - } - }); - threads.push_back(std::move(th)); - } - - for (auto& th : threads) { - th.join(); - } - return 0; + auto multiThreadListAccess = [](std::shared_ptr testcase) { + for (int i = 0; i < MAX_LOOP_SIZE; i++) { + // may crash inside loop + testcase->ManipulateList(); + testcase->Print(); + } + }; + return MultiThreadAccess(multiThreadListAccess); } + namespace OHOS { namespace HiviewDFX { std::string MultiThreadContainerAccess::GenerateStr() -- Gitee From 6aa1a303939882d7864deebc830607aa0ed4a3c1 Mon Sep 17 00:00:00 2001 From: wangqing Date: Mon, 18 Nov 2024 17:18:18 +0800 Subject: [PATCH 06/13] CleanCode Signed-off-by: wangqing Change-Id: I3c3ea8c3b8c53a5f6528781cf4c17ec1bb0f13a6 --- interfaces/innerkits/unwinder/dfx_config.cpp | 86 +++++++++---------- interfaces/innerkits/unwinder/dfx_elf.cpp | 7 +- .../innerkits/unwinder/dfx_elf_parser.cpp | 2 +- 3 files changed, 46 insertions(+), 49 deletions(-) diff --git a/interfaces/innerkits/unwinder/dfx_config.cpp b/interfaces/innerkits/unwinder/dfx_config.cpp index c1ad5325..0f50dd57 100644 --- a/interfaces/innerkits/unwinder/dfx_config.cpp +++ b/interfaces/innerkits/unwinder/dfx_config.cpp @@ -36,11 +36,11 @@ namespace { const char FAULTLOGGER_CONF_PATH[] = "/system/etc/faultlogger.conf"; const int CONF_LINE_SIZE = 256; -auto boolConfigParser = [](bool* configProp, const std::string& value) { +auto g_boolConfigParser = [](bool* configProp, const std::string& value) { *configProp = (value != "false"); }; -auto uintConfigParser = [](unsigned int* configProp, const std::string& value) { +auto g_uintConfigParser = [](unsigned int* configProp, const std::string& value) { unsigned int propValue = static_cast(atoi(value.data())); if (propValue != 0) { *configProp = propValue; @@ -60,51 +60,49 @@ DfxConfigInfo& DfxConfig::GetConfig() void DfxConfig::ReadAndParseConfig(DfxConfigInfo& config) { - do { - FILE *fp = nullptr; - char codeBuffer[CONF_LINE_SIZE] = {0}; - fp = fopen(FAULTLOGGER_CONF_PATH, "r"); - if (fp == nullptr) { - DFXLOGW("Failed to open %{public}s. Reason: %{public}s.", FAULTLOGGER_CONF_PATH, strerror(errno)); - break; + FILE *fp = nullptr; + char codeBuffer[CONF_LINE_SIZE] = {0}; + fp = fopen(FAULTLOGGER_CONF_PATH, "r"); + if (fp == nullptr) { + DFXLOGW("Failed to open %{public}s. Reason: %{public}s.", FAULTLOGGER_CONF_PATH, strerror(errno)); + return; + } + std::map boolConfig = { + {std::string("displayRegister"), &(config.displayRegister)}, + {std::string("displayBacktrace"), &(config.displayBacktrace)}, + {std::string("displayMaps"), &(config.displayMaps)}, + {std::string("displayFaultStack.switch"), &(config.displayFaultStack)}, + {std::string("dumpOtherThreads"), &(config.dumpOtherThreads)}, + }; + std::map uintConfig = { + {std::string("displayFaultStack.lowAddressStep"), &(config.lowAddressStep)}, + {std::string("displayFaultStack.highAddressStep"), &(config.highAddressStep)}, + {std::string("maxFrameNums"), &(config.maxFrameNums)}, + }; + while (!feof(fp)) { + (void)memset_s(codeBuffer, sizeof(codeBuffer), '\0', sizeof(codeBuffer)); + if (fgets(codeBuffer, CONF_LINE_SIZE - 1, fp) == nullptr) { + continue; } - std::map boolConfig = { - {std::string("displayRegister"), &(config.displayRegister)}, - {std::string("displayBacktrace"), &(config.displayBacktrace)}, - {std::string("displayMaps"), &(config.displayMaps)}, - {std::string("displayFaultStack.switch"), &(config.displayFaultStack)}, - {std::string("dumpOtherThreads"), &(config.dumpOtherThreads)}, - }; - std::map uintConfig = { - {std::string("displayFaultStack.lowAddressStep"), &(config.lowAddressStep)}, - {std::string("displayFaultStack.highAddressStep"), &(config.highAddressStep)}, - {std::string("maxFrameNums"), &(config.maxFrameNums)}, - }; - while (!feof(fp)) { - (void)memset_s(codeBuffer, sizeof(codeBuffer), '\0', sizeof(codeBuffer)); - if (fgets(codeBuffer, CONF_LINE_SIZE - 1, fp) == nullptr) { - continue; - } - std::string line(codeBuffer); - std::string::size_type newLinePos = line.find_first_of("\n"); - if (newLinePos != line.npos) { - line.resize(newLinePos); - } - std::string::size_type equalSignPos = line.find_first_of("="); - if (equalSignPos != line.npos) { - std::string key = line.substr(0, equalSignPos); - std::string value = line.substr(equalSignPos + 1); - Trim(key); - Trim(value); - if (boolConfig.find(key) != boolConfig.end()) { - boolConfigParser(boolConfig[key], value); - } else if (uintConfig.find(key) != uintConfig.end()) { - uintConfigParser(uintConfig[key], value); - } + std::string line(codeBuffer); + std::string::size_type newLinePos = line.find_first_of("\n"); + if (newLinePos != line.npos) { + line.resize(newLinePos); + } + std::string::size_type equalSignPos = line.find_first_of("="); + if (equalSignPos != line.npos) { + std::string key = line.substr(0, equalSignPos); + std::string value = line.substr(equalSignPos + 1); + Trim(key); + Trim(value); + if (boolConfig.find(key) != boolConfig.end()) { + g_boolConfigParser(boolConfig[key], value); + } else if (uintConfig.find(key) != uintConfig.end()) { + g_uintConfigParser(uintConfig[key], value); } } - (void)fclose(fp); - } while (0); + } + (void)fclose(fp); } } // namespace HiviewDFX } // namespace OHOS diff --git a/interfaces/innerkits/unwinder/dfx_elf.cpp b/interfaces/innerkits/unwinder/dfx_elf.cpp index 2b1687ea..b7bf5ff7 100644 --- a/interfaces/innerkits/unwinder/dfx_elf.cpp +++ b/interfaces/innerkits/unwinder/dfx_elf.cpp @@ -865,9 +865,9 @@ bool DfxElf::FindSection(struct dl_phdr_info *info, const std::string secName, S return elf->GetSectionInfo(shdr, secName); } -void DfxElf::ParsePhdr(struct dl_phdr_info *info, std::vector& pHdrSections, const uintptr_t pc) +void DfxElf::ParsePhdr(struct dl_phdr_info *info, std::vector &pHdrSections, const uintptr_t pc) { - for(auto& section : pHdrSections) { + for (auto §ion : pHdrSections) { section = nullptr; } const ElfW(Phdr) *phdr = info->dlpi_phdr; @@ -961,7 +961,6 @@ int DfxElf::DlPhdrCb(struct dl_phdr_info *info, size_t size, void *data) const ElfW(Phdr) *pDynamic = pHdrSections[2]; const ElfW(Phdr) *pEhHdr = pHdrSections[3]; - if (pText == nullptr) { return 0; } @@ -981,7 +980,7 @@ int DfxElf::DlPhdrCb(struct dl_phdr_info *info, size_t size, void *data) #endif if (pDynamic) { - if(!ProccessDynamic(pDynamic, loadBase, uti)) { + if (!ProccessDynamic(pDynamic, loadBase, uti)) { return 0; } } else { diff --git a/interfaces/innerkits/unwinder/dfx_elf_parser.cpp b/interfaces/innerkits/unwinder/dfx_elf_parser.cpp index a1597c2d..4a3ca23e 100644 --- a/interfaces/innerkits/unwinder/dfx_elf_parser.cpp +++ b/interfaces/innerkits/unwinder/dfx_elf_parser.cpp @@ -245,7 +245,7 @@ bool ElfParser::ParseSectionHeaders(const EhdrType& ehdr) return false; } - if(!ExtractSectionHeadersInfo(ehdr, shdr)) { + if (!ExtractSectionHeadersInfo(ehdr, shdr)) { return false; } -- Gitee From 02678765521d093424dea30ed66caf2f47f262c6 Mon Sep 17 00:00:00 2001 From: wangqing Date: Tue, 12 Nov 2024 09:20:03 +0800 Subject: [PATCH 07/13] =?UTF-8?q?DwarfSection::FillInCie=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wangqing Change-Id: I0f1a0c8c6505bd6058c27cd51002cca4ec30e303 --- .../innerkits/unwinder/dwarf_section.cpp | 82 +++++++++++-------- .../unwinder/include/dwarf_section.h | 2 + 2 files changed, 48 insertions(+), 36 deletions(-) diff --git a/interfaces/innerkits/unwinder/dwarf_section.cpp b/interfaces/innerkits/unwinder/dwarf_section.cpp index 47654559..58a2f52d 100644 --- a/interfaces/innerkits/unwinder/dwarf_section.cpp +++ b/interfaces/innerkits/unwinder/dwarf_section.cpp @@ -293,6 +293,49 @@ bool DwarfSection::ParseCie(uintptr_t cieAddr, uintptr_t ciePtr, CommonInfoEntry return true; } +void DwarfSection::SaveAugStr(uintptr_t& ptr, std::vector& augStr) +{ + uint8_t ch; + augStr.clear(); + while (true) { + memory_->Read(ptr, &ch, true); + if (ch == '\0') { + break; + } + augStr.push_back(ch); + } +} + +void DwarfSection::ParseAugData(uintptr_t& ptr, CommonInfoEntry &cieInfo, const std::vector& augStr) +{ + MAYBE_UNUSED uintptr_t augSize = memory_->ReadUleb128(ptr); + DFXLOGU("augSize: %{public}" PRIxPTR "", augSize); + cieInfo.instructionsOff = ptr + augSize; + + for (size_t i = 1; i < augStr.size(); ++i) { + switch (augStr[i]) { + case 'P': + uint8_t personalityEncoding; + memory_->Read(ptr, &personalityEncoding, true); + cieInfo.personality = memory_->ReadEncodedValue(ptr, personalityEncoding); + break; + case 'L': + memory_->Read(ptr, &cieInfo.lsdaEncoding, true); + DFXLOGU("cieInfo.lsdaEncoding: %{public}x", cieInfo.lsdaEncoding); + break; + case 'R': + memory_->Read(ptr, &cieInfo.pointerEncoding, true); + DFXLOGU("cieInfo.pointerEncoding: %{public}x", cieInfo.pointerEncoding); + break; + case 'S': + cieInfo.isSignalFrame = true; + break; + default: + break; + } + } +} + bool DwarfSection::FillInCie(uintptr_t ptr, CommonInfoEntry &cieInfo) { uint8_t version; @@ -305,16 +348,8 @@ bool DwarfSection::FillInCie(uintptr_t ptr, CommonInfoEntry &cieInfo) } // save augmentation string - uint8_t ch; std::vector augStr; - augStr.clear(); - while (true) { - memory_->ReadU8(ptr, &ch, true); - if (ch == '\0') { - break; - } - augStr.push_back(ch); - } + SaveAugStr(ptr, augStr); // Segment Size if (version == 4 || version == 5) { // 4 5 : cie version @@ -349,33 +384,8 @@ bool DwarfSection::FillInCie(uintptr_t ptr, CommonInfoEntry &cieInfo) return true; } cieInfo.hasAugmentationData = true; - // parse augmentation data length - MAYBE_UNUSED uintptr_t augSize = memory_->ReadUleb128(ptr); - DFXLOGU("augSize: %{public}" PRIxPTR "", augSize); - cieInfo.instructionsOff = ptr + augSize; - - for (size_t i = 1; i < augStr.size(); ++i) { - switch (augStr[i]) { - case 'P': - uint8_t personalityEncoding; - memory_->ReadU8(ptr, &personalityEncoding, true); - cieInfo.personality = memory_->ReadEncodedValue(ptr, personalityEncoding); - break; - case 'L': - memory_->ReadU8(ptr, &cieInfo.lsdaEncoding, true); - DFXLOGU("cieInfo.lsdaEncoding: %{public}x", cieInfo.lsdaEncoding); - break; - case 'R': - memory_->ReadU8(ptr, &cieInfo.pointerEncoding, true); - DFXLOGU("cieInfo.pointerEncoding: %{public}x", cieInfo.pointerEncoding); - break; - case 'S': - cieInfo.isSignalFrame = true; - break; - default: - break; - } - } + ParseAugData(ptr, cieInfo, augStr); + return true; } } // namespace HiviewDFX diff --git a/interfaces/innerkits/unwinder/include/dwarf_section.h b/interfaces/innerkits/unwinder/include/dwarf_section.h index 30254f5e..316c503a 100644 --- a/interfaces/innerkits/unwinder/include/dwarf_section.h +++ b/interfaces/innerkits/unwinder/include/dwarf_section.h @@ -45,6 +45,8 @@ protected: bool FillInFde(uintptr_t ptr, FrameDescEntry &fdeInfo); bool ParseCie(uintptr_t cieAddr, uintptr_t ciePtr, CommonInfoEntry &cieInfo); bool FillInCie(uintptr_t ptr, CommonInfoEntry &cieInfo); + void SaveAugStr(uintptr_t& ptr, std::vector& augStr); + void ParseAugData(uintptr_t& ptr, CommonInfoEntry &cieInfo, const std::vector& augStr); protected: std::shared_ptr memory_; -- Gitee From 607d500c47d3d59302edc4afc9457a9ccf5dc37e Mon Sep 17 00:00:00 2001 From: wangqing Date: Sat, 26 Oct 2024 11:36:24 +0800 Subject: [PATCH 08/13] =?UTF-8?q?DfxMemory::ReadEncodedValue=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wangqing Change-Id: I5e29a8b893695c90490dd35164e5e804545a3983 --- interfaces/innerkits/unwinder/arm_exidx.cpp | 8 +- interfaces/innerkits/unwinder/dfx_elf.cpp | 33 ++-- .../innerkits/unwinder/dfx_instructions.cpp | 4 +- interfaces/innerkits/unwinder/dfx_memory.cpp | 150 ++++++------------ .../innerkits/unwinder/dfx_regs_arm.cpp | 6 +- .../unwinder/dwarf_cfa_instructions.cpp | 2 +- interfaces/innerkits/unwinder/dwarf_op.cpp | 20 +-- .../innerkits/unwinder/dwarf_section.cpp | 26 ++- .../innerkits/unwinder/include/dfx_elf.h | 9 ++ .../innerkits/unwinder/include/dfx_memory.h | 44 ++--- .../innerkits/unwinder/include/dwarf_op.h | 18 +-- interfaces/innerkits/unwinder/unwinder.cpp | 6 +- test/unittest/unwind/memory_test.cpp | 34 ++-- 13 files changed, 144 insertions(+), 216 deletions(-) diff --git a/interfaces/innerkits/unwinder/arm_exidx.cpp b/interfaces/innerkits/unwinder/arm_exidx.cpp index b09ac8e8..4297eb0a 100644 --- a/interfaces/innerkits/unwinder/arm_exidx.cpp +++ b/interfaces/innerkits/unwinder/arm_exidx.cpp @@ -200,7 +200,7 @@ bool ArmExidx::ExtractEntryData(uintptr_t entryOffset) } entryOffset += FOUR_BYTE_OFFSET; - if (!memory_->ReadU32(entryOffset, &data, false)) { + if (!memory_->Read(entryOffset, &data, false)) { DFXLOGE("[%{public}d]: entryOffset: %{public}llx error.", __LINE__, (uint64_t)entryOffset); lastErrorData_.SetAddrAndCode(entryOffset, UNW_ERROR_ILLEGAL_VALUE); return false; @@ -256,7 +256,7 @@ bool ArmExidx::ExtractEntryTabByPersonality(uintptr_t& tabOffset, uint32_t& data tabOffset += FOUR_BYTE_OFFSET; // Skip four bytes, because dont have unwind data to read - if (!memory_->ReadU32(tabOffset, &data, false)) { + if (!memory_->Read(tabOffset, &data, false)) { lastErrorData_.SetAddrAndCode(tabOffset, UNW_ERROR_INVALID_MEMORY); return false; } @@ -296,7 +296,7 @@ bool ArmExidx::ExtractEntryTab(uintptr_t tabOffset) { uint32_t data = 0; DFXLOGU("Exidx tabOffset: %{public}llx", (uint64_t)tabOffset); - if (!memory_->ReadU32(tabOffset, &data, false)) { + if (!memory_->Read(tabOffset, &data, false)) { lastErrorData_.SetAddrAndCode(tabOffset, UNW_ERROR_INVALID_MEMORY); return false; } @@ -312,7 +312,7 @@ bool ArmExidx::ExtractEntryTab(uintptr_t tabOffset) } for (size_t i = 0; i < tableCount; i++) { - if (!memory_->ReadU32(tabOffset, &data, false)) { + if (!memory_->Read(tabOffset, &data, false)) { return false; } tabOffset += FOUR_BYTE_OFFSET; diff --git a/interfaces/innerkits/unwinder/dfx_elf.cpp b/interfaces/innerkits/unwinder/dfx_elf.cpp index b7bf5ff7..382b4d30 100644 --- a/interfaces/innerkits/unwinder/dfx_elf.cpp +++ b/interfaces/innerkits/unwinder/dfx_elf.cpp @@ -877,25 +877,25 @@ void DfxElf::ParsePhdr(struct dl_phdr_info *info, std::vectorp_vaddr + info->dlpi_addr; if (pc >= vaddr && pc < vaddr + phdr->p_memsz) { // .text section - pHdrSections[0] = phdr; + pHdrSections[TEXT] = phdr; } break; } #if defined(__arm__) case PT_ARM_EXIDX: { // .arm_exidx section - pHdrSections[1] = phdr; + pHdrSections[ARMEXIDX] = phdr; break; } #endif case PT_GNU_EH_FRAME: { // .dynamic section - pHdrSections[2] = phdr; + pHdrSections[DYNAMIC] = phdr; break; } case PT_DYNAMIC: { // .eh_frame_hdr section - pHdrSections[3] = phdr; + pHdrSections[EHFRAMEHDR] = phdr; break; } default: @@ -954,33 +954,26 @@ int DfxElf::DlPhdrCb(struct dl_phdr_info *info, size_t size, void *data) std::vector pHdrSections(numOfPhdrSections); ParsePhdr(info, pHdrSections, pc); - const ElfW(Phdr) *pText = pHdrSections[0]; -#if defined(__arm__) - const ElfW(Phdr) *pArmExidx = pHdrSections[1]; -#endif - const ElfW(Phdr) *pDynamic = pHdrSections[2]; - const ElfW(Phdr) *pEhHdr = pHdrSections[3]; - - if (pText == nullptr) { + if (pHdrSections[TEXT] == nullptr) { return 0; } ElfW(Addr) loadBase = info->dlpi_addr; - uti->startPc = pText->p_vaddr + loadBase; - uti->endPc = uti->startPc + pText->p_memsz; + uti->startPc = pHdrSections[TEXT]->p_vaddr + loadBase; + uti->endPc = uti->startPc + pHdrSections[TEXT]->p_memsz; DFXLOGU("Elf name: %{public}s", info->dlpi_name); uti->namePtr = (uintptr_t) info->dlpi_name; #if defined(__arm__) - if (pArmExidx) { + if (pHdrSections[ARMEXIDX]) { ShdrInfo shdr; - shdr.addr = pArmExidx->p_vaddr; - shdr.size = pArmExidx->p_memsz; + shdr.addr = pHdrSections[ARMEXIDX]->p_vaddr; + shdr.size = pHdrSections[ARMEXIDX]->p_memsz; return FillUnwindTableByExidx(shdr, loadBase, uti); } #endif - if (pDynamic) { - if (!ProccessDynamic(pDynamic, loadBase, uti)) { + if (pHdrSections[DYNAMIC]) { + if (!ProccessDynamic(pHdrSections[DYNAMIC], loadBase, uti)) { return 0; } } else { @@ -989,7 +982,7 @@ int DfxElf::DlPhdrCb(struct dl_phdr_info *info, size_t size, void *data) struct DwarfEhFrameHdr *hdr = nullptr; struct DwarfEhFrameHdr synthHdr; - InitHdr(&hdr, synthHdr, info, loadBase, pEhHdr); + InitHdr(&hdr, synthHdr, info, loadBase, pHdrSections[EHFRAMEHDR]); return FillUnwindTableByEhhdrLocal(hdr, uti); } diff --git a/interfaces/innerkits/unwinder/dfx_instructions.cpp b/interfaces/innerkits/unwinder/dfx_instructions.cpp index 370fa635..64342f02 100644 --- a/interfaces/innerkits/unwinder/dfx_instructions.cpp +++ b/interfaces/innerkits/unwinder/dfx_instructions.cpp @@ -47,7 +47,7 @@ bool DfxInstructions::Flush(DfxRegs& regs, std::shared_ptr memory, ui break; case REG_LOC_MEM_OFFSET: location = cfa + static_cast(loc.val); - memory->ReadUptr(location, &val); + memory->Read(location, &val); break; case REG_LOC_REGISTER: location = static_cast(loc.val); @@ -60,7 +60,7 @@ bool DfxInstructions::Flush(DfxRegs& regs, std::shared_ptr memory, ui case REG_LOC_MEM_EXPRESSION: { DwarfOp dwarfOp(memory); location = dwarfOp.Eval(regs, cfa, loc.val); - memory->ReadUptr(location, &val); + memory->Read(location, &val); break; } case REG_LOC_VAL_EXPRESSION: { diff --git a/interfaces/innerkits/unwinder/dfx_memory.cpp b/interfaces/innerkits/unwinder/dfx_memory.cpp index 470e6cb6..b4401d72 100644 --- a/interfaces/innerkits/unwinder/dfx_memory.cpp +++ b/interfaces/innerkits/unwinder/dfx_memory.cpp @@ -106,46 +106,6 @@ size_t DfxMemory::Read(uintptr_t& addr, void* val, size_t size, bool incre) return bytesRead; } -bool DfxMemory::ReadU8(uintptr_t& addr, uint8_t *val, bool incre) -{ - if (Read(addr, val, sizeof(uint8_t), incre) == sizeof(uint8_t)) { - return true; - } - return false; -} - -bool DfxMemory::ReadU16(uintptr_t& addr, uint16_t *val, bool incre) -{ - if (Read(addr, val, sizeof(uint16_t), incre) == sizeof(uint16_t)) { - return true; - } - return false; -} - -bool DfxMemory::ReadU32(uintptr_t& addr, uint32_t *val, bool incre) -{ - if (Read(addr, val, sizeof(uint32_t), incre) == sizeof(uint32_t)) { - return true; - } - return false; -} - -bool DfxMemory::ReadU64(uintptr_t& addr, uint64_t *val, bool incre) -{ - if (Read(addr, val, sizeof(uint64_t), incre) == sizeof(uint64_t)) { - return true; - } - return false; -} - -bool DfxMemory::ReadUptr(uintptr_t& addr, uintptr_t *val, bool incre) -{ - if (Read(addr, val, sizeof(uintptr_t), incre) == sizeof(uintptr_t)) { - return true; - } - return false; -} - bool DfxMemory::ReadString(uintptr_t& addr, std::string* str, size_t maxSize, bool incre) { if (str == nullptr) { @@ -182,7 +142,7 @@ bool DfxMemory::ReadString(uintptr_t& addr, std::string* str, size_t maxSize, bo bool DfxMemory::ReadPrel31(uintptr_t& addr, uintptr_t *val) { uintptr_t offset; - if (!ReadUptr(addr, &offset, false)) { + if (!Read(addr, &offset, false)) { return false; } offset = static_cast(static_cast(offset << 1) >> 1); @@ -196,7 +156,7 @@ uint64_t DfxMemory::ReadUleb128(uintptr_t& addr) uint64_t shift = 0; uint8_t u8 = 0; do { - if (!ReadU8(addr, &u8, true)) { + if (!Read(addr, &u8, true)) { break; } @@ -212,7 +172,7 @@ int64_t DfxMemory::ReadSleb128(uintptr_t& addr) uint64_t shift = 0; uint8_t byte = 0; do { - if (!ReadU8(addr, &byte, true)) { + if (!Read(addr, &byte, true)) { break; } @@ -250,83 +210,67 @@ size_t DfxMemory::GetEncodedSize(uint8_t encoding) } } -uintptr_t DfxMemory::ReadEncodedValue(uintptr_t& addr, uint8_t encoding) +void DfxMemory::ReadFormatEncodedValue(uintptr_t& addr, uintptr_t& val, uint8_t formatEncoding) { - uintptr_t startAddr = addr; - uintptr_t val = 0; - if (encoding == DW_EH_PE_omit) { - return val; - } else if (encoding == DW_EH_PE_aligned) { - if (__builtin_add_overflow(addr, sizeof(uintptr_t) - 1, &addr)) { - return val; - } - addr &= -sizeof(uintptr_t); - ReadUptr(addr, &val, true); - return val; - } - - switch (encoding & DW_EH_PE_FORMAT_MASK) { - case DW_EH_PE_absptr: - ReadUptr(addr, &val, true); - return val; + switch (formatEncoding) { case DW_EH_PE_uleb128: val = static_cast(ReadUleb128(addr)); break; case DW_EH_PE_sleb128: val = static_cast(ReadSleb128(addr)); break; - case DW_EH_PE_udata1: { - uint8_t tmp = 0; - ReadU8(addr, &tmp, true); - val = static_cast(tmp); - } + case DW_EH_PE_udata1: + val = static_cast(ReadValue(addr, true)); break; - case DW_EH_PE_sdata1: { - int8_t tmp = 0; - ReadS8(addr, &tmp, true); - val = static_cast(tmp); - } + case DW_EH_PE_sdata1: + val = static_cast(ReadValue(addr, true)); break; - case DW_EH_PE_udata2: { - uint16_t tmp = 0; - ReadU16(addr, &tmp, true); - val = static_cast(tmp); - } + case DW_EH_PE_udata2: + val = static_cast(ReadValue(addr, true)); break; - case DW_EH_PE_sdata2: { - int16_t tmp = 0; - ReadS16(addr, &tmp, true); - val = static_cast(tmp); - } + case DW_EH_PE_sdata2: + val = static_cast(ReadValue(addr, true)); break; - case DW_EH_PE_udata4: { - uint32_t tmp = 0; - ReadU32(addr, &tmp, true); - val = static_cast(tmp); - } + case DW_EH_PE_udata4: + val = static_cast(ReadValue(addr, true)); break; - case DW_EH_PE_sdata4: { - int32_t tmp = 0; - ReadS32(addr, &tmp, true); - val = static_cast(tmp); - } + case DW_EH_PE_sdata4: + val = static_cast(ReadValue(addr, true)); break; - case DW_EH_PE_udata8: { - uint64_t tmp = 0; - ReadU64(addr, &tmp, true); - val = static_cast(tmp); - } + case DW_EH_PE_udata8: + val = static_cast(ReadValue(addr, true)); break; - case DW_EH_PE_sdata8: { - int64_t tmp = 0; - ReadS64(addr, &tmp, true); - val = static_cast(tmp); - } + case DW_EH_PE_sdata8: + val = static_cast(ReadValue(addr, true)); break; default: - DFXLOGW("Unexpected encoding format 0x%{public}x", encoding & DW_EH_PE_FORMAT_MASK); + DFXLOGW("Unexpected encoding format 0x%{public}x", formatEncoding); break; } +} + +uintptr_t DfxMemory::ReadEncodedValue(uintptr_t& addr, uint8_t encoding) +{ + uintptr_t startAddr = addr; + uintptr_t val = 0; + if (encoding == DW_EH_PE_omit) { + return val; + } else if (encoding == DW_EH_PE_aligned) { + if (__builtin_add_overflow(addr, sizeof(uintptr_t) - 1, &addr)) { + return val; + } + addr &= -sizeof(uintptr_t); + Read(addr, &val, true); + return val; + } + + uint8_t formatEncoding = encoding & DW_EH_PE_FORMAT_MASK; + if (formatEncoding == DW_EH_PE_absptr) { + Read(addr, &val, true); + return val; + } else { + ReadFormatEncodedValue(addr, val, formatEncoding); + } switch (encoding & DW_EH_PE_APPL_MASK) { case DW_EH_PE_pcrel: @@ -347,7 +291,7 @@ uintptr_t DfxMemory::ReadEncodedValue(uintptr_t& addr, uint8_t encoding) if (encoding & DW_EH_PE_indirect) { uintptr_t indirectAddr = val; - ReadUptr(indirectAddr, &val, true); + Read(indirectAddr, &val, true); } return val; } diff --git a/interfaces/innerkits/unwinder/dfx_regs_arm.cpp b/interfaces/innerkits/unwinder/dfx_regs_arm.cpp index 73c1a6bc..caf82de2 100644 --- a/interfaces/innerkits/unwinder/dfx_regs_arm.cpp +++ b/interfaces/innerkits/unwinder/dfx_regs_arm.cpp @@ -129,7 +129,7 @@ bool DfxRegsArm::StepIfSignalFrame(uintptr_t pc, std::shared_ptr memo pc = pc & ~0x1; uint32_t data; - if (!memory->ReadU32(pc, &data, false)) { + if (!memory->Read(pc, &data, false)) { return false; } DFXLOGU("data: %{public}x", data); @@ -151,7 +151,7 @@ bool DfxRegsArm::StepIfSignalFrame(uintptr_t pc, std::shared_ptr memo // Form 3 (thumb): // 0x77 0x27 movs r7, #77 // 0x00 0xdf svc 0 - if (!memory->ReadU32(spAddr, &data, false)) { + if (!memory->Read(spAddr, &data, false)) { return false; } if (data == 0x5ac3c35a) { @@ -177,7 +177,7 @@ bool DfxRegsArm::StepIfSignalFrame(uintptr_t pc, std::shared_ptr memo // Form 3 (thumb): // 0xad 0x27 movs r7, #ad // 0x00 0xdf svc 0 - if (!memory->ReadU32(spAddr, &data, false)) { + if (!memory->Read(spAddr, &data, false)) { return false; } if (data == spAddr + 8) { // 8 : eight bytes offset diff --git a/interfaces/innerkits/unwinder/dwarf_cfa_instructions.cpp b/interfaces/innerkits/unwinder/dwarf_cfa_instructions.cpp index ae219d08..aebdb827 100644 --- a/interfaces/innerkits/unwinder/dwarf_cfa_instructions.cpp +++ b/interfaces/innerkits/unwinder/dwarf_cfa_instructions.cpp @@ -53,7 +53,7 @@ bool DwarfCfaInstructions::Iterate(uintptr_t pc, FrameDescEntry fde, // Read the cfa information. uint8_t opCode; - if (!memory_->ReadU8(instPtr, &opCode, true)) { + if (!memory_->Read(instPtr, &opCode, true)) { break; } diff --git a/interfaces/innerkits/unwinder/dwarf_op.cpp b/interfaces/innerkits/unwinder/dwarf_op.cpp index b5a6d1ff..6c7eb710 100644 --- a/interfaces/innerkits/unwinder/dwarf_op.cpp +++ b/interfaces/innerkits/unwinder/dwarf_op.cpp @@ -52,12 +52,12 @@ template bool DwarfOp::Decode(DfxRegs& regs, uintptr_t& addr) { uint8_t opcode; - memory_->ReadU8(addr, &opcode, true); + memory_->Read(addr, &opcode, true); switch (opcode) { case DW_OP_addr: { DFXLOGU("DW_OP_addr"); uintptr_t val; - memory_->ReadUptr(addr, &val, true); + memory_->Read(addr, &val, true); OpPush(val); } break; @@ -68,56 +68,56 @@ bool DwarfOp::Decode(DfxRegs& regs, uintptr_t& addr) case DW_OP_const1u: { DFXLOGU("DW_OP_const1u"); uint8_t val; - memory_->ReadU8(addr, &val, true); + memory_->Read(addr, &val, true); OpPush(val); } break; case DW_OP_const1s: { DFXLOGU("DW_OP_const1s"); int8_t val; - memory_->ReadS8(addr, &val, true); + memory_->Read(addr, &val, true); OpPush(val); } break; case DW_OP_const2u: { DFXLOGU("DW_OP_const2u"); uint16_t val; - memory_->ReadU16(addr, &val, true); + memory_->Read(addr, &val, true); OpPush(val); } break; case DW_OP_const2s: { DFXLOGU("DW_OP_const2s"); int16_t val; - memory_->ReadS16(addr, &val, true); + memory_->Read(addr, &val, true); OpPush(val); } break; case DW_OP_const4u: { DFXLOGU("DW_OP_const4u"); uint32_t val; - memory_->ReadU32(addr, &val, true); + memory_->Read(addr, &val, true); OpPush(val); } break; case DW_OP_const4s: { DFXLOGU("DW_OP_const4s"); int32_t val; - memory_->ReadS32(addr, &val, true); + memory_->Read(addr, &val, true); OpPush(val); } break; case DW_OP_const8u: { DFXLOGU("DW_OP_const8u"); uint64_t val; - memory_->ReadU64(addr, &val, true); + memory_->Read(addr, &val, true); OpPush(val); } break; case DW_OP_const8s: { DFXLOGU("DW_OP_const8s"); int64_t val; - memory_->ReadS64(addr, &val, true); + memory_->Read(addr, &val, true); OpPush(val); } break; diff --git a/interfaces/innerkits/unwinder/dwarf_section.cpp b/interfaces/innerkits/unwinder/dwarf_section.cpp index 58a2f52d..1ecdf83f 100644 --- a/interfaces/innerkits/unwinder/dwarf_section.cpp +++ b/interfaces/innerkits/unwinder/dwarf_section.cpp @@ -76,13 +76,13 @@ bool DwarfSection::SearchEntry(uintptr_t pc, struct UnwindTableInfo uti, struct while (low < high) { uintptr_t cur = (low + high) / 2; // 2 : binary search divided parameter ptr = (uintptr_t) tableData + cur * sizeof(DwarfTableEntry); - if (!memory_->ReadS32(ptr, &dwarfTableEntry.startPc, true)) { + if (!memory_->Read(ptr, &dwarfTableEntry.startPc, true)) { lastErrorData_.SetAddrAndCode(ptr, UNW_ERROR_INVALID_MEMORY); return false; } uintptr_t startPc = static_cast(dwarfTableEntry.startPc) + segbase; if (startPc == pc) { - if (!memory_->ReadS32(ptr, &dwarfTableEntry.fdeOffset, true)) { + if (!memory_->Read(ptr, &dwarfTableEntry.fdeOffset, true)) { lastErrorData_.SetAddrAndCode(ptr, UNW_ERROR_INVALID_MEMORY); return false; } @@ -98,7 +98,7 @@ bool DwarfSection::SearchEntry(uintptr_t pc, struct UnwindTableInfo uti, struct if (entry == 0) { if (high != 0) { ptr = static_cast(tableData) + (high - 1) * sizeof(DwarfTableEntry) + 4; // 4 : four bytes - if (!memory_->ReadS32(ptr, &dwarfTableEntry.fdeOffset, true)) { + if (!memory_->Read(ptr, &dwarfTableEntry.fdeOffset, true)) { lastErrorData_.SetAddrAndCode(ptr, UNW_ERROR_INVALID_MEMORY); return false; } @@ -163,15 +163,15 @@ bool DwarfSection::GetCieOrFde(uintptr_t &addr, FrameDescEntry &fdeInfo) void DwarfSection::ParseCieOrFdeHeader(uintptr_t& ptr, FrameDescEntry &fdeInfo, bool& isCieEntry) { uint32_t value32 = 0; - memory_->ReadU32(ptr, &value32, true); + memory_->Read(ptr, &value32, true); uintptr_t ciePtr = 0; uintptr_t instructionsEnd = 0; if (value32 == static_cast(-1)) { uint64_t value64; - memory_->ReadU64(ptr, &value64, true); + memory_->Read(ptr, &value64, true); instructionsEnd = ptr + value64; - memory_->ReadU64(ptr, &value64, true); + memory_->Read(ptr, &value64, true); ciePtr = static_cast(value64); if (ciePtr == cie64Value_) { isCieEntry = true; @@ -184,7 +184,7 @@ void DwarfSection::ParseCieOrFdeHeader(uintptr_t& ptr, FrameDescEntry &fdeInfo, ptr += sizeof(uint64_t); } else { instructionsEnd = ptr + value32; - memory_->ReadU32(ptr, &value32, false); + memory_->Read(ptr, &value32, false); ciePtr = static_cast(value32); if (ciePtr == cie32Value_) { isCieEntry = true; @@ -297,11 +297,7 @@ void DwarfSection::SaveAugStr(uintptr_t& ptr, std::vector& augStr) { uint8_t ch; augStr.clear(); - while (true) { - memory_->Read(ptr, &ch, true); - if (ch == '\0') { - break; - } + while (memory_->Read(ptr, &ch, true) && ch == '\0') { augStr.push_back(ch); } } @@ -339,7 +335,7 @@ void DwarfSection::ParseAugData(uintptr_t& ptr, CommonInfoEntry &cieInfo, const bool DwarfSection::FillInCie(uintptr_t ptr, CommonInfoEntry &cieInfo) { uint8_t version; - memory_->ReadU8(ptr, &version, true); + memory_->Read(ptr, &version, true); DFXLOGU("Cie version: %{public}d", version); if (version != DW_EH_VERSION && version != 3 && version != 4 && version != 5) { // 3 4 5 : cie version DFXLOGE("Invalid cie version: %{public}d", version); @@ -355,7 +351,7 @@ bool DwarfSection::FillInCie(uintptr_t ptr, CommonInfoEntry &cieInfo) if (version == 4 || version == 5) { // 4 5 : cie version // Skip the Address Size field since we only use it for validation. ptr += 1; - memory_->ReadU8(ptr, &cieInfo.segmentSize, true); + memory_->Read(ptr, &cieInfo.segmentSize, true); } else { cieInfo.segmentSize = 0; } @@ -371,7 +367,7 @@ bool DwarfSection::FillInCie(uintptr_t ptr, CommonInfoEntry &cieInfo) // parse return address register if (version == DW_EH_VERSION) { uint8_t val; - memory_->ReadU8(ptr, &val, true); + memory_->Read(ptr, &val, true); cieInfo.returnAddressRegister = static_cast(val); } else { cieInfo.returnAddressRegister = (uintptr_t)memory_->ReadUleb128(ptr); diff --git a/interfaces/innerkits/unwinder/include/dfx_elf.h b/interfaces/innerkits/unwinder/include/dfx_elf.h index 0b6bfda7..bccc88ff 100644 --- a/interfaces/innerkits/unwinder/include/dfx_elf.h +++ b/interfaces/innerkits/unwinder/include/dfx_elf.h @@ -29,6 +29,15 @@ struct DlCbData { bool singleFde = false; }; +#if is_ohos && !is_mingw +enum HdrSection { + TEXT = 0, + ARMEXIDX = 1, + DYNAMIC = 2, + EHFRAMEHDR = 3 +}; +#endif + class DfxElf final { public: static std::shared_ptr Create(const std::string& file); diff --git a/interfaces/innerkits/unwinder/include/dfx_memory.h b/interfaces/innerkits/unwinder/include/dfx_memory.h index 7788cdc4..2794db82 100644 --- a/interfaces/innerkits/unwinder/include/dfx_memory.h +++ b/interfaces/innerkits/unwinder/include/dfx_memory.h @@ -41,39 +41,24 @@ public: bool ReadMem(uintptr_t addr, uintptr_t *val); virtual size_t Read(uintptr_t& addr, void* val, size_t size, bool incre = false); - virtual bool ReadU8(uintptr_t& addr, uint8_t *val, bool incre = false); - virtual bool ReadS8(uintptr_t& addr, int8_t *val, bool incre = false) - { - uint8_t valp = 0; - bool ret = ReadU8(addr, &valp, incre); - *val = static_cast(valp); - return ret; - } - virtual bool ReadU16(uintptr_t& addr, uint16_t *val, bool incre = false); - virtual bool ReadS16(uintptr_t& addr, int16_t *val, bool incre = false) - { - uint16_t valp = 0; - bool ret = ReadU16(addr, &valp, incre); - *val = static_cast(valp); - return ret; - } - virtual bool ReadU32(uintptr_t& addr, uint32_t *val, bool incre = false); - virtual bool ReadS32(uintptr_t& addr, int32_t *val, bool incre = false) + + template + bool Read(uintptr_t& addr, T *val, bool incre = false) { - uint32_t valp = 0; - bool ret = ReadU32(addr, &valp, incre); - *val = static_cast(valp); - return ret; + if (Read(addr, val, sizeof(T), incre) == sizeof(T)) { + return true; + } + return false; } - virtual bool ReadU64(uintptr_t& addr, uint64_t *val, bool incre = false); - virtual bool ReadS64(uintptr_t& addr, int64_t *val, bool incre = false) + + template + inline T ReadValue(uintptr_t& addr, bool incre = false) { - uint64_t valp = 0; - bool ret = ReadU64(addr, &valp, incre); - *val = static_cast(valp); - return ret; + T tmp = 0; + Read(addr, &tmp, incre); + return tmp; } - virtual bool ReadUptr(uintptr_t& addr, uintptr_t *val, bool incre = false); + virtual bool ReadString(uintptr_t& addr, std::string* str, size_t maxSize, bool incre = false); virtual bool ReadPrel31(uintptr_t& addr, uintptr_t *val); @@ -84,6 +69,7 @@ public: virtual void SetFuncOffset(uintptr_t offset) { funcOffset_ = offset; } virtual size_t GetEncodedSize(uint8_t encoding); virtual uintptr_t ReadEncodedValue(uintptr_t& addr, uint8_t encoding); + virtual void ReadFormatEncodedValue(uintptr_t& addr, uintptr_t& val, uint8_t formatEncoding); #if is_ohos && !is_mingw static size_t ReadProcMemByPid(const pid_t pid, const uint64_t addr, void* data, size_t size); #endif diff --git a/interfaces/innerkits/unwinder/include/dwarf_op.h b/interfaces/innerkits/unwinder/include/dwarf_op.h index 7c8f0790..88f80b06 100644 --- a/interfaces/innerkits/unwinder/include/dwarf_op.h +++ b/interfaces/innerkits/unwinder/include/dwarf_op.h @@ -78,7 +78,7 @@ protected: { auto addr = static_cast(StackPop()); uintptr_t val; - memory_->ReadUptr(addr, &val); + memory_->Read(addr, &val); StackPush(static_cast(val)); }; @@ -88,24 +88,24 @@ protected: auto addr = static_cast(StackPop()); AddressType value = 0; uint8_t operand; - memory_->ReadU8(exprPtr, &operand, true); + memory_->Read(exprPtr, &operand, true); switch (operand) { case 1: { // 1 : read one byte length uint8_t u8; - memory_->ReadU8(addr, &u8, true); + memory_->Read(addr, &u8, true); value = static_cast(u8); } break; case 2: { // 2 : read two bytes length uint16_t u16; - memory_->ReadU16(addr, &u16, true); + memory_->Read(addr, &u16, true); value = static_cast(u16); } break; case 3: // 3 : read four bytes length case 4: { // 4 : read four bytes length uint32_t u32; - memory_->ReadU32(addr, &u32, true); + memory_->Read(addr, &u32, true); value = static_cast(u32); } break; @@ -114,7 +114,7 @@ protected: case 7: // 7 : read eight bytes length case 8: { // 8 : read eight bytes length uint64_t u64; - memory_->ReadU64(addr, &u64, true); + memory_->Read(addr, &u64, true); value = static_cast(u64); } break; @@ -146,7 +146,7 @@ protected: inline void OpPick(AddressType& exprPtr) { uint8_t reg; - memory_->ReadU8(exprPtr, ®, true); + memory_->Read(exprPtr, ®, true); if (reg > StackSize()) { return; } @@ -280,7 +280,7 @@ protected: inline void OpSkip(AddressType& exprPtr) { int16_t offset; - memory_->ReadS16(exprPtr, &offset, true); + memory_->Read(exprPtr, &offset, true); exprPtr = static_cast(exprPtr + offset); }; @@ -289,7 +289,7 @@ protected: { AddressType top = StackPop(); int16_t offset; - memory_->ReadS16(exprPtr, &offset, true); + memory_->Read(exprPtr, &offset, true); if (top != 0) { exprPtr = exprPtr + offset; } diff --git a/interfaces/innerkits/unwinder/unwinder.cpp b/interfaces/innerkits/unwinder/unwinder.cpp index 1a95c7ae..74449d74 100644 --- a/interfaces/innerkits/unwinder/unwinder.cpp +++ b/interfaces/innerkits/unwinder/unwinder.cpp @@ -864,8 +864,8 @@ bool Unwinder::Impl::FpStep(uintptr_t& fp, uintptr_t& pc, void *ctx) uintptr_t prevFp = fp; uintptr_t ptr = fp; - if (ptr != 0 && memory_->ReadUptr(ptr, &fp, true) && - memory_->ReadUptr(ptr, &pc, false)) { + if (ptr != 0 && memory_->Read(ptr, &fp, true) && + memory_->Read(ptr, &pc, false)) { if (fp != 0 && fp <= prevFp) { DFXLOGU("Illegal or same fp value"); lastErrorData_.SetAddrAndCode(pc, UNW_ERROR_ILLEGAL_VALUE); @@ -1100,7 +1100,7 @@ bool Unwinder::Impl::Apply(std::shared_ptr regs, std::shared_ptrGetSp(); - if (ret && (!memory_->ReadUptr(sp, &tmp, false))) { + if (ret && (!memory_->Read(sp, &tmp, false))) { errCode = UNW_ERROR_UNREADABLE_SP; ret = false; } diff --git a/test/unittest/unwind/memory_test.cpp b/test/unittest/unwind/memory_test.cpp index ba34e29f..ad2866cb 100644 --- a/test/unittest/unwind/memory_test.cpp +++ b/test/unittest/unwind/memory_test.cpp @@ -80,7 +80,7 @@ HWTEST_F(DfxMemoryTest, DfxMemoryTest002, TestSize.Level2) uintptr_t value; auto acc = std::make_shared(); auto memory = std::make_shared(acc); - bool ret = memory->ReadUptr(addr, &value, false); + bool ret = memory->Read(addr, &value, false); EXPECT_EQ(true, ret) << "DfxMemoryTest002: ret:" << ret; @@ -116,7 +116,7 @@ HWTEST_F(DfxMemoryTest, DfxMemoryTest003, TestSize.Level2) memory->SetCtx(&ctx); uintptr_t addr = reinterpret_cast(&values[0]); uintptr_t value; - ASSERT_TRUE(memory->ReadUptr(addr, &value, false)); + ASSERT_TRUE(memory->Read(addr, &value, false)); #if defined(__arm__) ASSERT_EQ(value, 0x04030201); #elif defined(__aarch64__) @@ -155,16 +155,16 @@ HWTEST_F(DfxMemoryTest, DfxMemoryTest004, TestSize.Level2) memory->SetCtx(&ctx); uintptr_t addr = reinterpret_cast(&values[0]); uint8_t tmp8; - ASSERT_TRUE(memory->ReadU8(addr, &tmp8, false)); + ASSERT_TRUE(memory->Read(addr, &tmp8, false)); ASSERT_EQ(tmp8, 0x01); uint16_t tmp16; - ASSERT_TRUE(memory->ReadU16(addr, &tmp16, false)); + ASSERT_TRUE(memory->Read(addr, &tmp16, false)); ASSERT_EQ(tmp16, 0x0201); uint32_t tmp32; - ASSERT_TRUE(memory->ReadU32(addr, &tmp32, false)); + ASSERT_TRUE(memory->Read(addr, &tmp32, false)); ASSERT_EQ(tmp32, 0x04030201); uint64_t tmp64; - ASSERT_TRUE(memory->ReadU64(addr, &tmp64, false)); + ASSERT_TRUE(memory->Read(addr, &tmp64, false)); ASSERT_EQ(tmp64, 0x0807060504030201); GTEST_LOG_(INFO) << "DfxMemoryTest004: end."; } @@ -259,7 +259,7 @@ HWTEST_F(DfxMemoryTest, DfxMemoryTest008, TestSize.Level2) auto memory = std::make_shared(acc); memory->SetCtx(&ctx); uintptr_t addr = reinterpret_cast(&values[0]); - bool ret = memory->ReadUptr(addr, &value, false); + bool ret = memory->Read(addr, &value, false); EXPECT_EQ(true, ret) << "DfxMemoryTest008: ret:" << ret; uint64_t tmp; memory->Read(addr, &tmp, sizeof(uint8_t), false); @@ -303,7 +303,7 @@ HWTEST_F(DfxMemoryTest, DfxMemoryTest009, TestSize.Level2) memory->SetCtx(&ctx); uintptr_t addr = reinterpret_cast(&values[0]); uintptr_t value; - ASSERT_TRUE(memory->ReadUptr(addr, &value, false)); + ASSERT_TRUE(memory->Read(addr, &value, false)); #if defined(__arm__) ASSERT_EQ(value, 0x04030201); #elif defined(__aarch64__) @@ -353,16 +353,16 @@ HWTEST_F(DfxMemoryTest, DfxMemoryTest010, TestSize.Level2) memory->SetCtx(&ctx); uintptr_t addr = reinterpret_cast(&values[0]); uint8_t tmp8; - ASSERT_TRUE(memory->ReadU8(addr, &tmp8, false)); + ASSERT_TRUE(memory->Read(addr, &tmp8, false)); ASSERT_EQ(tmp8, 0x01); uint16_t tmp16; - ASSERT_TRUE(memory->ReadU16(addr, &tmp16, false)); + ASSERT_TRUE(memory->Read(addr, &tmp16, false)); ASSERT_EQ(tmp16, 0x0201); uint32_t tmp32; - ASSERT_TRUE(memory->ReadU32(addr, &tmp32, false)); + ASSERT_TRUE(memory->Read(addr, &tmp32, false)); ASSERT_EQ(tmp32, 0x04030201); uint64_t tmp64; - ASSERT_TRUE(memory->ReadU64(addr, &tmp64, false)); + ASSERT_TRUE(memory->Read(addr, &tmp64, false)); ASSERT_EQ(tmp64, 0x0807060504030201); DfxPtrace::Detach(pid); _exit(0); @@ -464,12 +464,12 @@ HWTEST_F(DfxMemoryTest, DfxMemoryTest013, TestSize.Level2) uint8_t values[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8}; uintptr_t addr = reinterpret_cast(&values[0]); EXPECT_FALSE(memory->ReadMem(addr, nullptr)); - EXPECT_FALSE(memory->ReadUptr(addr, nullptr, false)); + EXPECT_FALSE(memory->Read(addr, nullptr, false)); EXPECT_FALSE(memory->Read(addr, nullptr, sizeof(uint8_t), false)); - EXPECT_FALSE(memory->ReadU8(addr, nullptr, false)); - EXPECT_FALSE(memory->ReadU16(addr, nullptr, false)); - EXPECT_FALSE(memory->ReadU32(addr, nullptr, false)); - EXPECT_FALSE(memory->ReadU64(addr, nullptr, false)); + EXPECT_FALSE(memory->Read(addr, nullptr, false)); + EXPECT_FALSE(memory->Read(addr, nullptr, false)); + EXPECT_FALSE(memory->Read(addr, nullptr, false)); + EXPECT_FALSE(memory->Read(addr, nullptr, false)); GTEST_LOG_(INFO) << "DfxMemoryTest013: end."; } -- Gitee From 229bbb853f727f8d3df11429b472ef954e959ea8 Mon Sep 17 00:00:00 2001 From: wangqing Date: Tue, 19 Nov 2024 15:20:35 +0800 Subject: [PATCH 09/13] fix DfxElf::DlPhdrCb bug Signed-off-by: wangqing Change-Id: I5d6eb5ee0314717ce76f1c0fd34d3773773e56b5 --- interfaces/innerkits/unwinder/dfx_elf.cpp | 19 ++++++++----------- .../innerkits/unwinder/include/dfx_elf.h | 2 +- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/interfaces/innerkits/unwinder/dfx_elf.cpp b/interfaces/innerkits/unwinder/dfx_elf.cpp index 382b4d30..9d1e7e24 100644 --- a/interfaces/innerkits/unwinder/dfx_elf.cpp +++ b/interfaces/innerkits/unwinder/dfx_elf.cpp @@ -867,9 +867,6 @@ bool DfxElf::FindSection(struct dl_phdr_info *info, const std::string secName, S void DfxElf::ParsePhdr(struct dl_phdr_info *info, std::vector &pHdrSections, const uintptr_t pc) { - for (auto §ion : pHdrSections) { - section = nullptr; - } const ElfW(Phdr) *phdr = info->dlpi_phdr; for (size_t i = 0; i < info->dlpi_phnum && phdr != nullptr; i++, phdr++) { switch (phdr->p_type) { @@ -889,13 +886,13 @@ void DfxElf::ParsePhdr(struct dl_phdr_info *info, std::vectorp_memsz, 0); - *hdr = (struct DwarfEhFrameHdr *) (pEhHdr->p_vaddr + loadBase); + *hdr = (struct DwarfEhFrameHdr *) (pEhHdr->p_vaddr + info->dlpi_addr); } else { ShdrInfo shdr; if (FindSection(info, EH_FRAME, shdr)) { @@ -951,7 +948,7 @@ int DfxElf::DlPhdrCb(struct dl_phdr_info *info, size_t size, void *data) UnwindTableInfo* uti = &cbData->uti; uintptr_t pc = cbData->pc; const int numOfPhdrSections = 4; - std::vector pHdrSections(numOfPhdrSections); + std::vector pHdrSections(numOfPhdrSections, nullptr); ParsePhdr(info, pHdrSections, pc); if (pHdrSections[TEXT] == nullptr) { @@ -982,7 +979,7 @@ int DfxElf::DlPhdrCb(struct dl_phdr_info *info, size_t size, void *data) struct DwarfEhFrameHdr *hdr = nullptr; struct DwarfEhFrameHdr synthHdr; - InitHdr(&hdr, synthHdr, info, loadBase, pHdrSections[EHFRAMEHDR]); + InitHdr(&hdr, synthHdr, info, pHdrSections[EHFRAMEHDR]); return FillUnwindTableByEhhdrLocal(hdr, uti); } diff --git a/interfaces/innerkits/unwinder/include/dfx_elf.h b/interfaces/innerkits/unwinder/include/dfx_elf.h index bccc88ff..79dd5c90 100644 --- a/interfaces/innerkits/unwinder/include/dfx_elf.h +++ b/interfaces/innerkits/unwinder/include/dfx_elf.h @@ -98,7 +98,7 @@ protected: static void ParsePhdr(struct dl_phdr_info *info, std::vector& pHdrSections, const uintptr_t pc); static bool ProccessDynamic(const ElfW(Phdr) *pDynamic, ElfW(Addr) loadBase, UnwindTableInfo *uti); static void InitHdr(struct DwarfEhFrameHdr **hdr, struct DwarfEhFrameHdr& synthHdr, - struct dl_phdr_info *info, ElfW(Addr) loadBase, const ElfW(Phdr) *pEhHdr); + struct dl_phdr_info *info, const ElfW(Phdr) *pEhHdr); static bool FindSection(struct dl_phdr_info *info, const std::string secName, ShdrInfo& shdr); static bool FillUnwindTableByEhhdrLocal(struct DwarfEhFrameHdr* hdr, struct UnwindTableInfo* uti); #endif -- Gitee From 5a57ffa8f1cfa1b524ffc204df40d5c62d23cfc7 Mon Sep 17 00:00:00 2001 From: wangqing Date: Tue, 19 Nov 2024 17:05:44 +0800 Subject: [PATCH 10/13] fix DfxMemory::ReadEncodedValue bug Signed-off-by: wangqing Change-Id: I9bb8d85040c85749f2b3dc0a45528c3329412196 --- interfaces/innerkits/unwinder/dfx_regs_arm64.cpp | 2 +- interfaces/innerkits/unwinder/dfx_regs_riscv64.cpp | 2 +- interfaces/innerkits/unwinder/dfx_regs_x86_64.cpp | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/interfaces/innerkits/unwinder/dfx_regs_arm64.cpp b/interfaces/innerkits/unwinder/dfx_regs_arm64.cpp index bc353905..0c47bdbe 100644 --- a/interfaces/innerkits/unwinder/dfx_regs_arm64.cpp +++ b/interfaces/innerkits/unwinder/dfx_regs_arm64.cpp @@ -144,7 +144,7 @@ bool DfxRegsArm64::StepIfSignalFrame(uintptr_t pc, std::shared_ptr me return false; } uint64_t data; - if (!memory->ReadU64(pc, &data, false)) { + if (!memory->Read(pc, &data, false)) { return false; } DFXLOGU("data: %{public}lx", data); diff --git a/interfaces/innerkits/unwinder/dfx_regs_riscv64.cpp b/interfaces/innerkits/unwinder/dfx_regs_riscv64.cpp index 0d6d2428..2ab1af7c 100644 --- a/interfaces/innerkits/unwinder/dfx_regs_riscv64.cpp +++ b/interfaces/innerkits/unwinder/dfx_regs_riscv64.cpp @@ -141,7 +141,7 @@ std::string DfxRegsRiscv64::PrintRegs() const bool DfxRegsRiscv64::StepIfSignalFrame(uintptr_t pc, std::shared_ptr memory) { uint64_t data; - if (!memory->ReadU64(pc, &data, false)) { + if (!memory->Read(pc, &data, false)) { return false; } DFXLOGU("[%{public}d]: data: %{public}llx", __LINE__, data); diff --git a/interfaces/innerkits/unwinder/dfx_regs_x86_64.cpp b/interfaces/innerkits/unwinder/dfx_regs_x86_64.cpp index 2ed70e72..192e0a0b 100644 --- a/interfaces/innerkits/unwinder/dfx_regs_x86_64.cpp +++ b/interfaces/innerkits/unwinder/dfx_regs_x86_64.cpp @@ -64,7 +64,7 @@ void DfxRegsX86_64::SetFromQutMiniRegs(const uintptr_t* regs, const size_t size) bool DfxRegsX86_64::SetPcFromReturnAddress(std::shared_ptr memory) { uintptr_t newPc; - if (!memory->ReadUptr(regsData_[REG_SP], &newPc, false) || + if (!memory->Read(regsData_[REG_SP], &newPc, false) || newPc == regsData_[REG_PC]) { return false; } @@ -97,7 +97,7 @@ std::string DfxRegsX86_64::PrintRegs() const bool DfxRegsX86_64::StepIfSignalFrame(uintptr_t pc, std::shared_ptr memory) { uint64_t data; - if (!memory->ReadU64(pc, &data, false)) { + if (!memory->Read(pc, &data, false)) { return false; } DFXLOGU("[%{public}d]: data: %{public}llx", __LINE__, data); @@ -112,7 +112,7 @@ bool DfxRegsX86_64::StepIfSignalFrame(uintptr_t pc, std::shared_ptr m uint16_t data2; pc += sizeof(uint64_t); - if (!memory->ReadU16(pc, &data2, false) || (data2 != 0x0f05)) { + if (!memory->Read(pc, &data2, false) || (data2 != 0x0f05)) { DFXLOGU("data2: %{public}x", data2); return false; } -- Gitee From 442bd16f31e13097386305c78c8cdd9e8c51ba2b Mon Sep 17 00:00:00 2001 From: wangqing Date: Wed, 20 Nov 2024 12:13:30 +0800 Subject: [PATCH 11/13] =?UTF-8?q?DfxDumpCatcher::DoDumpRemotePoll=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wangqing Change-Id: I17200d9ee66a50f40b1c8a358e802d10fd253515 Signed-off-by: wangqing --- .../dump_catcher/dfx_dump_catcher.cpp | 195 +++++++++++------- .../dump_catcher/include/dfx_dump_catcher.h | 9 + 2 files changed, 125 insertions(+), 79 deletions(-) diff --git a/interfaces/innerkits/dump_catcher/dfx_dump_catcher.cpp b/interfaces/innerkits/dump_catcher/dfx_dump_catcher.cpp index cb06376e..3577eb4e 100644 --- a/interfaces/innerkits/dump_catcher/dfx_dump_catcher.cpp +++ b/interfaces/innerkits/dump_catcher/dfx_dump_catcher.cpp @@ -433,108 +433,145 @@ void DfxDumpCatcher::AsyncGetAllTidKernelStack(pid_t pid, int waitMilliSeconds) } } -int DfxDumpCatcher::DoDumpRemotePoll(int bufFd, int resFd, int timeout, std::string& msg, bool isJson) +bool DfxDumpCatcher::DoPollRetLEZero(std::string &resMsg, const uint64_t endTime, int &remainTime, + bool &collectAllTidStack, int &ret) { - DFX_TRACE_SCOPED_DLSYM("DoDumpRemotePoll"); - if (bufFd < 0 || resFd < 0) { - if (!isJson) { - msg = "Result: bufFd or resFd < 0.\n"; + if (errno == EINTR) { + uint64_t now = GetAbsTimeMilliSeconds(); + if (now >= endTime) { + ret = DUMP_POLL_TIMEOUT; + resMsg.append("Result: poll timeout.\n"); + return false; } - DFXLOGE("invalid bufFd or resFd"); - return DUMP_POLL_FD; + if (!collectAllTidStack && (remainTime == DUMPCATCHER_REMOTE_P90_TIMEOUT)) { + AsyncGetAllTidKernelStack(pid_); + collectAllTidStack = true; + } + remainTime = static_cast(endTime - now); + return true; + } else { + ret = DUMP_POLL_FAILED; + resMsg.append("Result: poll error, errno(" + std::to_string(errno) + ")\n"); + return false; + } +} + +bool DfxDumpCatcher::DoPollRetEQZero(std::string &resMsg, const int timeout, int &remainTime, + bool &collectAllTidStack, int &ret) +{ + if (!collectAllTidStack && (remainTime == DUMPCATCHER_REMOTE_P90_TIMEOUT)) { + AsyncGetAllTidKernelStack(pid_); + remainTime = timeout - DUMPCATCHER_REMOTE_P90_TIMEOUT; + collectAllTidStack = true; + return true; + } + ret = DUMP_POLL_TIMEOUT; + resMsg.append("Result: poll timeout.\n"); + return false; +} + +bool DfxDumpCatcher::DoEventsPoll(std::vector fds, std::vector &messages, + std::vector &readfds, bool &bPipeConnect, bool &res) +{ + bool bufRet = true; + bool resRet = false; + bool eventRet = true; + for (auto readfd : readfds) { + if (!bPipeConnect && ((uint32_t)readfd.revents & POLLIN)) { + bPipeConnect = true; + } + + if (bPipeConnect && + (((uint32_t)readfd.revents & POLLERR) || ((uint32_t)readfd.revents & POLLHUP))) { + eventRet = false; + // messages[1]: resMsg + (messages[1]).append("Result: poll events error.\n"); + break; + } + + if (((uint32_t)readfd.revents & POLLIN) != POLLIN) { + continue; + } + + if (readfd.fd == fds[0]) { + // fds[0]: bufFd + // messages[0]: bufMsg + bufRet = DoReadBuf(fds[0], messages[0]); + } else if (readfd.fd == fds[1]) { + // fds[1]: resFd + // messages[1]: resMsg + resRet = DoReadRes(fds[1], res, messages[1]); + } + } + + if ((eventRet == false) || (bufRet == false) || (resRet == true)) { + DFXLOGI("%{public}s :: %{public}s :: eventRet(%{public}d) bufRet: %{public}d resRet: %{public}d", + DFXDUMPCATCHER_TAG.c_str(), __func__, eventRet, bufRet, resRet); + return false; + } + return true; +} + +void DfxDumpCatcher::DumpRemotePoll(std::vector fds, std::vector &messages, + const int timeout, bool &res, int &ret) +{ + std::vector readfds; + for (auto fd : fds) { + readfds.push_back({fd, POLLIN, 0}); } - int ret = DUMP_POLL_INIT; - std::string resMsg; - bool res = false; - std::string bufMsg; - struct pollfd readfds[2]; - (void)memset_s(readfds, sizeof(readfds), 0, sizeof(readfds)); - readfds[0].fd = bufFd; - readfds[0].events = POLLIN; - readfds[1].fd = resFd; - readfds[1].events = POLLIN; - int fdsSize = sizeof(readfds) / sizeof(readfds[0]); bool bPipeConnect = false; int remainTime = DUMPCATCHER_REMOTE_P90_TIMEOUT; bool collectAllTidStack = false; uint64_t startTime = GetAbsTimeMilliSeconds(); uint64_t endTime = startTime + static_cast(timeout); - while (true) { - int pollRet = poll(readfds, fdsSize, remainTime); - if (pollRet < 0 && errno == EINTR) { - uint64_t now = GetAbsTimeMilliSeconds(); - if (now >= endTime) { - ret = DUMP_POLL_TIMEOUT; - resMsg.append("Result: poll timeout.\n"); - break; - } - if (!collectAllTidStack && (remainTime == DUMPCATCHER_REMOTE_P90_TIMEOUT)) { - AsyncGetAllTidKernelStack(pid_); - collectAllTidStack = true; - } - remainTime = static_cast(endTime - now); + bool isContinue = true; + while (isContinue) { + int pollRet = poll(readfds.data(), readfds.size(), remainTime); + if (pollRet < 0) { + // messages[1]: resMsg + isContinue = DoPollRetLEZero(messages[1], endTime, remainTime, collectAllTidStack, ret); continue; - } else if (pollRet < 0) { - ret = DUMP_POLL_FAILED; - resMsg.append("Result: poll error, errno(" + std::to_string(errno) + ")\n"); - break; } else if (pollRet == 0) { - if (!collectAllTidStack && (remainTime == DUMPCATCHER_REMOTE_P90_TIMEOUT)) { - AsyncGetAllTidKernelStack(pid_); - remainTime = timeout - DUMPCATCHER_REMOTE_P90_TIMEOUT; - collectAllTidStack = true; - continue; - } - ret = DUMP_POLL_TIMEOUT; - resMsg.append("Result: poll timeout.\n"); - break; - } - - bool bufRet = true; - bool resRet = false; - bool eventRet = true; - for (int i = 0; i < fdsSize; ++i) { - if (!bPipeConnect && ((uint32_t)readfds[i].revents & POLLIN)) { - bPipeConnect = true; - } - if (bPipeConnect && - (((uint32_t)readfds[i].revents & POLLERR) || ((uint32_t)readfds[i].revents & POLLHUP))) { - eventRet = false; - resMsg.append("Result: poll events error.\n"); - break; - } - - if (((uint32_t)readfds[i].revents & POLLIN) != POLLIN) { - continue; - } - - if (readfds[i].fd == bufFd) { - bufRet = DoReadBuf(bufFd, bufMsg); - continue; - } - - if (readfds[i].fd == resFd) { - resRet = DoReadRes(resFd, res, resMsg); - } + // messages[1]: resMsg + isContinue = DoPollRetEQZero(messages[1], timeout, remainTime, collectAllTidStack, ret); + continue; } - if ((eventRet == false) || (bufRet == false) || (resRet == true)) { - DFXLOGI("%{public}s :: %{public}s :: eventRet(%{public}d) bufRet: %{public}d resRet: %{public}d", - DFXDUMPCATCHER_TAG.c_str(), __func__, eventRet, bufRet, resRet); + if (!DoEventsPoll(fds, messages, readfds, bPipeConnect, res)) { ret = DUMP_POLL_RETURN; break; } uint64_t now = GetAbsTimeMilliSeconds(); if (now >= endTime) { ret = DUMP_POLL_TIMEOUT; - resMsg.append("Result: poll timeout.\n"); + // messages[1]: resMsg + messages[1].append("Result: poll timeout.\n"); break; } remainTime = static_cast(endTime - now); } +} - DFXLOGI("%{public}s :: %{public}s :: %{public}s", DFXDUMPCATCHER_TAG.c_str(), __func__, resMsg.c_str()); - msg = isJson && res ? bufMsg : (resMsg + bufMsg); +int DfxDumpCatcher::DoDumpRemotePoll(int bufFd, int resFd, int timeout, std::string& msg, bool isJson) +{ + DFX_TRACE_SCOPED_DLSYM("DoDumpRemotePoll"); + if (bufFd < 0 || resFd < 0) { + if (!isJson) { + msg = "Result: bufFd or resFd < 0.\n"; + } + DFXLOGE("invalid bufFd or resFd"); + return DUMP_POLL_FD; + } + int ret = DUMP_POLL_INIT; + bool res = false; + std::vector fds = {bufFd, resFd}; + // messages[0]: bufMsg + // messages[1]: resMsg + std::vector messages(fds.size(), ""); + DumpRemotePoll(fds, messages, timeout, res, ret); + + DFXLOGI("%{public}s :: %{public}s :: %{public}s", DFXDUMPCATCHER_TAG.c_str(), __func__, messages[1].c_str()); + msg = isJson && res ? messages[0] : (messages[1] + messages[0]); return res ? DUMP_POLL_OK : ret; } diff --git a/interfaces/innerkits/dump_catcher/include/dfx_dump_catcher.h b/interfaces/innerkits/dump_catcher/include/dfx_dump_catcher.h index c6552349..53cde8db 100644 --- a/interfaces/innerkits/dump_catcher/include/dfx_dump_catcher.h +++ b/interfaces/innerkits/dump_catcher/include/dfx_dump_catcher.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -89,6 +90,14 @@ private: bool DoDumpCatchRemote(int pid, int tid, std::string& msg, bool isJson = false, int timeout = DUMPCATCHER_REMOTE_TIMEOUT); int DoDumpRemotePid(int pid, std::string& msg, bool isJson = false, int32_t timeout = DUMPCATCHER_REMOTE_TIMEOUT); + bool DoPollRetLEZero(std::string &resMsg, const uint64_t endTime, + int &remainTime, bool &collectAllTidStack, int &ret); + bool DoPollRetEQZero(std::string &resMsg, const int timeout, + int &remainTime, bool &collectAllTidStack, int &ret); + bool DoEventsPoll(std::vector fds, std::vector &messages, + std::vector &readfds, bool &bPipeConnect, bool &res); + void DumpRemotePoll(std::vector fds, std::vector &messages, + const int timeout, bool &res, int &ret); int DoDumpRemotePoll(int bufFd, int resFd, int timeout, std::string& msg, bool isJson = false); bool DoReadBuf(int fd, std::string& msg); bool DoReadRes(int fd, bool &ret, std::string& msg); -- Gitee From 68a22819a5a40c5467cd0d41c7f2750dd2abe199 Mon Sep 17 00:00:00 2001 From: wangqing Date: Thu, 21 Nov 2024 14:15:59 +0800 Subject: [PATCH 12/13] fix DwarfSection::FillInCie bug Signed-off-by: wangqing Change-Id: I37f5b7276715805eeff24c213c6901902cf5e1d7 --- interfaces/innerkits/unwinder/dwarf_section.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interfaces/innerkits/unwinder/dwarf_section.cpp b/interfaces/innerkits/unwinder/dwarf_section.cpp index 1ecdf83f..acb46ce9 100644 --- a/interfaces/innerkits/unwinder/dwarf_section.cpp +++ b/interfaces/innerkits/unwinder/dwarf_section.cpp @@ -297,7 +297,7 @@ void DwarfSection::SaveAugStr(uintptr_t& ptr, std::vector& augStr) { uint8_t ch; augStr.clear(); - while (memory_->Read(ptr, &ch, true) && ch == '\0') { + while (memory_->Read(ptr, &ch, true) && ch != '\0') { augStr.push_back(ch); } } -- Gitee From a0046903685248eaf6e5dff9fe7630e2ef9a093e Mon Sep 17 00:00:00 2001 From: wangqing Date: Fri, 22 Nov 2024 11:09:30 +0800 Subject: [PATCH 13/13] fix DfxDumpCatcher::DoDumpRemotePoll bug and cleancode Signed-off-by: wangqing Change-Id: I305f70aac43f541df6680c62619ced91366e5aaf --- .../dump_catcher/dfx_dump_catcher.cpp | 21 +++++++++++-------- .../dump_catcher/include/dfx_dump_catcher.h | 2 +- interfaces/innerkits/unwinder/arm_exidx.cpp | 2 +- interfaces/innerkits/unwinder/dfx_config.cpp | 12 +++++------ interfaces/innerkits/unwinder/dfx_elf.cpp | 2 +- .../innerkits/unwinder/dfx_elf_parser.cpp | 4 ++-- interfaces/innerkits/unwinder/dfx_memory.cpp | 4 ++-- .../innerkits/unwinder/dwarf_section.cpp | 4 ++-- .../innerkits/unwinder/include/dfx_config.h | 2 +- .../innerkits/unwinder/include/dfx_elf.h | 4 ++-- .../unwinder/include/dfx_elf_parser.h | 4 ++-- .../innerkits/unwinder/include/dfx_memory.h | 4 ++-- .../unwinder/include/dwarf_section.h | 4 ++-- 13 files changed, 36 insertions(+), 33 deletions(-) diff --git a/interfaces/innerkits/dump_catcher/dfx_dump_catcher.cpp b/interfaces/innerkits/dump_catcher/dfx_dump_catcher.cpp index 3577eb4e..7eccc99d 100644 --- a/interfaces/innerkits/dump_catcher/dfx_dump_catcher.cpp +++ b/interfaces/innerkits/dump_catcher/dfx_dump_catcher.cpp @@ -471,7 +471,7 @@ bool DfxDumpCatcher::DoPollRetEQZero(std::string &resMsg, const int timeout, int } bool DfxDumpCatcher::DoEventsPoll(std::vector fds, std::vector &messages, - std::vector &readfds, bool &bPipeConnect, bool &res) + std::vector readfds, bool &bPipeConnect, bool &res) { bool bufRet = true; bool resRet = false; @@ -515,10 +515,13 @@ bool DfxDumpCatcher::DoEventsPoll(std::vector fds, std::vector void DfxDumpCatcher::DumpRemotePoll(std::vector fds, std::vector &messages, const int timeout, bool &res, int &ret) { - std::vector readfds; - for (auto fd : fds) { - readfds.push_back({fd, POLLIN, 0}); - } + struct pollfd readfds[2]; + (void)memset_s(readfds, sizeof(readfds), 0, sizeof(readfds)); + readfds[0].fd = fds[0]; + readfds[0].events = POLLIN; + readfds[1].fd = fds[1]; + readfds[1].events = POLLIN; + int fdsSize = sizeof(readfds) / sizeof(readfds[0]); bool bPipeConnect = false; int remainTime = DUMPCATCHER_REMOTE_P90_TIMEOUT; bool collectAllTidStack = false; @@ -526,7 +529,7 @@ void DfxDumpCatcher::DumpRemotePoll(std::vector fds, std::vector(timeout); bool isContinue = true; while (isContinue) { - int pollRet = poll(readfds.data(), readfds.size(), remainTime); + int pollRet = poll(readfds, fdsSize, remainTime); if (pollRet < 0) { // messages[1]: resMsg isContinue = DoPollRetLEZero(messages[1], endTime, remainTime, collectAllTidStack, ret); @@ -536,8 +539,8 @@ void DfxDumpCatcher::DumpRemotePoll(std::vector fds, std::vector vecReadfds(readfds, readfds + 2); + if (!DoEventsPoll(fds, messages, vecReadfds, bPipeConnect, res)) { ret = DUMP_POLL_RETURN; break; } @@ -552,7 +555,7 @@ void DfxDumpCatcher::DumpRemotePoll(std::vector fds, std::vector fds, std::vector &messages, - std::vector &readfds, bool &bPipeConnect, bool &res); + std::vector readfds, bool &bPipeConnect, bool &res); void DumpRemotePoll(std::vector fds, std::vector &messages, const int timeout, bool &res, int &ret); int DoDumpRemotePoll(int bufFd, int resFd, int timeout, std::string& msg, bool isJson = false); diff --git a/interfaces/innerkits/unwinder/arm_exidx.cpp b/interfaces/innerkits/unwinder/arm_exidx.cpp index 4297eb0a..d90ff6cb 100644 --- a/interfaces/innerkits/unwinder/arm_exidx.cpp +++ b/interfaces/innerkits/unwinder/arm_exidx.cpp @@ -241,7 +241,7 @@ bool ArmExidx::ExtractEntryData(uintptr_t entryOffset) return ExtractEntryTab(extabAddr); } -bool ArmExidx::ExtractEntryTabByPersonality(uintptr_t& tabOffset, uint32_t& data, uint8_t& tableCount) +bool ArmExidx::ExtractEntryTabByPersonality(uintptr_t &tabOffset, uint32_t &data, uint8_t &tableCount) { if ((data & ARM_EXIDX_COMPACT) == 0) { DFXLOGU("Arm generic personality, data: %{public}x.", data); diff --git a/interfaces/innerkits/unwinder/dfx_config.cpp b/interfaces/innerkits/unwinder/dfx_config.cpp index 0f50dd57..5b47bdc1 100644 --- a/interfaces/innerkits/unwinder/dfx_config.cpp +++ b/interfaces/innerkits/unwinder/dfx_config.cpp @@ -36,11 +36,11 @@ namespace { const char FAULTLOGGER_CONF_PATH[] = "/system/etc/faultlogger.conf"; const int CONF_LINE_SIZE = 256; -auto g_boolConfigParser = [](bool* configProp, const std::string& value) { +auto g_boolConfigParser = [](bool *configProp, const std::string &value) { *configProp = (value != "false"); }; -auto g_uintConfigParser = [](unsigned int* configProp, const std::string& value) { +auto g_uintConfigParser = [](unsigned int *configProp, const std::string &value) { unsigned int propValue = static_cast(atoi(value.data())); if (propValue != 0) { *configProp = propValue; @@ -48,7 +48,7 @@ auto g_uintConfigParser = [](unsigned int* configProp, const std::string& value) }; } -DfxConfigInfo& DfxConfig::GetConfig() +DfxConfigInfo &DfxConfig::GetConfig() { static DfxConfigInfo config; static std::once_flag flag; @@ -58,7 +58,7 @@ DfxConfigInfo& DfxConfig::GetConfig() return config; } -void DfxConfig::ReadAndParseConfig(DfxConfigInfo& config) +void DfxConfig::ReadAndParseConfig(DfxConfigInfo &config) { FILE *fp = nullptr; char codeBuffer[CONF_LINE_SIZE] = {0}; @@ -67,14 +67,14 @@ void DfxConfig::ReadAndParseConfig(DfxConfigInfo& config) DFXLOGW("Failed to open %{public}s. Reason: %{public}s.", FAULTLOGGER_CONF_PATH, strerror(errno)); return; } - std::map boolConfig = { + std::map boolConfig = { {std::string("displayRegister"), &(config.displayRegister)}, {std::string("displayBacktrace"), &(config.displayBacktrace)}, {std::string("displayMaps"), &(config.displayMaps)}, {std::string("displayFaultStack.switch"), &(config.displayFaultStack)}, {std::string("dumpOtherThreads"), &(config.dumpOtherThreads)}, }; - std::map uintConfig = { + std::map uintConfig = { {std::string("displayFaultStack.lowAddressStep"), &(config.lowAddressStep)}, {std::string("displayFaultStack.highAddressStep"), &(config.highAddressStep)}, {std::string("maxFrameNums"), &(config.maxFrameNums)}, diff --git a/interfaces/innerkits/unwinder/dfx_elf.cpp b/interfaces/innerkits/unwinder/dfx_elf.cpp index 9d1e7e24..8745b909 100644 --- a/interfaces/innerkits/unwinder/dfx_elf.cpp +++ b/interfaces/innerkits/unwinder/dfx_elf.cpp @@ -916,7 +916,7 @@ bool DfxElf::ProccessDynamic(const ElfW(Phdr) *pDynamic, ElfW(Addr) loadBase, Un return true; } -void DfxElf::InitHdr(struct DwarfEhFrameHdr **hdr, struct DwarfEhFrameHdr& synthHdr, +void DfxElf::InitHdr(struct DwarfEhFrameHdr **hdr, struct DwarfEhFrameHdr &synthHdr, struct dl_phdr_info *info, const ElfW(Phdr) *pEhHdr) { if (pEhHdr) { diff --git a/interfaces/innerkits/unwinder/dfx_elf_parser.cpp b/interfaces/innerkits/unwinder/dfx_elf_parser.cpp index 4a3ca23e..dddff82f 100644 --- a/interfaces/innerkits/unwinder/dfx_elf_parser.cpp +++ b/interfaces/innerkits/unwinder/dfx_elf_parser.cpp @@ -169,7 +169,7 @@ std::shared_ptr ElfParser::GetMiniDebugInfo() } template -bool ElfParser::ExtractSectionHeadersInfo(const EhdrType& ehdr, ShdrType& shdr) +bool ElfParser::ExtractSectionHeadersInfo(const EhdrType &ehdr, ShdrType &shdr) { uint64_t offset = ehdr.e_shoff; offset += ehdr.e_shentsize; @@ -222,7 +222,7 @@ bool ElfParser::ExtractSectionHeadersInfo(const EhdrType& ehdr, ShdrType& shdr) } template -bool ElfParser::ParseSectionHeaders(const EhdrType& ehdr) +bool ElfParser::ParseSectionHeaders(const EhdrType &ehdr) { ShdrType shdr; //section header string table index. include section header table with section name string table. diff --git a/interfaces/innerkits/unwinder/dfx_memory.cpp b/interfaces/innerkits/unwinder/dfx_memory.cpp index b4401d72..9f84af15 100644 --- a/interfaces/innerkits/unwinder/dfx_memory.cpp +++ b/interfaces/innerkits/unwinder/dfx_memory.cpp @@ -210,7 +210,7 @@ size_t DfxMemory::GetEncodedSize(uint8_t encoding) } } -void DfxMemory::ReadFormatEncodedValue(uintptr_t& addr, uintptr_t& val, uint8_t formatEncoding) +void DfxMemory::ReadFormatEncodedValue(uintptr_t &addr, uintptr_t &val, uint8_t formatEncoding) { switch (formatEncoding) { case DW_EH_PE_uleb128: @@ -249,7 +249,7 @@ void DfxMemory::ReadFormatEncodedValue(uintptr_t& addr, uintptr_t& val, uint8_t } } -uintptr_t DfxMemory::ReadEncodedValue(uintptr_t& addr, uint8_t encoding) +uintptr_t DfxMemory::ReadEncodedValue(uintptr_t &addr, uint8_t encoding) { uintptr_t startAddr = addr; uintptr_t val = 0; diff --git a/interfaces/innerkits/unwinder/dwarf_section.cpp b/interfaces/innerkits/unwinder/dwarf_section.cpp index acb46ce9..c2460d00 100644 --- a/interfaces/innerkits/unwinder/dwarf_section.cpp +++ b/interfaces/innerkits/unwinder/dwarf_section.cpp @@ -293,7 +293,7 @@ bool DwarfSection::ParseCie(uintptr_t cieAddr, uintptr_t ciePtr, CommonInfoEntry return true; } -void DwarfSection::SaveAugStr(uintptr_t& ptr, std::vector& augStr) +void DwarfSection::SaveAugStr(uintptr_t &ptr, std::vector &augStr) { uint8_t ch; augStr.clear(); @@ -302,7 +302,7 @@ void DwarfSection::SaveAugStr(uintptr_t& ptr, std::vector& augStr) } } -void DwarfSection::ParseAugData(uintptr_t& ptr, CommonInfoEntry &cieInfo, const std::vector& augStr) +void DwarfSection::ParseAugData(uintptr_t &ptr, CommonInfoEntry &cieInfo, const std::vector &augStr) { MAYBE_UNUSED uintptr_t augSize = memory_->ReadUleb128(ptr); DFXLOGU("augSize: %{public}" PRIxPTR "", augSize); diff --git a/interfaces/innerkits/unwinder/include/dfx_config.h b/interfaces/innerkits/unwinder/include/dfx_config.h index 05cce65b..bd6fa44e 100644 --- a/interfaces/innerkits/unwinder/include/dfx_config.h +++ b/interfaces/innerkits/unwinder/include/dfx_config.h @@ -32,7 +32,7 @@ class DfxConfig { public: static DfxConfigInfo& GetConfig(); private: - static void ReadAndParseConfig(DfxConfigInfo& config); + static void ReadAndParseConfig(DfxConfigInfo &config); private: DfxConfig() = default; ~DfxConfig() = default; diff --git a/interfaces/innerkits/unwinder/include/dfx_elf.h b/interfaces/innerkits/unwinder/include/dfx_elf.h index 79dd5c90..31fadfda 100644 --- a/interfaces/innerkits/unwinder/include/dfx_elf.h +++ b/interfaces/innerkits/unwinder/include/dfx_elf.h @@ -95,9 +95,9 @@ protected: bool InitEmbeddedElf(); #if is_ohos && !is_mingw static int DlPhdrCb(struct dl_phdr_info *info, size_t size, void *data); - static void ParsePhdr(struct dl_phdr_info *info, std::vector& pHdrSections, const uintptr_t pc); + static void ParsePhdr(struct dl_phdr_info *info, std::vector &pHdrSections, const uintptr_t pc); static bool ProccessDynamic(const ElfW(Phdr) *pDynamic, ElfW(Addr) loadBase, UnwindTableInfo *uti); - static void InitHdr(struct DwarfEhFrameHdr **hdr, struct DwarfEhFrameHdr& synthHdr, + static void InitHdr(struct DwarfEhFrameHdr **hdr, struct DwarfEhFrameHdr &synthHdr, struct dl_phdr_info *info, const ElfW(Phdr) *pEhHdr); static bool FindSection(struct dl_phdr_info *info, const std::string secName, ShdrInfo& shdr); static bool FillUnwindTableByEhhdrLocal(struct DwarfEhFrameHdr* hdr, struct UnwindTableInfo* uti); diff --git a/interfaces/innerkits/unwinder/include/dfx_elf_parser.h b/interfaces/innerkits/unwinder/include/dfx_elf_parser.h index 8a7a3fc3..0870943d 100644 --- a/interfaces/innerkits/unwinder/include/dfx_elf_parser.h +++ b/interfaces/innerkits/unwinder/include/dfx_elf_parser.h @@ -71,9 +71,9 @@ protected: template bool ParseProgramHeaders(const EhdrType& ehdr); template - bool ExtractSectionHeadersInfo(const EhdrType& ehdr, ShdrType& shdr); + bool ExtractSectionHeadersInfo(const EhdrType &ehdr, ShdrType &shdr); template - bool ParseSectionHeaders(const EhdrType& ehdr); + bool ParseSectionHeaders(const EhdrType &ehdr); template bool IsFunc(const SymType sym); template diff --git a/interfaces/innerkits/unwinder/include/dfx_memory.h b/interfaces/innerkits/unwinder/include/dfx_memory.h index 2794db82..2d610361 100644 --- a/interfaces/innerkits/unwinder/include/dfx_memory.h +++ b/interfaces/innerkits/unwinder/include/dfx_memory.h @@ -68,8 +68,8 @@ public: virtual void SetDataOffset(uintptr_t offset) { dataOffset_ = offset; } virtual void SetFuncOffset(uintptr_t offset) { funcOffset_ = offset; } virtual size_t GetEncodedSize(uint8_t encoding); - virtual uintptr_t ReadEncodedValue(uintptr_t& addr, uint8_t encoding); - virtual void ReadFormatEncodedValue(uintptr_t& addr, uintptr_t& val, uint8_t formatEncoding); + virtual uintptr_t ReadEncodedValue(uintptr_t &addr, uint8_t encoding); + virtual void ReadFormatEncodedValue(uintptr_t &addr, uintptr_t &val, uint8_t formatEncoding); #if is_ohos && !is_mingw static size_t ReadProcMemByPid(const pid_t pid, const uint64_t addr, void* data, size_t size); #endif diff --git a/interfaces/innerkits/unwinder/include/dwarf_section.h b/interfaces/innerkits/unwinder/include/dwarf_section.h index 316c503a..8a9a3d6c 100644 --- a/interfaces/innerkits/unwinder/include/dwarf_section.h +++ b/interfaces/innerkits/unwinder/include/dwarf_section.h @@ -45,8 +45,8 @@ protected: bool FillInFde(uintptr_t ptr, FrameDescEntry &fdeInfo); bool ParseCie(uintptr_t cieAddr, uintptr_t ciePtr, CommonInfoEntry &cieInfo); bool FillInCie(uintptr_t ptr, CommonInfoEntry &cieInfo); - void SaveAugStr(uintptr_t& ptr, std::vector& augStr); - void ParseAugData(uintptr_t& ptr, CommonInfoEntry &cieInfo, const std::vector& augStr); + void SaveAugStr(uintptr_t &ptr, std::vector &augStr); + void ParseAugData(uintptr_t &ptr, CommonInfoEntry &cieInfo, const std::vector &augStr); protected: std::shared_ptr memory_; -- Gitee