diff --git a/ecmascript/dfx/hprof/rawheap_translate/rawheap_translate.cpp b/ecmascript/dfx/hprof/rawheap_translate/rawheap_translate.cpp old mode 100644 new mode 100755 index 5ddf6dabe384a59d143b05bb15d5bf5d56ac97b8..af2806cfb588381c70487f789fd16420aaee3bc1 --- a/ecmascript/dfx/hprof/rawheap_translate/rawheap_translate.cpp +++ b/ecmascript/dfx/hprof/rawheap_translate/rawheap_translate.cpp @@ -281,7 +281,7 @@ bool RawHeapTranslateV1::ReadStringTable(FileReader &file) bool RawHeapTranslateV1::ReadObjectTable(FileReader &file, uint32_t offset, uint32_t totalSize) { - if (!file.CheckAndGetHeaderAt(offset, sizeof(AddrTableItem))) { + if (!file.CheckAndGetHeaderAt(offset, 0) || file.GetHeaderRight() < sizeof(AddrTableItem)) { LOG_ERROR_ << "object table header error!"; return false; } @@ -298,25 +298,25 @@ bool RawHeapTranslateV1::ReadObjectTable(FileReader &file, uint32_t offset, uint mem_.push_back(mem); char *data = objTableData.data(); for (uint32_t i = 0; i < file.GetHeaderLeft(); ++i) { - uint64_t addr = ByteToU64(data); + AddrTableItem table = { + ByteToU64(data), // addr + ByteToU64(data + sizeof(uint64_t)), // id + ByteToU32(data + sizeof(uint64_t) * 2), // objSize + ByteToU32(data + sizeof(uint64_t) * 2 + sizeof(uint32_t)) // offset + }; + uint64_t addr = table.addr; Node *node = FindOrCreateNode(addr); - data += sizeof(uint64_t); - - node->nodeId = ByteToU64(data); - data += sizeof(uint64_t); - - node->size = ByteToU32(data); - data += sizeof(uint32_t); - - uint32_t memOffset = ByteToU32(data) - tableSize; - data += sizeof(uint32_t); + node->nodeId = table.id; + node->size = table.objSize; + uint32_t memOffset = table.offset - tableSize; if (memOffset + sizeof(uint64_t) > memSize) { LOG_ERROR_ << "object memory offset error!"; return false; } node->data = mem + memOffset; + data += file.GetHeaderRight(); } LOG_INFO_ << "section objects count " << file.GetHeaderLeft(); return true; @@ -614,13 +614,13 @@ bool RawHeapTranslateV2::ReadStringTable(FileReader &file) bool RawHeapTranslateV2::ReadObjectTable(FileReader &file) { // 4: index in sections means the offset of object table - if (!file.CheckAndGetHeaderAt(sections_[4], sizeof(AddrTableItemV2))) { + if (!file.CheckAndGetHeaderAt(sections_[4], 0) || file.GetHeaderRight() < sizeof(AddrTableItemV2)) { LOG_ERROR_ << "object table header error!"; return false; } syntheticRoot_ = CreateNode(); - uint32_t tableSize = file.GetHeaderLeft() * sizeof(AddrTableItemV2); + uint32_t tableSize = file.GetHeaderLeft() * file.GetHeaderRight(); // 5: index in sections means the total size of object table memSize_ = sections_[5] - tableSize - sizeof(uint64_t); std::vector objTableData(tableSize); @@ -646,7 +646,7 @@ bool RawHeapTranslateV2::ReadObjectTable(FileReader &file) node->nodeId = table.nodeId; node->nativeSize = table.nativeSize; node->jsType = static_cast(table.type); - tableData += sizeof(AddrTableItemV2); + tableData += file.GetHeaderRight(); } LOG_INFO_ << "objects table count " << file.GetHeaderLeft(); diff --git a/ecmascript/dfx/hprof/tests/heap_dump_test.cpp b/ecmascript/dfx/hprof/tests/heap_dump_test.cpp index 577780c47917d123c84c59165444b0364bf7bc87..bb5ae380a26428c380073354698898b209514ec8 100644 --- a/ecmascript/dfx/hprof/tests/heap_dump_test.cpp +++ b/ecmascript/dfx/hprof/tests/heap_dump_test.cpp @@ -264,6 +264,28 @@ public: return false; // Lost the Line } + bool ReadRawHeapSectionInfo(std::string &filePath, std::vector §ion) + { + uint64_t fileSize = rawheap_translate::FileReader::GetFileSize(filePath); + rawheap_translate::FileReader file; + if (!file.Initialize(filePath) || !file.CheckAndGetHeaderAt(file.GetFileSize() - sizeof(uint64_t), 0)) { + return false; + } + if (!file.CheckAndGetHeaderAt(fileSize - sizeof(uint64_t), sizeof(uint32_t))) { + GTEST_LOG_(ERROR) << "sections header error!"; + return false; + } + + uint32_t sectionHeaderOffset = fileSize - (file.GetHeaderLeft() + 2) * sizeof(uint32_t); + section.resize(file.GetHeaderLeft()); + if (!file.Seek(sectionHeaderOffset) || !file.ReadArray(section, file.GetHeaderLeft())) { + GTEST_LOG_(ERROR) << "read sections error!"; + return false; + } + + return true; + } + JSHandle CreateNumberTypedArray(JSType jsType) { JSHandle env = instance->GetGlobalEnv(); @@ -1678,6 +1700,32 @@ HWTEST_F_L0(HeapDumpTest, TestGenerateMixedNodeId) ASSERT_TRUE(tester.GenerateRawHeapSnashot(rawHeapPath, dumpOption)); ASSERT_TRUE(tester.CheckHashInNodeId(thread_, vec, rawHeapPath)); } + +HWTEST_F_L0(HeapDumpTest, TestDecodeRawheapAddrTableItemSizeMin) +{ + ObjectFactory *factory = ecmaVm_->GetFactory(); + HeapDumpTestHelper tester(ecmaVm_); + std::vector vec; + CreateObjectsForBinaryDump(thread_, factory, &tester, vec); + + std::string rawHeapPath("test_binary_dump_addrtable_size_min.rawheap"); + DumpSnapShotOption dumpOption; + ASSERT_TRUE(tester.GenerateRawHeapSnashot(rawHeapPath, dumpOption)); + + std::vector sections; + ASSERT_TRUE(tester.ReadRawHeapSectionInfo(rawHeapPath, sections)); + + FILE* fd = std::fopen(rawHeapPath.c_str(), "rb+"); + ASSERT_TRUE(fd != nullptr); + uint32_t testUnitSize = sizeof(uint64_t) - 1; + std::fseek(fd, sections[4] + sizeof(uint32_t), SEEK_SET); + std::fwrite(reinterpret_cast(&testUnitSize), sizeof(testUnitSize), sizeof(testUnitSize), fd); + std::fclose(fd); + + std::string heapsnapshotPath("test_binary_dump_addrtable_size_min.heapsnapshot"); + ASSERT_TRUE(tester.AddMetaDataJsonToRawheap(rawHeapPath)); + ASSERT_FALSE(tester.DecodeRawheap(rawHeapPath, heapsnapshotPath)); +} #endif HWTEST_F_L0(HeapDumpTest, TestSharedFullGCInHeapDump)