diff --git a/interfaces/common/dfx_socket_request.h b/interfaces/common/dfx_socket_request.h index 3008c4c797c4c25743866739f6d053adbd49b531..0c3f7018ad8142b28cf692bf750dc4c6bac6d1d8 100644 --- a/interfaces/common/dfx_socket_request.h +++ b/interfaces/common/dfx_socket_request.h @@ -261,6 +261,8 @@ typedef enum ResponseCode : int32_t { CORE_DUMP_NOPROC, /** cancel coredump */ CORE_DUMP_CANCEL, + /** coredump generate fail */ + CORE_DUMP_GENERATE_FAIL, } ResponseCode; #ifdef __cplusplus diff --git a/test/unittest/process_dump/BUILD.gn b/test/unittest/process_dump/BUILD.gn index adbf9eb32d70e30d54aea3193b92a06e4d9fd101..4a76ad7c687b18142d58e78d8a41c5f78f91e006 100644 --- a/test/unittest/process_dump/BUILD.gn +++ b/test/unittest/process_dump/BUILD.gn @@ -31,6 +31,7 @@ if (defined(ohos_lite)) { "$faultloggerd_path/example", "$faultloggerd_path/test/utils", "$faultloggerd_path/tools/process_dump", + "$faultloggerd_path/tools/process_dump/coredump", "$hilog_lite_include_path", ] @@ -70,6 +71,7 @@ if (defined(ohos_lite)) { "$faultloggerd_path/example", "$faultloggerd_path/test/utils", "$faultloggerd_path/tools/process_dump", + "$faultloggerd_path/tools/process_dump/coredump", ] } @@ -78,6 +80,8 @@ if (defined(ohos_lite)) { ohos_unittest("test_processdump") { module_out_path = module_output_path sources = [ + "dfx_coredump_test.cpp", + "dfx_coredump_writer_test.cpp", "dfx_processdump_test.cpp", "dump_info_header_test.cpp", "dump_utils_test.cpp", diff --git a/test/unittest/process_dump/dfx_coredump_test.cpp b/test/unittest/process_dump/dfx_coredump_test.cpp index 21ee3ed90caa66fb824eb1b89c07bd78cd58d2a8..3e96d9222048580d53a7ccbd1a5a3df318fb45cf 100644 --- a/test/unittest/process_dump/dfx_coredump_test.cpp +++ b/test/unittest/process_dump/dfx_coredump_test.cpp @@ -92,7 +92,7 @@ HWTEST_F(DfxCoreDumpTest, DfxCoreDumpTest003, TestSize.Level2) auto pid = getpid(); auto tid = gettid(); CoreDumpService coreDumpService = CoreDumpService(pid, tid); - auto bundleName = coreDumpService.GetBundleName(); + auto bundleName = coreDumpService.GetBundleNameItem(); ASSERT_TRUE(bundleName.empty()); GTEST_LOG_(INFO) << "DfxCoreDumpTest003: end."; #endif @@ -147,8 +147,8 @@ HWTEST_F(DfxCoreDumpTest, DfxCoreDumpTest006, TestSize.Level2) auto tid = gettid(); CoreDumpService coreDumpService = CoreDumpService(pid, tid); std::string line = "5a0eb08000-5a0eb09000 r-xp 00007000 00:00 0 /system/lib/test.z.so"; - struct DumpMemoryRegions region; - coreDumpService.ObtainDumpRegion(line.c_str(), ®ion); + DumpMemoryRegions region; + coreDumpService.ObtainDumpRegion(line, region); ASSERT_EQ(region.memorySizeHex, 0x1000); GTEST_LOG_(INFO) << "DfxCoreDumpTest006: end."; #endif diff --git a/test/unittest/process_dump/dfx_coredump_writer_test.cpp b/test/unittest/process_dump/dfx_coredump_writer_test.cpp index 6ea197aa7c7ed618b0b0d61582210fdaa2b77aea..a0ef69a0e8e53796f9250fb21b95e9824e89f30a 100644 --- a/test/unittest/process_dump/dfx_coredump_writer_test.cpp +++ b/test/unittest/process_dump/dfx_coredump_writer_test.cpp @@ -62,7 +62,7 @@ HWTEST_F(DfxCoreDumpWriterTest, DfxCoreDumpWriterTest001, TestSize.Level2) .memorySizeHex = 0x1000 }; std::vector maps = { dummyRegion }; - ProgramSegmentHeaderWriter writer(mappedMemory, currentPointer, &phNum, maps); + ProgramSegmentHeaderWriter writer(mappedMemory, currentPointer, phNum, maps); currentPointer = writer.Write(); @@ -75,7 +75,7 @@ HWTEST_F(DfxCoreDumpWriterTest, DfxCoreDumpWriterTest001, TestSize.Level2) /** * @tc.name: DfxCoreDumpWriterTest002 - * @tc.desc: test SegmentWriter + * @tc.desc: test LoadSegmentWriter * @tc.type: FUNC */ HWTEST_F(DfxCoreDumpWriterTest, DfxCoreDumpWriterTest002, TestSize.Level2) @@ -102,7 +102,7 @@ HWTEST_F(DfxCoreDumpWriterTest, DfxCoreDumpWriterTest002, TestSize.Level2) pid_t testPid = getpid(); Elf64_Half phNum = 2; - SegmentWriter writer(mappedMemory, currentPointer, testPid, phNum); + LoadSegmentWriter writer(mappedMemory, currentPointer, testPid, phNum); char* result = writer.Write(); @@ -136,7 +136,7 @@ HWTEST_F(DfxCoreDumpWriterTest, DfxCoreDumpWriterTest003, TestSize.Level2) /** * @tc.name: DfxCoreDumpWriterTest004 - * @tc.desc: test NoteWriter + * @tc.desc: test NoteSegmentWriter * @tc.type: FUNC */ HWTEST_F(DfxCoreDumpWriterTest, DfxCoreDumpWriterTest004, TestSize.Level2) @@ -160,7 +160,7 @@ HWTEST_F(DfxCoreDumpWriterTest, DfxCoreDumpWriterTest004, TestSize.Level2) std::vector maps = { dummyRegion }; std::shared_ptr regs = DfxRegs::Create(); - NoteWriter writer(mappedMemory, currentPointer, coreDumpThread, maps, regs); + NoteSegmentWriter writer(mappedMemory, currentPointer, coreDumpThread, maps, regs); char* result = writer.Write(); ASSERT_TRUE(static_cast(currentPointer) != static_cast(result)); diff --git a/tools/process_dump/BUILD.gn b/tools/process_dump/BUILD.gn index 4e2d4e6839be46c72aab922cf202318d82c0526b..45b6dfdabf81805044410e994057a71ae2ba55bb 100644 --- a/tools/process_dump/BUILD.gn +++ b/tools/process_dump/BUILD.gn @@ -14,9 +14,9 @@ import("//base/hiviewdfx/faultloggerd/faultloggerd.gni") processdump_sources = [ + "coredump/dfx_coredump_writer.cpp", + "coredump/dfx_coredump_service.cpp", "dfx_buffer_writer.cpp", - "dfx_coredump_writer.cpp", - "dfx_coredump_service.cpp", "dfx_process.cpp", "dfx_thread.cpp", "dump_info_header.cpp", @@ -50,6 +50,7 @@ if (defined(ohos_lite)) { include_dirs = [ ".", + "coredump", "$c_utils_include_path", "$faultloggerd_common_path/dfxlog", "$faultloggerd_common_path/dfxutil", @@ -108,6 +109,7 @@ if (defined(ohos_lite)) { include_dirs = [ ".", + "coredump", "$faultloggerd_interfaces_path/common", "$faultloggerd_interfaces_path/innerkits/backtrace/include", "$faultloggerd_interfaces_path/innerkits/crash_exception", diff --git a/tools/process_dump/dfx_coredump_common.h b/tools/process_dump/coredump/dfx_coredump_common.h similarity index 100% rename from tools/process_dump/dfx_coredump_common.h rename to tools/process_dump/coredump/dfx_coredump_common.h diff --git a/tools/process_dump/dfx_coredump_service.cpp b/tools/process_dump/coredump/dfx_coredump_service.cpp similarity index 61% rename from tools/process_dump/dfx_coredump_service.cpp rename to tools/process_dump/coredump/dfx_coredump_service.cpp index 1f0232c43e65fc8265932a84720e1f94c4a70245..f550438ebdbe5d4cbdeee6e948661bff9a2b41bd 100644 --- a/tools/process_dump/dfx_coredump_service.cpp +++ b/tools/process_dump/coredump/dfx_coredump_service.cpp @@ -19,6 +19,7 @@ #include #include "dfx_define.h" #include "dfx_log.h" +#include "dump_utils.h" #include "faultloggerd_client.h" #include "securec.h" #ifndef is_ohos_lite @@ -28,12 +29,11 @@ namespace OHOS { namespace HiviewDFX { namespace { - const char *const COREDUMP_DIR_PATH = "/data/storage/el2/base/files"; const char *const COREDUMP_HAP_WHITE_LIST = "const.dfx.coredump.hap_list"; -const char *const DEFAULT_BUNDLE_NAME = ""; const char *const HWASAN_COREDUMP_ENABLE = "faultloggerd.priv.hwasan_coredump.enabled"; char g_coredumpFilePath[256] = {0}; +static const int ARG2 = 2; static const int ARG16 = 16; static const int ARG100 = 100; static const int ARG1000 = 1000; @@ -48,6 +48,37 @@ static std::string GetCoredumpWhiteList() #endif return ""; } + +void HandleSigterm(int sig) +{ + unlink(g_coredumpFilePath); + _exit(0); +} + +int UnBlockSIGTERM() +{ + sigset_t set; + sigemptyset(&set); + sigaddset(&set, DUMPCATCHER_TIMEOUT); + sigprocmask(SIG_UNBLOCK, &set, nullptr); + return 0; +} + +int RegisterCancelCoredump(std::string logPath) +{ + auto ret = strncpy_s(g_coredumpFilePath, sizeof(g_coredumpFilePath), logPath.c_str(), logPath.length()); + if (ret != 0) { + DFXLOGE("strncpy_s fail, err:%{public}d", ret); + return -1; + } + + UnBlockSIGTERM(); + if (signal(DUMPCATCHER_TIMEOUT, HandleSigterm) == SIG_ERR) { + DFXLOGE("Failed to register handler for DUMPCATCHER_TIMEOUT"); + return -1; + } + return 0; +} } bool CoreDumpService::IsHwasanCoredumpEnabled() @@ -60,17 +91,57 @@ bool CoreDumpService::IsHwasanCoredumpEnabled() #endif } +bool CoreDumpService::IsCoredumpSignal(const ProcessDumpRequest& request) +{ + return request.siginfo.si_signo == 42 && request.siginfo.si_code == 3; // 42 3 +} + CoreDumpService::CoreDumpService(int32_t targetPid, int32_t targetTid) { coreDumpThread_.targetPid = targetPid; coreDumpThread_.targetTid = targetTid; } +CoreDumpService::CoreDumpService(int32_t targetPid, int32_t targetTid, std::shared_ptr keyRegs) +{ + coreDumpThread_.targetPid = targetPid; + coreDumpThread_.targetTid = targetTid; + keyRegs_ = keyRegs; +} + +CoreDumpService::~CoreDumpService() +{ + DeInit(); +} + void CoreDumpService::SetVmPid(int32_t vmPid) { coreDumpThread_.vmPid = vmPid; } +void CoreDumpService::StartFirstStageDump() +{ + StartCoreDump(); + WriteSegmentHeader(); + WriteNoteSegment(); +} + +void CoreDumpService::StartSecondStageDump(int32_t vmPid, const ProcessDumpRequest& request) +{ + coreDumpThread_.vmPid = vmPid; + int pid = coreDumpThread_.targetPid; + WriteLoadSegment(); + WriteSectionHeader(); + auto ret = FinishCoreDump(); + std::string bundleName = ret ? GetBundleNameItem() + ".dmp" : ""; + int32_t retCode = ret ? ResponseCode::REQUEST_SUCCESS : ResponseCode::CORE_DUMP_GENERATE_FAIL; + FinishCoredumpCb(pid, bundleName, retCode); + if (IsHwasanCoredumpEnabled()) { + DumpUtils::InfoCrashUnwindResult(request, true); + } + _exit(0); +} + std::string CoreDumpService::GetBundleNameItem() { return bundleName_; @@ -83,51 +154,49 @@ CoreDumpThread CoreDumpService::GetCoreDumpThread() bool CoreDumpService::StartCoreDump() { - Init(); + DFXLOGI("Begin to start coredump"); + if (status_ != WriteStatus::START_STAGE) { + DFXLOGE("The status is not START_STAGE!"); + return false; + } if (!CreateFile()) { return false; } if (!MmapForFd()) { return false; } + status_ = WriteStatus::WRITE_SEGMENT_HEADER_STAGE; return true; } -void CoreDumpService::StopCoreDump() -{ - DeInit(); -} - -void CoreDumpService::Init() +bool CoreDumpService::FinishCoreDump() { - fd_ = -1; - mappedMemory_ = nullptr; - currentPointer_ = nullptr; - ePhnum_ = 0; - coreFileSize_ = 0; - status_ = WriteStatus::INIT_STAGE; + DFXLOGI("Coredump end: pid = %{public}d, elapsed time = %{public}" PRId64 "ms", + coreDumpThread_.targetPid, counter_.Elapsed()); + if (status_ != WriteStatus::STOP_STAGE) { + DFXLOGE("The status is not STOP_STAGE!"); + return false; + } + status_ = WriteStatus::DONE_STAGE; + return true; } void CoreDumpService::DeInit() { - if (status_ != WriteStatus::DEINIT_STAGE) { - DFXLOGE("The status is not DEINIT_STAGE!"); - return; - } - if (fd_ != 0) { + if (fd_ != -1) { close(fd_); - fd_ = 0; + fd_ = -1; } if (mappedMemory_ != nullptr) { munmap(static_cast(mappedMemory_), coreFileSize_); + mappedMemory_ = nullptr; } - status_ = WriteStatus::DONE_STAGE; } bool CoreDumpService::CreateFile() { - if (status_ != WriteStatus::INIT_STAGE || coreDumpThread_.targetPid == 0) { - DFXLOGE("The status is not INIT_STAGE!"); + if (coreDumpThread_.targetPid == 0) { + DFXLOGE("The targetPid is 0!"); return false; } coreFileSize_ = GetCoreFileSize(coreDumpThread_.targetPid); @@ -140,59 +209,62 @@ bool CoreDumpService::CreateFile() DFXLOGE("create file fail"); return false; } - DFXLOGI("create coredump file success"); - status_ = WriteStatus::MMAP_STAGE; return true; } bool CoreDumpService::MmapForFd() { - if (status_ != WriteStatus::MMAP_STAGE) { - DFXLOGE("The status is not MMAP_STAGE!"); + if (fd_ == -1) { + DFXLOGE("The fd is invalid, not to mmap"); + return false; + } + if (coreFileSize_ == 0) { + DFXLOGE("The coreFileSize is 0, not to mmap"); return false; } if (ftruncate(fd_, coreFileSize_) == -1) { DFXLOGE("ftruncate fail"); close(fd_); - fd_ = 0; + fd_ = -1; return false; } mappedMemory_ = static_cast(mmap(nullptr, coreFileSize_, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, 0)); if (mappedMemory_ == MAP_FAILED) { DFXLOGE("mmap fail"); close(fd_); - fd_ = 0; + fd_ = -1; mappedMemory_ = nullptr; return false; } DFXLOGI("mmap success"); - status_ = WriteStatus::WRITE_SEGMENT_HEADER_STAGE; return true; } bool CoreDumpService::WriteSegmentHeader() { + DFXLOGI("Begin to Write segment header"); if (status_ != WriteStatus::WRITE_SEGMENT_HEADER_STAGE) { DFXLOGE("The status is not WRITE_SEGMENT_HEADER_STAGE!"); return false; } currentPointer_ = mappedMemory_; currentPointer_ += sizeof(Elf64_Ehdr); - ProgramSegmentHeaderWriter programSegmentHeader(mappedMemory_, currentPointer_, &ePhnum_, maps_); + ProgramSegmentHeaderWriter programSegmentHeader(mappedMemory_, currentPointer_, ePhnum_, maps_); currentPointer_ = programSegmentHeader.Write(); Elf64_Ehdr eh; - ElfHeaderFill(&eh, ePhnum_, ePhnum_ + 2, ePhnum_ + 1); // 2 + ElfHeaderFill(eh, ePhnum_); if (memcpy_s(mappedMemory_, sizeof(eh), reinterpret_cast(&eh), sizeof(eh)) != EOK) { DFXLOGE("memcpy fail"); return false; } - status_ = WriteStatus::WRITE_NOTE_STAGE; + status_ = WriteStatus::WRITE_NOTE_SEGMENT_STAGE; return true; } -bool CoreDumpService::WriteNote() +bool CoreDumpService::WriteNoteSegment() { - if (status_ != WriteStatus::WRITE_NOTE_STAGE) { + DFXLOGI("Begin to Write note segment"); + if (status_ != WriteStatus::WRITE_NOTE_SEGMENT_STAGE) { DFXLOGE("The status is not WRITE_NOTE_STAGE!"); return false; } @@ -201,15 +273,16 @@ bool CoreDumpService::WriteNote() return false; } - NoteWriter note(mappedMemory_, currentPointer_, coreDumpThread_, maps_, keyRegs_); + NoteSegmentWriter note(mappedMemory_, currentPointer_, coreDumpThread_, maps_, keyRegs_); currentPointer_ = note.Write(); - status_ = WriteStatus::WRITE_SEGMENT_STAGE; + status_ = WriteStatus::WRITE_LOAD_SEGMENT_STAGE; return true; } -bool CoreDumpService::WriteSegment() +bool CoreDumpService::WriteLoadSegment() { - if (status_ != WriteStatus::WRITE_SEGMENT_STAGE) { + DFXLOGI("Begin to Write load segment"); + if (status_ != WriteStatus::WRITE_LOAD_SEGMENT_STAGE) { DFXLOGE("The status is not WRITE_SEGMENT_STAGE!"); return false; } @@ -217,7 +290,7 @@ bool CoreDumpService::WriteSegment() DFXLOGE("vmPid is 0!"); return false; } - SegmentWriter segment(mappedMemory_, currentPointer_, coreDumpThread_.vmPid, ePhnum_); + LoadSegmentWriter segment(mappedMemory_, currentPointer_, coreDumpThread_.vmPid, ePhnum_); currentPointer_ = segment.Write(); status_ = WriteStatus::WRITE_SECTION_HEADER_STAGE; return true; @@ -225,84 +298,53 @@ bool CoreDumpService::WriteSegment() bool CoreDumpService::WriteSectionHeader() { + DFXLOGI("Begin to Write section header"); if (status_ != WriteStatus::WRITE_SECTION_HEADER_STAGE) { DFXLOGE("The status is not WRITE_SECTION_HEADER_STAGE!"); return false; } SectionHeaderTableWriter sectionHeaderTable(mappedMemory_, currentPointer_); currentPointer_ = sectionHeaderTable.Write(); - status_ = WriteStatus::DEINIT_STAGE; + status_ = WriteStatus::STOP_STAGE; return true; } -void CoreDumpService::ElfHeaderFill(Elf64_Ehdr* eh, uint16_t ePhnum, uint16_t eShnum, uint16_t eShstrndx) +void CoreDumpService::ElfHeaderFill(Elf64_Ehdr &eh, uint16_t ePhnum) { - eh->e_ident[EI_MAG0] = ELFMAG0; - eh->e_ident[EI_MAG1] = ELFMAG1; - eh->e_ident[EI_MAG2] = ELFMAG2; - eh->e_ident[EI_MAG3] = ELFMAG3; - eh->e_ident[EI_CLASS] = ELFCLASS64; - eh->e_ident[EI_DATA] = ELFDATA2LSB; - eh->e_ident[EI_VERSION] = EV_CURRENT; - eh->e_ident[EI_OSABI] = ELFOSABI_NONE; - eh->e_ident[EI_ABIVERSION] = 0x00; - eh->e_ident[EI_PAD] = 0x00; - eh->e_ident[10] = 0x00; // 10 - eh->e_ident[11] = 0x00; // 11 - eh->e_ident[12] = 0x00; // 12 - eh->e_ident[13] = 0x00; // 13 - eh->e_ident[14] = 0x00; // 14 - eh->e_ident[15] = 0x00; // 15 - eh->e_type = ET_CORE; - eh->e_machine = EM_AARCH64; - eh->e_version = EV_CURRENT; - eh->e_entry = 0x00; - eh->e_phoff = sizeof(Elf64_Ehdr); - eh->e_shoff = sizeof(Elf64_Shdr); - eh->e_flags = 0x00; - eh->e_ehsize = sizeof(Elf64_Ehdr); - eh->e_phentsize = sizeof(Elf64_Phdr); - eh->e_phnum = ePhnum; - eh->e_shentsize = sizeof(Elf64_Shdr); - eh->e_shnum = eShnum; - eh->e_shstrndx = eShstrndx; -} - -void HandleSigterm(int sig) -{ - unlink(g_coredumpFilePath); - _exit(0); -} - -int UnBlockSIGTERM() -{ - sigset_t set; - sigemptyset(&set); - sigaddset(&set, DUMPCATCHER_TIMEOUT); - sigprocmask(SIG_UNBLOCK, &set, nullptr); - - return 0; -} - -int RegisterCancelCoredump(std::string logPath) -{ - auto ret = strncpy_s(g_coredumpFilePath, sizeof(g_coredumpFilePath), logPath.c_str(), logPath.length()); - if (ret != 0) { - DFXLOGE("strncpy_s fail, err:%{public}d", ret); - return -1; - } - - UnBlockSIGTERM(); - if (signal(DUMPCATCHER_TIMEOUT, HandleSigterm) == SIG_ERR) { - DFXLOGE("Failed to register handler for DUMPCATCHER_TIMEOUT"); - return -1; - } - return 0; + eh.e_ident[EI_MAG0] = ELFMAG0; + eh.e_ident[EI_MAG1] = ELFMAG1; + eh.e_ident[EI_MAG2] = ELFMAG2; + eh.e_ident[EI_MAG3] = ELFMAG3; + eh.e_ident[EI_CLASS] = ELFCLASS64; + eh.e_ident[EI_DATA] = ELFDATA2LSB; + eh.e_ident[EI_VERSION] = EV_CURRENT; + eh.e_ident[EI_OSABI] = ELFOSABI_NONE; + eh.e_ident[EI_ABIVERSION] = 0x00; + eh.e_ident[EI_PAD] = 0x00; + eh.e_ident[10] = 0x00; // 10 + eh.e_ident[11] = 0x00; // 11 + eh.e_ident[12] = 0x00; // 12 + eh.e_ident[13] = 0x00; // 13 + eh.e_ident[14] = 0x00; // 14 + eh.e_ident[15] = 0x00; // 15 + eh.e_type = ET_CORE; + eh.e_machine = EM_AARCH64; + eh.e_version = EV_CURRENT; + eh.e_entry = 0x00; + eh.e_phoff = sizeof(Elf64_Ehdr); + eh.e_shoff = sizeof(Elf64_Shdr); + eh.e_flags = 0x00; + eh.e_ehsize = sizeof(Elf64_Ehdr); + eh.e_phentsize = sizeof(Elf64_Phdr); + eh.e_phnum = ePhnum; + eh.e_shentsize = sizeof(Elf64_Shdr); + eh.e_shnum = ePhnum + ARG2; + eh.e_shstrndx = ePhnum + 1; } int CoreDumpService::CreateFileForCoreDump() { - bundleName_ = GetBundleName(); + bundleName_ = DumpUtils::GetSelfBundleName(); if (bundleName_.empty()) { DFXLOGE("query bundleName fail"); return INVALID_FD; @@ -355,10 +397,10 @@ uint64_t CoreDumpService::GetCoreFileSize(pid_t pid) std::string line; uint16_t lineNumber = 0; - struct DumpMemoryRegions region; + DumpMemoryRegions region; while (getline(file, line)) { lineNumber += 1; - ObtainDumpRegion(line.c_str(), ®ion); + ObtainDumpRegion(line, region); maps_.push_back(region); if (!strcmp(region.pathName, "[vvar]") || region.priority[0] != 'r') { continue; @@ -373,63 +415,25 @@ uint64_t CoreDumpService::GetCoreFileSize(pid_t pid) return coreFileSize; } -void CoreDumpService::ObtainDumpRegion(const char *line, DumpMemoryRegions *region) +void CoreDumpService::ObtainDumpRegion(std::string &line, DumpMemoryRegions ®ion) { - auto ret = sscanf_s(line, "%[^-\n]-%[^ ] %s %s %s %u %[^\n]", - region->start, sizeof(region->start), - region->end, sizeof(region->end), - region->priority, sizeof(region->priority), - region->offset, sizeof(region->offset), - region->dev, sizeof(region->dev), - &(region->inode), - region->pathName, sizeof(region->pathName)); + auto ret = sscanf_s(line.c_str(), "%[^-\n]-%[^ ] %s %s %s %u %[^\n]", + region.start, sizeof(region.start), + region.end, sizeof(region.end), + region.priority, sizeof(region.priority), + region.offset, sizeof(region.offset), + region.dev, sizeof(region.dev), + &(region.inode), + region.pathName, sizeof(region.pathName)); if (ret != 7) { // 7 - region->pathName[0] = '\0'; + region.pathName[0] = '\0'; } - region->startHex = strtoul(region->start, nullptr, ARG16); - region->endHex = strtoul(region->end, nullptr, ARG16); - region->offsetHex = strtoul(region->offset, nullptr, ARG16); - region->memorySizeHex = region->endHex - region->startHex; -} - -std::string CoreDumpService::GetBundleName() -{ -#ifndef is_ohos_lite - auto bundleInstance = GetBundleManager(); - if (bundleInstance == nullptr) { - DFXLOGE("bundleInstance is nullptr"); - return DEFAULT_BUNDLE_NAME; - } - AppExecFwk::BundleInfo bundleInfo; - auto ret = bundleInstance->GetBundleInfoForSelf(0, bundleInfo); - if (ret != ERR_OK) { - DFXLOGE("GetBundleInfoForSelf failed! ret = %{public}d", ret); - return DEFAULT_BUNDLE_NAME; - } - return bundleInfo.name; -#endif - return DEFAULT_BUNDLE_NAME; -} - -#ifndef is_ohos_lite -sptr CoreDumpService::GetBundleManager() -{ - auto systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - if (!systemManager) { - DFXLOGE("Get system ability manager failed"); - return nullptr; - } - auto remoteObject = systemManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); - if (!remoteObject) { - DFXLOGE("Get system ability failed"); - return nullptr; - } - sptr bundleMgrProxy = iface_cast(remoteObject); - return bundleMgrProxy; + region.startHex = strtoul(region.start, nullptr, ARG16); + region.endHex = strtoul(region.end, nullptr, ARG16); + region.offsetHex = strtoul(region.offset, nullptr, ARG16); + region.memorySizeHex = region.endHex - region.startHex; } -#endif - } // namespace HiviewDFX } // namespace OHOS #endif \ No newline at end of file diff --git a/tools/process_dump/dfx_coredump_service.h b/tools/process_dump/coredump/dfx_coredump_service.h similarity index 67% rename from tools/process_dump/dfx_coredump_service.h rename to tools/process_dump/coredump/dfx_coredump_service.h index 15f1f1fb802797c685a5b7c68fffaf87119966a7..cf0262770b96e4b993f00a5c77851b531a0e3726 100644 --- a/tools/process_dump/dfx_coredump_service.h +++ b/tools/process_dump/coredump/dfx_coredump_service.h @@ -16,70 +16,65 @@ #define DFX_COREDUMP_SERVICE_H #if defined(__aarch64__) -#ifndef is_ohos_lite -#include "bundle_mgr_interface.h" -#include "bundle_mgr_proxy.h" -#include "if_system_ability_manager.h" -#include "iservice_registry.h" -#include "system_ability_definition.h" -#endif #include "dfx_coredump_common.h" #include "dfx_coredump_writer.h" +#include "dfx_dump_request.h" #include "dfx_regs.h" +#include "elapsed_time.h" namespace OHOS { namespace HiviewDFX { -std::string GetBundleName(); - class CoreDumpService { public: CoreDumpService() = default; CoreDumpService(int32_t targetPid, int32_t targetTid); + CoreDumpService(int32_t targetPid, int32_t targetTid, std::shared_ptr keyRegs); CoreDumpService(const CoreDumpService&) = delete; + CoreDumpService &operator=(const CoreDumpService&) = delete; + ~CoreDumpService(); bool StartCoreDump(); - void StopCoreDump(); + bool FinishCoreDump(); bool WriteSegmentHeader(); - bool WriteNote(); - bool WriteSegment(); + bool WriteNoteSegment(); + bool WriteLoadSegment(); bool WriteSectionHeader(); void SetVmPid(int32_t vmPid); + void StartFirstStageDump(); + void StartSecondStageDump(int32_t vmPid, const ProcessDumpRequest& request); CoreDumpThread GetCoreDumpThread(); std::string GetBundleNameItem(); - std::string GetBundleName(); - std::shared_ptr keyRegs_; static bool IsHwasanCoredumpEnabled(); + static bool IsCoredumpSignal(const ProcessDumpRequest& request); private: - enum class WriteStatus { - INIT_STAGE, - MMAP_STAGE, - WRITE_SEGMENT_HEADER_STAGE, - WRITE_NOTE_STAGE, - WRITE_SEGMENT_STAGE, - WRITE_SECTION_HEADER_STAGE, - DEINIT_STAGE, - DONE_STAGE, - }; - void Init(); void DeInit(); + void ObtainDumpRegion(std::string &line, DumpMemoryRegions ®ion); + void ElfHeaderFill(Elf64_Ehdr &eh, uint16_t ePhnum); bool CreateFile(); bool MmapForFd(); bool VerifyTrustlist(); int CreateFileForCoreDump(); uint64_t GetCoreFileSize(pid_t pid); - void ObtainDumpRegion(const char *line, DumpMemoryRegions *region); - void ElfHeaderFill(Elf64_Ehdr* eh, uint16_t ePhnum, uint16_t eShnum, uint16_t eShstrndx); -#ifndef is_ohos_lite - sptr GetBundleManager(); -#endif +private: + enum class WriteStatus { + START_STAGE, + WRITE_SEGMENT_HEADER_STAGE, + WRITE_NOTE_SEGMENT_STAGE, + WRITE_LOAD_SEGMENT_STAGE, + WRITE_SECTION_HEADER_STAGE, + STOP_STAGE, + DONE_STAGE, + }; int fd_ {-1}; uint64_t coreFileSize_ {0}; + Elf64_Half ePhnum_ {0}; std::vector maps_; - char *mappedMemory_ {nullptr}; std::string bundleName_; + char *mappedMemory_ {nullptr}; char *currentPointer_ {nullptr}; - Elf64_Half ePhnum_ {0}; - WriteStatus status_ = WriteStatus::INIT_STAGE; + WriteStatus status_ = WriteStatus::START_STAGE; CoreDumpThread coreDumpThread_; + ElapsedTime counter_; + std::shared_ptr keyRegs_; }; } // namespace HiviewDFX } // namespace OHOS diff --git a/tools/process_dump/dfx_coredump_writer.cpp b/tools/process_dump/coredump/dfx_coredump_writer.cpp similarity index 68% rename from tools/process_dump/dfx_coredump_writer.cpp rename to tools/process_dump/coredump/dfx_coredump_writer.cpp index b296551a1f32072beb4ce31c88f29ac64670a858..fcb3c54a0bc9badea153de43f7e8739a46073422 100644 --- a/tools/process_dump/dfx_coredump_writer.cpp +++ b/tools/process_dump/coredump/dfx_coredump_writer.cpp @@ -43,14 +43,18 @@ namespace OHOS { namespace HiviewDFX { - static const char NOTE_NAME_CORE[8] = "CORE"; static const char NOTE_NAME_LINUX[8] = "LINUX"; +const char *const UID = "Uid:"; +const char *const GID = "Gid:"; +const char *const PPID = "PPid:"; +const char *const SIGPND = "SigPnd:"; +const char *const SIGBLK = "SigBlk:"; char* ProgramSegmentHeaderWriter::Write() { Elf64_Phdr ptNote; - PtNoteFill(&ptNote); + PtNoteFill(ptNote); if (!CopyAndAdvance(&ptNote, sizeof(ptNote))) { DFXLOGE("Write ptNote fail, errno:%{public}d", errno); @@ -60,11 +64,11 @@ char* ProgramSegmentHeaderWriter::Write() Elf64_Phdr ptLoad; Elf64_Half lineNumber = 1; - for (const auto& region : maps_) { + for (const auto ®ion : maps_) { if (!strcmp(region.pathName, "[vvar]") || (region.priority[0] != 'r')) { continue; } - PtLoadFill(&ptLoad, region); + PtLoadFill(ptLoad, region); if (!CopyAndAdvance(&ptLoad, sizeof(ptLoad))) { DFXLOGE("Write ptLoad fail, errno:%{public}d", errno); return currentPointer_; @@ -100,11 +104,11 @@ char* ProgramSegmentHeaderWriter::Write() *pOffset = pOffsetValueLast + *pFileszLast; - *ePhnum_ = lineNumber; + ePhnum_ = lineNumber; return currentPointer_; } -void ProgramSegmentHeaderWriter::PtLoadFill(Elf64_Phdr *ph, struct DumpMemoryRegions region) +void ProgramSegmentHeaderWriter::PtLoadFill(Elf64_Phdr &ph, const DumpMemoryRegions ®ion) { Elf64_Word pFlags = 0x00; if (region.priority[0] == 'r' || region.priority[0] == '-') { @@ -119,7 +123,7 @@ void ProgramSegmentHeaderWriter::PtLoadFill(Elf64_Phdr *ph, struct DumpMemoryReg ProgramSegmentHeaderFill(ph, PT_LOAD, pFlags, region); } -void ProgramSegmentHeaderWriter::PtNoteFill(Elf64_Phdr *ph) +void ProgramSegmentHeaderWriter::PtNoteFill(Elf64_Phdr &ph) { struct DumpMemoryRegions region; Elf64_Word pFlags = PF_R; @@ -129,49 +133,52 @@ void ProgramSegmentHeaderWriter::PtNoteFill(Elf64_Phdr *ph) ProgramSegmentHeaderFill(ph, PT_NOTE, pFlags, region); } -void ProgramSegmentHeaderWriter::ProgramSegmentHeaderFill(Elf64_Phdr *ph, Elf64_Word pType, - Elf64_Word pFlags, struct DumpMemoryRegions region) +void ProgramSegmentHeaderWriter::ProgramSegmentHeaderFill(Elf64_Phdr &ph, Elf64_Word pType, + Elf64_Word pFlags, const DumpMemoryRegions ®ion) { - ph->p_type = pType; - ph->p_flags = pFlags; - ph->p_offset = sizeof(Elf64_Ehdr); - ph->p_vaddr = region.startHex; - ph->p_paddr = 0x00; - ph->p_filesz = region.memorySizeHex; - ph->p_memsz = ph->p_filesz; - ph->p_align = 0x1; + ph.p_type = pType; + ph.p_flags = pFlags; + ph.p_offset = sizeof(Elf64_Ehdr); + ph.p_vaddr = region.startHex; + ph.p_paddr = 0x00; + ph.p_filesz = region.memorySizeHex; + ph.p_memsz = ph.p_filesz; + ph.p_align = 0x1; } -char* SegmentWriter::Write() +char* LoadSegmentWriter::Write() { char *ptLoadAddr = mappedMemory_ + sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr); Elf64_Phdr *ptLoad = reinterpret_cast(ptLoadAddr); + if (ptLoad == nullptr) { + return currentPointer_; + } for (Elf64_Half i = 0; i < (ePhnum_ - 1); i++) { - ReadProcessVmmem(ptLoad); + ReadProcessVmmem(*ptLoad); ptLoad += 1; } return currentPointer_; } -void SegmentWriter::ReadProcessVmmem(Elf64_Phdr *ptLoad) +void LoadSegmentWriter::ReadProcessVmmem(Elf64_Phdr &ptLoad) { struct iovec local[1]; struct iovec remote[1]; local[0].iov_base = currentPointer_; - local[0].iov_len = ptLoad->p_memsz; + local[0].iov_len = ptLoad.p_memsz; - remote[0].iov_base = reinterpret_cast(ptLoad->p_vaddr); - remote[0].iov_len = ptLoad->p_memsz; + remote[0].iov_base = reinterpret_cast(ptLoad.p_vaddr); + remote[0].iov_len = ptLoad.p_memsz; ssize_t nread = process_vm_readv(pid_, local, 1, remote, 1, 0); if (nread == -1) { - (void)memset_s(currentPointer_, ptLoad->p_memsz, -1, ptLoad->p_memsz); + (void)memset_s(currentPointer_, ptLoad.p_memsz, -1, ptLoad.p_memsz); } - ptLoad->p_offset = reinterpret_cast(currentPointer_) - reinterpret_cast(mappedMemory_); - currentPointer_ += ptLoad->p_memsz; + ptLoad.p_offset = reinterpret_cast(currentPointer_) - reinterpret_cast(mappedMemory_); + currentPointer_ += ptLoad.p_memsz; } -char* NoteWriter::Write() +char* NoteSegmentWriter::Write() { char *noteStart = currentPointer_; PrpsinfoWrite(); @@ -187,11 +194,11 @@ char* NoteWriter::Write() return currentPointer_; } -bool NoteWriter::PrpsinfoWrite() +bool NoteSegmentWriter::PrpsinfoWrite() { - NoteWrite(NT_PRPSINFO, sizeof(struct elf_prpsinfo), NOTE_NAME_CORE); - struct elf_prpsinfo ntPrpsinfo; - FillPrpsinfo(&ntPrpsinfo); + NoteWrite(NT_PRPSINFO, sizeof(prpsinfo_t), NOTE_NAME_CORE); + prpsinfo_t ntPrpsinfo; + FillPrpsinfo(ntPrpsinfo); if (!CopyAndAdvance(&ntPrpsinfo, sizeof(ntPrpsinfo))) { DFXLOGE("Write ntPrpsinfo fail, errno:%{public}d", errno); return false; @@ -199,18 +206,23 @@ bool NoteWriter::PrpsinfoWrite() return true; } -void NoteWriter::FillPrpsinfo(struct elf_prpsinfo *ntPrpsinfo) +void NoteSegmentWriter::FillPrpsinfo(prpsinfo_t &ntPrpsinfo) { - if (ntPrpsinfo == nullptr) { - return; + if (!ReadProcessStat(ntPrpsinfo)) { + DFXLOGE("Read targetPid process stat fail!"); + } + if (!ReadProcessStatus(ntPrpsinfo)) { + DFXLOGE("Read targetPid process status fail!"); + } + if (!ReadProcessComm(ntPrpsinfo)) { + DFXLOGE("Read targetPid process comm fail!"); + } + if (!ReadProcessCmdline(ntPrpsinfo)) { + DFXLOGE("Read targetPid process cmdline fail!"); } - ReadProcessStat(ntPrpsinfo); - ReadProcessStatus(ntPrpsinfo); - ReadProcessComm(ntPrpsinfo); - ReadProcessCmdline(ntPrpsinfo); } -bool NoteWriter::NoteWrite(uint32_t noteType, size_t descSize, const char* noteName) +bool NoteSegmentWriter::NoteWrite(uint32_t noteType, size_t descSize, const char* noteName) { Elf64_Nhdr note; note.n_namesz = strlen(noteName) + 1; @@ -229,19 +241,19 @@ bool NoteWriter::NoteWrite(uint32_t noteType, size_t descSize, const char* noteN return true; } -void NoteWriter::ReadProcessStat(struct elf_prpsinfo *ntPrpsinfo) +bool NoteSegmentWriter::ReadProcessStat(prpsinfo_t &ntPrpsinfo) { std::string filePath = "/proc/" + std::to_string(pid_) + "/stat"; std::ifstream statFile(filePath); if (!statFile.is_open()) { DFXLOGE("open %{public}s fail, errno:%{public}d", filePath.c_str(), errno); - return; + return false; } std::string line; if (!std::getline(statFile, line)) { DFXLOGE("read %{public}s fail, errno:%{public}d", filePath.c_str(), errno); - return; + return false; } std::istringstream iss(line); @@ -260,16 +272,17 @@ void NoteWriter::ReadProcessStat(struct elf_prpsinfo *ntPrpsinfo) iss >> prFlag; - ntPrpsinfo->pr_state = state; - ntPrpsinfo->pr_sname = state; - ntPrpsinfo->pr_zomb = (state == 'Z') ? 1 : 0; - ntPrpsinfo->pr_flag = prFlag; + ntPrpsinfo.pr_state = state; + ntPrpsinfo.pr_sname = state; + ntPrpsinfo.pr_zomb = (state == 'Z') ? 1 : 0; + ntPrpsinfo.pr_flag = prFlag; statFile.close(); + return true; } -void NoteWriter::ReadProcessStatus(struct elf_prpsinfo *ntPrpsinfo) +bool NoteSegmentWriter::ReadProcessStatus(prpsinfo_t &ntPrpsinfo) { - ntPrpsinfo->pr_nice = getpriority(PRIO_PROCESS, pid_); + ntPrpsinfo.pr_nice = getpriority(PRIO_PROCESS, pid_); unsigned int prUid = 0; unsigned int prGid = 0; int prPpid = 0; @@ -279,54 +292,58 @@ void NoteWriter::ReadProcessStatus(struct elf_prpsinfo *ntPrpsinfo) FILE *file = fopen(filePath.c_str(), "r"); if (!file) { DFXLOGE("open %{public}s fail, errno:%{public}d", filePath.c_str(), errno); - return; + return false; } while (fgets(buffer, sizeof(buffer), file) != nullptr) { - if (strncmp(buffer, "Uid:", 4) == 0) { // 4 - if (sscanf_s(buffer + 4, "%u", &prUid) != 1) { // 4 + if (strncmp(buffer, UID, strlen(UID)) == 0) { + if (sscanf_s(buffer + strlen(UID), "%u", &prUid) != 1) { continue; } - } else if (strncmp(buffer, "Gid:", 4) == 0) { // 4 - if (sscanf_s(buffer + 4, "%u", &prGid) != 1) { // 4 + } else if (strncmp(buffer, GID, strlen(GID)) == 0) { + if (sscanf_s(buffer + strlen(GID), "%u", &prGid) != 1) { continue; } - } else if (strncmp(buffer, "PPid:", 5) == 0) { // 5 - if (sscanf_s(buffer + 5, "%d", &prPpid) != 1) { // 5 + } else if (strncmp(buffer, PPID, strlen(PPID)) == 0) { + if (sscanf_s(buffer + strlen(PPID), "%d", &prPpid) != 1) { continue; } } } (void)fclose(file); - ntPrpsinfo->pr_uid = prUid; - ntPrpsinfo->pr_gid = prGid; - ntPrpsinfo->pr_pid = pid_; - ntPrpsinfo->pr_ppid = prPpid; - ntPrpsinfo->pr_pgrp = getpgrp(); - ntPrpsinfo->pr_sid = getsid(ntPrpsinfo->pr_pid); + ntPrpsinfo.pr_uid = prUid; + ntPrpsinfo.pr_gid = prGid; + ntPrpsinfo.pr_pid = pid_; + ntPrpsinfo.pr_ppid = prPpid; + ntPrpsinfo.pr_pgrp = getpgrp(); + ntPrpsinfo.pr_sid = getsid(ntPrpsinfo.pr_pid); + return true; } -void NoteWriter::ReadProcessComm(struct elf_prpsinfo *ntPrpsinfo) +bool NoteSegmentWriter::ReadProcessComm(prpsinfo_t &ntPrpsinfo) { std::string filePath = "/proc/" + std::to_string(pid_) + "/comm"; FILE *file = fopen(filePath.c_str(), "r"); if (!file) { DFXLOGE("open %{public}s fail, errno:%{public}d", filePath.c_str(), errno); - return; + return false; } - if (fgets(ntPrpsinfo->pr_fname, sizeof(ntPrpsinfo->pr_fname), file) == nullptr) { + if (fgets(ntPrpsinfo.pr_fname, sizeof(ntPrpsinfo.pr_fname), file) == nullptr) { DFXLOGE("read comm fail, errno:%{public}d", errno); + (void)fclose(file); + return false; } (void)fclose(file); + return true; } -void NoteWriter::ReadProcessCmdline(struct elf_prpsinfo *ntPrpsinfo) +bool NoteSegmentWriter::ReadProcessCmdline(prpsinfo_t &ntPrpsinfo) { std::string filePath = "/proc/" + std::to_string(pid_) + "/cmdline"; FILE *file = fopen(filePath.c_str(), "r"); if (!file) { DFXLOGE("open %{public}s fail, errno:%{public}d", filePath.c_str(), errno); - return; + return false; } char cmdline[256]; size_t len = fread(cmdline, 1, sizeof(cmdline) - 1, file); @@ -334,25 +351,27 @@ void NoteWriter::ReadProcessCmdline(struct elf_prpsinfo *ntPrpsinfo) if (len <= 0) { DFXLOGE("read %{public}s fail, errno:%{public}d", filePath.c_str(), errno); - return; + return false; } cmdline[len] = '\0'; - (void)memset_s(&ntPrpsinfo->pr_psargs, sizeof(ntPrpsinfo->pr_psargs), 0, sizeof(ntPrpsinfo->pr_psargs)); - auto ret = strncpy_s(ntPrpsinfo->pr_psargs, sizeof(ntPrpsinfo->pr_psargs), - cmdline, sizeof(ntPrpsinfo->pr_psargs) - 1); + (void)memset_s(&ntPrpsinfo.pr_psargs, sizeof(ntPrpsinfo.pr_psargs), 0, sizeof(ntPrpsinfo.pr_psargs)); + auto ret = strncpy_s(ntPrpsinfo.pr_psargs, sizeof(ntPrpsinfo.pr_psargs), + cmdline, sizeof(ntPrpsinfo.pr_psargs) - 1); if (ret != 0) { DFXLOGE("strncpy_s fail, err:%{public}d", ret); + return false; } + return true; } -void NoteWriter::MultiThreadNoteWrite() +bool NoteSegmentWriter::MultiThreadNoteWrite() { std::string filePath = "/proc/" + std::to_string(pid_) + "/task"; DIR *dir = opendir(filePath.c_str()); if (!dir) { DFXLOGE("open %{public}s fail, errno:%{public}d", filePath.c_str(), errno); - return; + return false; } struct dirent *entry; @@ -363,28 +382,40 @@ void NoteWriter::MultiThreadNoteWrite() } } closedir(dir); + return true; } -void NoteWriter::ThreadNoteWrite(pid_t tid) +bool NoteSegmentWriter::ThreadNoteWrite(pid_t tid) { if (tid == targetTid_) { ptrace(PTRACE_INTERRUPT, tid, 0, 0); if (waitpid(tid, nullptr, 0) < 0) { DFXLOGE("Failed to waitpid tid(%{public}d), errno=%{public}d", tid, errno); - return; + return false; } } - PrstatusWrite(tid); - ArmPacMaskWrite(tid); - FpregsetWrite(tid); - SiginfoWrite(tid); - ArmTaggedAddrCtrlWrite(); + if (!PrstatusWrite(tid)) { + DFXLOGE("Failed to write prstatus in (%{public}d)", tid); + } + if (!ArmPacMaskWrite(tid)) { + DFXLOGE("Failed to write arm_pac_mask in (%{public}d)", tid); + } + if (!FpregsetWrite(tid)) { + DFXLOGE("Failed to write fp reg in (%{public}d)", tid); + } + if (!SiginfoWrite(tid)) { + DFXLOGE("Failed to write siginfo in (%{public}d)", tid); + } + if (!ArmTaggedAddrCtrlWrite()) { + DFXLOGE("Failed to write arm tagged"); + } if (tid == targetTid_) { ptrace(PTRACE_CONT, tid, 0, 0); } + return true; } -bool NoteWriter::ArmPacMaskWrite(pid_t tid) +bool NoteSegmentWriter::ArmPacMaskWrite(pid_t tid) { if (!NoteWrite(NT_ARM_PAC_MASK, sizeof(UserPacMask), NOTE_NAME_LINUX)) { return false; @@ -405,12 +436,16 @@ bool NoteWriter::ArmPacMaskWrite(pid_t tid) return true; } -bool NoteWriter::PrstatusWrite(pid_t tid) +bool NoteSegmentWriter::PrstatusWrite(pid_t tid) { - NoteWrite(NT_PRSTATUS, sizeof(struct elf_prstatus), NOTE_NAME_CORE); - struct elf_prstatus ntPrstatus; - GetPrStatus(&ntPrstatus, tid); - GetPrReg(&ntPrstatus, tid); + NoteWrite(NT_PRSTATUS, sizeof(prstatus_t), NOTE_NAME_CORE); + prstatus_t ntPrstatus; + if (!GetPrStatus(ntPrstatus, tid)) { + DFXLOGE("Fail to get pr status in (%{public}d)", tid); + } + if (!GetPrReg(ntPrstatus, tid)) { + DFXLOGE("Fail to get pr reg in (%{public}d)", tid); + } if (!CopyAndAdvance(&ntPrstatus, sizeof(ntPrstatus))) { DFXLOGE("Write ntPrstatus fail, errno:%{public}d", errno); return false; @@ -418,7 +453,7 @@ bool NoteWriter::PrstatusWrite(pid_t tid) return true; } -bool NoteWriter::FpregsetWrite(pid_t tid) +bool NoteSegmentWriter::FpregsetWrite(pid_t tid) { if (!NoteWrite(NT_FPREGSET, sizeof(struct user_fpsimd_struct), NOTE_NAME_CORE)) { return false; @@ -439,7 +474,7 @@ bool NoteWriter::FpregsetWrite(pid_t tid) return true; } -bool NoteWriter::SiginfoWrite(pid_t tid) +bool NoteSegmentWriter::SiginfoWrite(pid_t tid) { if (!NoteWrite(NT_SIGINFO, sizeof(siginfo_t), NOTE_NAME_CORE)) { return false; @@ -457,7 +492,7 @@ bool NoteWriter::SiginfoWrite(pid_t tid) return true; } -bool NoteWriter::ArmTaggedAddrCtrlWrite() +bool NoteSegmentWriter::ArmTaggedAddrCtrlWrite() { if (!NoteWrite(0x409, sizeof(long), NOTE_NAME_LINUX)) { return false; @@ -468,10 +503,10 @@ bool NoteWriter::ArmTaggedAddrCtrlWrite() return true; } -void NoteWriter::GetPrStatus(struct elf_prstatus *ntPrstatus, pid_t tid) +bool NoteSegmentWriter::GetPrStatus(prstatus_t &ntPrstatus, pid_t tid) { - if (ptrace(PTRACE_GETSIGINFO, tid, NULL, &(ntPrstatus->pr_info)) == 0) { - ntPrstatus->pr_cursig = ntPrstatus->pr_info.si_signo; + if (ptrace(PTRACE_GETSIGINFO, tid, NULL, &(ntPrstatus.pr_info)) == 0) { + ntPrstatus.pr_cursig = ntPrstatus.pr_info.si_signo; } else { DFXLOGE("ptrace failed PTRACE_GETSIGINFO, tid:%{public}d, errno:%{public}d", tid, errno); } @@ -480,61 +515,62 @@ void NoteWriter::GetPrStatus(struct elf_prstatus *ntPrstatus, pid_t tid) FILE *file = fopen(filePath.c_str(), "r"); if (!file) { DFXLOGE("open %{public}s fail, errno:%{public}d", filePath.c_str(), errno); - return; + return false; } while (fgets(buffer, sizeof(buffer), file) != nullptr) { - if (strncmp(buffer, "PPid:", 5) == 0) { // 5 - if (sscanf_s(buffer + 5, "%d", &ntPrstatus->pr_ppid) != 1) { // 5 + if (strncmp(buffer, PPID, strlen(PPID)) == 0) { + if (sscanf_s(buffer + strlen(PPID), "%d", &ntPrstatus.pr_ppid) != 1) { continue; } - } else if (strncmp(buffer, "SigPnd:", 7) == 0) { // 7 - if (sscanf_s(buffer + 7, "%lx", &ntPrstatus->pr_sigpend) != 1) { // 7 + } else if (strncmp(buffer, SIGPND, strlen(SIGPND)) == 0) { + if (sscanf_s(buffer + strlen(SIGPND), "%lx", &ntPrstatus.pr_sigpend) != 1) { continue; } - } else if (strncmp(buffer, "SigBlk:", 7) == 0) { // 7 - if (sscanf_s(buffer + 7, "%lx", &ntPrstatus->pr_sighold) != 1) { // 7 + } else if (strncmp(buffer, SIGBLK, strlen(SIGBLK)) == 0) { + if (sscanf_s(buffer + strlen(SIGBLK), "%lx", &ntPrstatus.pr_sighold) != 1) { continue; } } } (void)fclose(file); - ntPrstatus->pr_pid = tid; - ntPrstatus->pr_pgrp = getpgrp(); - ntPrstatus->pr_sid = getsid(ntPrstatus->pr_pid); + ntPrstatus.pr_pid = tid; + ntPrstatus.pr_pgrp = getpgrp(); + ntPrstatus.pr_sid = getsid(ntPrstatus.pr_pid); struct rusage usage; getrusage(RUSAGE_SELF, &usage); - if (memcpy_s(&ntPrstatus->pr_utime, sizeof(usage.ru_utime), &usage.ru_utime, sizeof(usage.ru_utime)) != 0) { - return; + if (memcpy_s(&ntPrstatus.pr_utime, sizeof(ntPrstatus.pr_utime), &usage.ru_utime, sizeof(usage.ru_utime)) != 0) { + return false; } - if (memcpy_s(&ntPrstatus->pr_stime, sizeof(usage.ru_stime), &usage.ru_stime, sizeof(usage.ru_stime)) != 0) { - return; + if (memcpy_s(&ntPrstatus.pr_stime, sizeof(ntPrstatus.pr_stime), &usage.ru_stime, sizeof(usage.ru_stime)) != 0) { + return false; } getrusage(RUSAGE_CHILDREN, &usage); - if (memcpy_s(&ntPrstatus->pr_cutime, sizeof(usage.ru_utime), &usage.ru_utime, sizeof(usage.ru_utime)) != 0) { - return; + if (memcpy_s(&ntPrstatus.pr_cutime, sizeof(ntPrstatus.pr_cutime), &usage.ru_utime, sizeof(usage.ru_utime)) != 0) { + return false; } - if (memcpy_s(&ntPrstatus->pr_cstime, sizeof(usage.ru_stime), &usage.ru_stime, sizeof(usage.ru_stime)) != 0) { - return; + if (memcpy_s(&ntPrstatus.pr_cstime, sizeof(ntPrstatus.pr_cstime), &usage.ru_stime, sizeof(usage.ru_stime)) != 0) { + return false; } + return true; } -void NoteWriter::GetPrReg(struct elf_prstatus *ntPrstatus, pid_t tid) +bool NoteSegmentWriter::GetPrReg(prstatus_t &ntPrstatus, pid_t tid) { if (tid == targetTid_) { - if (memcpy_s(&(ntPrstatus->pr_reg), sizeof(ntPrstatus->pr_reg), keyRegs_->RawData(), - sizeof(ntPrstatus->pr_reg)) != 0) { + if (memcpy_s(&(ntPrstatus.pr_reg), sizeof(ntPrstatus.pr_reg), keyRegs_->RawData(), + sizeof(ntPrstatus.pr_reg)) != 0) { DFXLOGE("Failed to memcpy regs data, errno = %{public}d", errno); - return; + return false; } } else { struct iovec iov; (void)memset_s(&iov, sizeof(iov), 0, sizeof(iov)); - iov.iov_base = &(ntPrstatus->pr_reg); - iov.iov_len = sizeof(ntPrstatus->pr_reg); + iov.iov_base = &(ntPrstatus.pr_reg); + iov.iov_len = sizeof(ntPrstatus.pr_reg); if (ptrace(PTRACE_GETREGSET, tid, NT_PRSTATUS, &iov) == -1) { DFXLOGE("ptrace failed NT_PRSTATUS, tid:%{public}d, errno:%{public}d", tid, errno); - return; + return false; } } struct iovec iovFp; @@ -544,13 +580,14 @@ void NoteWriter::GetPrReg(struct elf_prstatus *ntPrstatus, pid_t tid) if (ptrace(PTRACE_GETREGSET, tid, NT_FPREGSET, &iovFp) == -1) { DFXLOGE("ptrace failed NT_FPREGSET, tid:%{public}d, errno:%{public}d", tid, errno); - ntPrstatus->pr_fpvalid = 0; + ntPrstatus.pr_fpvalid = 0; } else { - ntPrstatus->pr_fpvalid = 1; + ntPrstatus.pr_fpvalid = 1; } + return true; } -bool NoteWriter::AuxvWrite() +bool NoteSegmentWriter::AuxvWrite() { Elf64_Nhdr *note = reinterpret_cast(currentPointer_); note->n_namesz = 0x05; @@ -563,18 +600,20 @@ bool NoteWriter::AuxvWrite() return false; } - ReadProcessAuxv(note); + if (!ReadProcessAuxv(note)) { + DFXLOGE("Read targetPid Process Auxv fail"); + } return true; } -void NoteWriter::ReadProcessAuxv(Elf64_Nhdr *note) +bool NoteSegmentWriter::ReadProcessAuxv(Elf64_Nhdr *note) { std::string filePath = "/proc/" + std::to_string(pid_) + "/auxv"; FILE *file = fopen(filePath.c_str(), "r"); if (!file) { note->n_descsz = 0; DFXLOGE("open %{public}s fail, errno:%{public}d", filePath.c_str(), errno); - return; + return false; } Elf64_auxv_t ntAuxv; note->n_descsz = 0; @@ -583,16 +622,17 @@ void NoteWriter::ReadProcessAuxv(Elf64_Nhdr *note) if (!CopyAndAdvance(&ntAuxv, sizeof(ntAuxv))) { DFXLOGE("Wrtie ntAuxv fail, errno:%{public}d", errno); (void)fclose(file); - return; + return false; } if (ntAuxv.a_type == AT_NULL) { break; } } (void)fclose(file); + return true; } -bool NoteWriter::FileWrite() +bool NoteSegmentWriter::FileWrite() { Elf64_Nhdr *note = reinterpret_cast(currentPointer_); note->n_namesz = 0x05; @@ -612,7 +652,7 @@ bool NoteWriter::FileWrite() Elf64_Half lineNumber = 1; WriteAddrRelated(); - WriteFilePath(&lineNumber); + WriteFilePath(lineNumber); note->n_descsz = reinterpret_cast(currentPointer_) - reinterpret_cast(startPointer); ntFileHd->count = lineNumber - 1; @@ -628,7 +668,7 @@ bool NoteWriter::FileWrite() return true; } -bool NoteWriter::WriteAddrRelated() +bool NoteSegmentWriter::WriteAddrRelated() { for (const auto& region : maps_) { if (region.pathName[0] != '/' || (region.priority[0] != 'r')) { @@ -646,7 +686,7 @@ bool NoteWriter::WriteAddrRelated() return true; } -bool NoteWriter::WriteFilePath(Elf64_Half *lineNumber) +bool NoteSegmentWriter::WriteFilePath(Elf64_Half &lineNumber) { for (const auto& region : maps_) { if (region.pathName[0] != '/' || (region.priority[0] != 'r')) { @@ -658,7 +698,7 @@ bool NoteWriter::WriteFilePath(Elf64_Half *lineNumber) } *currentPointer_ = '\0'; currentPointer_ += 1; - *lineNumber = *lineNumber + 1; + lineNumber += 1; } return true; } diff --git a/tools/process_dump/dfx_coredump_writer.h b/tools/process_dump/coredump/dfx_coredump_writer.h similarity index 70% rename from tools/process_dump/dfx_coredump_writer.h rename to tools/process_dump/coredump/dfx_coredump_writer.h index d22814d91492b7b294e87190f9fbf3972c211d67..8f071bb5e9e15aae35f490107388c93df229d196 100644 --- a/tools/process_dump/dfx_coredump_writer.h +++ b/tools/process_dump/coredump/dfx_coredump_writer.h @@ -46,31 +46,31 @@ protected: class ProgramSegmentHeaderWriter : public Writer { public: - ProgramSegmentHeaderWriter(char* mappedMemory, char* currentPointer, Elf64_Half* ePhnum, + ProgramSegmentHeaderWriter(char* mappedMemory, char* currentPointer, Elf64_Half& ePhnum, std::vector& maps) : Writer(mappedMemory, currentPointer), ePhnum_(ePhnum), maps_(maps) {} char* Write() override; private: - void ProgramSegmentHeaderFill(Elf64_Phdr *ph, Elf64_Word pType, Elf64_Word pFlags, struct DumpMemoryRegions region); - void PtLoadFill(Elf64_Phdr *ph, struct DumpMemoryRegions region); - void PtNoteFill(Elf64_Phdr *ph); - Elf64_Half* ePhnum_; + void ProgramSegmentHeaderFill(Elf64_Phdr &ph, Elf64_Word pType, Elf64_Word pFlags, const DumpMemoryRegions ®ion); + void PtLoadFill(Elf64_Phdr &ph, const DumpMemoryRegions ®ion); + void PtNoteFill(Elf64_Phdr &ph); + Elf64_Half& ePhnum_; std::vector maps_; }; -class SegmentWriter : public Writer { +class LoadSegmentWriter : public Writer { public: - SegmentWriter(char* mappedMemory, char* currentPointer, pid_t pid, Elf64_Half ePhnum) + LoadSegmentWriter(char* mappedMemory, char* currentPointer, pid_t pid, Elf64_Half ePhnum) : Writer(mappedMemory, currentPointer), pid_(pid), ePhnum_(ePhnum) {} char* Write() override; private: - void ReadProcessVmmem(Elf64_Phdr *ptLoad); + void ReadProcessVmmem(Elf64_Phdr &ptLoad); pid_t pid_; Elf64_Half ePhnum_; }; -class NoteWriter : public Writer { +class NoteSegmentWriter : public Writer { public: - NoteWriter(char* mappedMemory, char* currentPointer, CoreDumpThread& coreDumpThread, + NoteSegmentWriter(char* mappedMemory, char* currentPointer, CoreDumpThread& coreDumpThread, std::vector& maps, std::shared_ptr regs) : Writer(mappedMemory, currentPointer), pid_(coreDumpThread.targetPid), targetTid_(coreDumpThread.targetTid), maps_(maps), keyRegs_(regs) {} char* Write() override; @@ -78,25 +78,25 @@ public: private: bool PrpsinfoWrite(); bool NoteWrite(uint32_t noteType, size_t descSize, const char* noteName); - void FillPrpsinfo(struct elf_prpsinfo *ntPrpsinfo); - void ReadProcessStat(struct elf_prpsinfo *ntPrpsinfo); - void ReadProcessStatus(struct elf_prpsinfo *ntPrpsinfo); - void ReadProcessComm(struct elf_prpsinfo *ntPrpsinfo); - void ReadProcessCmdline(struct elf_prpsinfo *ntPrpsinfo); - void MultiThreadNoteWrite(); - void ThreadNoteWrite(pid_t tid); + void FillPrpsinfo(prpsinfo_t &ntPrpsinfo); + bool ReadProcessStat(prpsinfo_t &ntPrpsinfo); + bool ReadProcessStatus(prpsinfo_t &ntPrpsinfo); + bool ReadProcessComm(prpsinfo_t &ntPrpsinfo); + bool ReadProcessCmdline(prpsinfo_t &ntPrpsinfo); + bool MultiThreadNoteWrite(); + bool ThreadNoteWrite(pid_t tid); bool PrstatusWrite(pid_t tid); bool ArmPacMaskWrite(pid_t tid); bool FpregsetWrite(pid_t tid); bool SiginfoWrite(pid_t tid); bool ArmTaggedAddrCtrlWrite(); - void GetPrStatus(struct elf_prstatus *ntPrstatus, pid_t tid); - void GetPrReg(struct elf_prstatus *ntPrstatus, pid_t tid); + bool GetPrStatus(prstatus_t &ntPrstatus, pid_t tid); + bool GetPrReg(prstatus_t &ntPrstatus, pid_t tid); bool AuxvWrite(); - void ReadProcessAuxv(Elf64_Nhdr *note); + bool ReadProcessAuxv(Elf64_Nhdr *note); bool FileWrite(); bool WriteAddrRelated(); - bool WriteFilePath(Elf64_Half *lineNumber); + bool WriteFilePath(Elf64_Half &lineNumber); pid_t pid_; pid_t targetTid_; std::vector maps_; diff --git a/tools/process_dump/dump_utils.cpp b/tools/process_dump/dump_utils.cpp index 45ab642f7e2a65d2a520d7711d0fe8db987aeb50..ae642e29148e65d3515ce8d168c212c7b2a5e81c 100644 --- a/tools/process_dump/dump_utils.cpp +++ b/tools/process_dump/dump_utils.cpp @@ -22,6 +22,13 @@ #include "dfx_log.h" #include "dfx_kernel_stack.h" #include "dfx_frame_formatter.h" +#ifndef is_ohos_lite +#include "bundle_mgr_interface.h" +#include "bundle_mgr_proxy.h" +#include "if_system_ability_manager.h" +#include "iservice_registry.h" +#include "system_ability_definition.h" +#endif namespace OHOS { namespace HiviewDFX { namespace { @@ -147,5 +154,58 @@ bool DumpUtils::ReadTargetMemory(pid_t tid, uintptr_t addr, uintptr_t &value) } return true; } + +#ifndef is_ohos_lite +sptr GetBundleManager() +{ + auto systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (!systemManager) { + DFXLOGE("Get system ability manager failed"); + return nullptr; + } + auto remoteObject = systemManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + if (!remoteObject) { + DFXLOGE("Get system ability failed"); + return nullptr; + } + sptr bundleMgrProxy = iface_cast(remoteObject); + return bundleMgrProxy; +} +#endif + +std::string DumpUtils::GetSelfBundleName() +{ +#ifndef is_ohos_lite + static std::string bundleName; + if (!bundleName.empty()) { + return bundleName; + } + auto bundleInstance = GetBundleManager(); + if (bundleInstance == nullptr) { + DFXLOGE("bundleInstance is nullptr"); + return ""; + } + AppExecFwk::BundleInfo bundleInfo; + auto ret = bundleInstance->GetBundleInfoForSelf(0, bundleInfo); + if (ret != ERR_OK) { + DFXLOGE("GetBundleInfoForSelf failed! ret = %{public}d", ret); + return ""; + } + bundleName = bundleInfo.name; + return bundleName; +#endif + return ""; +} + +void DumpUtils::InfoCrashUnwindResult(const ProcessDumpRequest& request, bool isUnwindSucc) +{ + if (!isUnwindSucc) { + return; + } + if (ptrace(PTRACE_POKEDATA, request.nsPid, reinterpret_cast(request.unwindResultAddr), + CRASH_UNWIND_SUCCESS_FLAG) < 0) { + DFXLOGE("pok unwind success flag to nsPid %{public}d fail %{public}s", request.nsPid, strerror(errno)); + } +} } // namespace HiviewDFX } // namespace OHOS diff --git a/tools/process_dump/dump_utils.h b/tools/process_dump/dump_utils.h index 3ba02afff33b841ad5771d360ff9cdfd1ce89f6b..63e838a67604f4b39d8a03a9c3a02c4d0765c2f2 100644 --- a/tools/process_dump/dump_utils.h +++ b/tools/process_dump/dump_utils.h @@ -16,6 +16,7 @@ #ifndef DUMP_UTILS_H #define DUMP_UTILS_H #include "unwinder.h" +#include "dfx_dump_request.h" #include "dfx_thread.h" #include #include @@ -29,6 +30,8 @@ public: static std::string ReadStringByPtrace(pid_t tid, uintptr_t startAddr, size_t maxLen); static std::string GetStackTrace(const std::vector& frames); static bool ReadTargetMemory(pid_t tid, uintptr_t addr, uintptr_t &value); + static std::string GetSelfBundleName(); + static void InfoCrashUnwindResult(const ProcessDumpRequest& request, bool isUnwindSucc); }; } // namespace HiviewDFX } // namespace OHOS diff --git a/tools/process_dump/process_dumper.cpp b/tools/process_dump/process_dumper.cpp index 3c15ad1a0c40c3ec2eba84686ebd0c357029b532..3b1b0603c96b13e6d1fbb85f47553ac18c3f124e 100644 --- a/tools/process_dump/process_dumper.cpp +++ b/tools/process_dump/process_dumper.cpp @@ -42,6 +42,7 @@ #include "crash_exception.h" #include "process_dump_config.h" #include "dump_info_factory.h" +#include "dump_utils.h" #include "dfx_define.h" #include "dfx_dump_request.h" #include "dfx_dump_res.h" @@ -119,11 +120,6 @@ void GetVmProcessRealPid(const ProcessDumpRequest& request, unsigned long vmPid, realPid = static_cast(data); } -MAYBE_UNUSED bool IsCoredumpSignal(const ProcessDumpRequest& request) -{ - return request.siginfo.si_signo == 42 && request.siginfo.si_code == 3; // 42 3 -} - void ReadPids(const ProcessDumpRequest& request, int& realPid, int& vmPid, DfxProcess process) { unsigned long childPid = 0; @@ -132,7 +128,13 @@ void ReadPids(const ProcessDumpRequest& request, int& realPid, int& vmPid, DfxPr ptrace(PTRACE_CONT, childPid, NULL, NULL); // freeze detach after fork child to fork vm process - if (request.type == ProcessDumpType::DUMP_TYPE_DUMP_CATCH || IsCoredumpSignal(request)) { + if (request.type == ProcessDumpType::DUMP_TYPE_DUMP_CATCH || +#if defined(__aarch64__) + CoreDumpService::IsCoredumpSignal(request) +#else + false +#endif + ) { process.Detach(); DFXLOGI("ptrace detach all tids"); } @@ -158,17 +160,6 @@ void NotifyOperateResult(ProcessDumpRequest& request, int result) } } -void InfoCrashUnwindResult(const ProcessDumpRequest& request, bool isUnwindSucc) -{ - if (!isUnwindSucc) { - return; - } - if (ptrace(PTRACE_POKEDATA, request.nsPid, reinterpret_cast(request.unwindResultAddr), - CRASH_UNWIND_SUCCESS_FLAG) < 0) { - DFXLOGE("pok unwind success flag to nsPid %{public}d fail %{public}s", request.nsPid, strerror(errno)); - } -} - void BlockCrashProcExit(const ProcessDumpRequest& request) { if (!IsBlockCrashProcess()) { @@ -211,7 +202,7 @@ void ProcessDumper::Dump() } if (request.type == ProcessDumpType::DUMP_TYPE_CPP_CRASH) { - InfoCrashUnwindResult(request, resDump == DumpErrorCode::DUMP_ESUCCESS); + DumpUtils::InfoCrashUnwindResult(request, resDump == DumpErrorCode::DUMP_ESUCCESS); BlockCrashProcExit(request); } if (process_ != nullptr) { @@ -476,34 +467,6 @@ int ProcessDumper::ParseSymbols(const ProcessDumpRequest& request, std::shared_p return dumpRes; } -#if defined(__aarch64__) -static void ProcessdumpDoCoredump(const ProcessDumpRequest& request, pid_t vmPid, CoreDumpService& coreDumpService) -{ - if (IsCoredumpSignal(request) || CoreDumpService::IsHwasanCoredumpEnabled()) { - ElapsedTime counter; - DFXLOGI("coredump begin to write segment"); - int pid = request.pid; - coreDumpService.SetVmPid(vmPid); - coreDumpService.WriteSegment(); - coreDumpService.WriteSectionHeader(); - coreDumpService.StopCoreDump(); - DFXLOGI("end to coredump"); - - std::string bundleName = coreDumpService.GetBundleNameItem(); - bundleName += ".dmp"; - int32_t retCode = ResponseCode::REQUEST_SUCCESS; - FinishCoredumpCb(pid, bundleName, retCode); - - DFXLOGI("coredump : pid = %{public}d, elapsed time = %{public}" PRId64 "ms, ", - pid, counter.Elapsed()); - if (CoreDumpService::IsHwasanCoredumpEnabled()) { - InfoCrashUnwindResult(request, true); - } - _exit(0); - } -} -#endif - bool ProcessDumper::InitUnwinder(const ProcessDumpRequest& request, int &dumpRes) { DFX_TRACE_SCOPED("InitUnwinder"); @@ -521,7 +484,11 @@ bool ProcessDumper::InitUnwinder(const ProcessDumpRequest& request, int &dumpRes return false; } #if defined(__aarch64__) - ProcessdumpDoCoredump(request, vmPid, coreDumpService_); + if (CoreDumpService::IsCoredumpSignal(request) || CoreDumpService::IsHwasanCoredumpEnabled()) { + if (coreDumpService_) { + coreDumpService_->StartSecondStageDump(vmPid, request); + } + } #endif process_->SetVmPid(vmPid); #if defined(PROCESSDUMP_MINIDEBUGINFO) @@ -572,13 +539,12 @@ bool ProcessDumper::InitDfxProcess(ProcessDumpRequest& request) } DFXLOGI("Finish create all thread."); #if defined(__aarch64__) - if (IsCoredumpSignal(request) || CoreDumpService::IsHwasanCoredumpEnabled()) { - DFXLOGI("Begin to do Coredump."); - coreDumpService_ = CoreDumpService(request.pid, request.tid); - coreDumpService_.keyRegs_ = DfxRegs::CreateFromUcontext(request.context); - coreDumpService_.StartCoreDump(); - coreDumpService_.WriteSegmentHeader(); - coreDumpService_.WriteNote(); + if (CoreDumpService::IsCoredumpSignal(request) || CoreDumpService::IsHwasanCoredumpEnabled()) { + coreDumpService_ = std::make_shared(request.pid, request.tid, + DfxRegs::CreateFromUcontext(request.context)); + if (coreDumpService_) { + coreDumpService_->StartFirstStageDump(); + } } #endif return true; diff --git a/tools/process_dump/process_dumper.h b/tools/process_dump/process_dumper.h index 1395143331c5c136f51fbd1e7c548dfdcdec8ee6..79f397079576d5e850af0e6ef55878121816f344 100644 --- a/tools/process_dump/process_dumper.h +++ b/tools/process_dump/process_dumper.h @@ -24,7 +24,6 @@ #include #include "reporter.h" -#include "dfx_coredump_common.h" #include "dfx_coredump_service.h" #include "dfx_dump_request.h" #include "dfx_process.h" @@ -73,7 +72,7 @@ private: bool isJsonDump_ = false; uint64_t expectedDumpFinishTime_ = 0; #if defined(__aarch64__) - CoreDumpService coreDumpService_; + std::shared_ptr coreDumpService_ = nullptr; #endif }; } // namespace HiviewDFX