diff --git a/README.md b/README.md index 64d06bd..54840a2 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,9 @@ dependencies { // 设置超时时间 (单位秒) Coredump.getInstance().setCoreTimeout(Coredump.DEF_TIMEOUT); + // 设置Coredump文件大小 + Coredump.getInstance().setCoreLimit(Coredump.DEF_LIMIT); + // 设置模式 // Coredump.getInstance().setCoreMode(Coredump.MODE_PTRACE | Coredump.MODE_COPY); // Coredump.getInstance().setCoreMode(Coredump.MODE_PTRACE); diff --git a/app/src/main/java/penguin/opencore/tester/TesterApp.java b/app/src/main/java/penguin/opencore/tester/TesterApp.java index d7d8ebd..6b366a0 100644 --- a/app/src/main/java/penguin/opencore/tester/TesterApp.java +++ b/app/src/main/java/penguin/opencore/tester/TesterApp.java @@ -28,7 +28,7 @@ public void onCreate() { Coredump.getInstance().init(); Coredump.getInstance().setCoreTimeout(Coredump.DEF_TIMEOUT); - + Coredump.getInstance().setCoreLimit(Coredump.DEF_LIMIT); //Coredump.getInstance().setCoreMode(Coredump.MODE_PTRACE | Coredump.MODE_COPY); //Coredump.getInstance().setCoreMode(Coredump.MODE_PTRACE); //Coredump.getInstance().setCoreMode(Coredump.MODE_COPY); diff --git a/opencore/src/main/cpp/arm/opencore_impl.cpp b/opencore/src/main/cpp/arm/opencore_impl.cpp index 83e92e1..ff6ca1f 100644 --- a/opencore/src/main/cpp/arm/opencore_impl.cpp +++ b/opencore/src/main/cpp/arm/opencore_impl.cpp @@ -246,7 +246,7 @@ void OpencoreImpl::CreateCoreAUXV(pid_t pid) void OpencoreImpl::WriteCoreHeader(FILE* fp) { - fwrite((void *)&ehdr, sizeof(Elf32_Ehdr), 1, fp); + WriteAndRecord((void *)&ehdr, sizeof(Elf32_Ehdr), 1, fp); } void OpencoreImpl::WriteCoreNoteHeader(FILE* fp) @@ -254,7 +254,7 @@ void OpencoreImpl::WriteCoreNoteHeader(FILE* fp) note.p_filesz = (sizeof(Elf32_prstatus) + sizeof(Elf32_Nhdr) + 8) * prnum; note.p_filesz += sizeof(Elf32_auxv) * auxvnum + sizeof(Elf32_Nhdr) + 8; note.p_filesz += sizeof(Elf32_ntfile) * phnum + sizeof(Elf32_Nhdr) + 8 + 8 + fileslen; - fwrite((void *)¬e, sizeof(Elf32_Phdr), 1, fp); + WriteAndRecord((void *)¬e, sizeof(Elf32_Phdr), 1, fp); } void OpencoreImpl::WriteCoreProgramHeaders(FILE* fp) @@ -266,12 +266,12 @@ void OpencoreImpl::WriteCoreProgramHeaders(FILE* fp) } phdr[0].p_offset = offset; - fwrite(&phdr[0], sizeof(Elf32_Phdr), 1, fp); + WriteAndRecord(&phdr[0], sizeof(Elf32_Phdr), 1, fp); int index = 1; while (index < ehdr.e_phnum - 1) { phdr[index].p_offset = phdr[index - 1].p_offset + phdr[index-1].p_filesz; - fwrite(&phdr[index], sizeof(Elf32_Phdr), 1, fp); + WriteAndRecord(&phdr[index], sizeof(Elf32_Phdr), 1, fp); index++; } } @@ -289,9 +289,9 @@ void OpencoreImpl::WriteCorePrStatus(FILE* fp) int index = 0; while (index < prnum) { - fwrite(&elf_nhdr, sizeof(Elf32_Nhdr), 1, fp); - fwrite(magic, sizeof(magic), 1, fp); - fwrite(&prstatus[index], sizeof(Elf32_prstatus), 1, fp); + WriteAndRecord(&elf_nhdr, sizeof(Elf32_Nhdr), 1, fp); + WriteAndRecord(magic, sizeof(magic), 1, fp); + WriteAndRecord(&prstatus[index], sizeof(Elf32_prstatus), 1, fp); index++; } } @@ -307,12 +307,12 @@ void OpencoreImpl::WriteCoreAUXV(FILE* fp) memset(magic, 0, sizeof(magic)); snprintf(magic, NOTE_CORE_NAME_SZ, ELFCOREMAGIC); - fwrite(&elf_nhdr, sizeof(Elf32_Nhdr), 1, fp); - fwrite(magic, sizeof(magic), 1, fp); + WriteAndRecord(&elf_nhdr, sizeof(Elf32_Nhdr), 1, fp); + WriteAndRecord(magic, sizeof(magic), 1, fp); int index = 0; while (index < auxvnum) { - fwrite(&auxv[index], sizeof(Elf32_auxv), 1, fp); + WriteAndRecord(&auxv[index], sizeof(Elf32_auxv), 1, fp); index++; } } @@ -328,21 +328,21 @@ void OpencoreImpl::WriteNtFile(FILE* fp) memset(magic, 0, sizeof(magic)); snprintf(magic, NOTE_CORE_NAME_SZ, ELFCOREMAGIC); - fwrite(&elf_nhdr, sizeof(Elf32_Nhdr), 1, fp); - fwrite(magic, sizeof(magic), 1, fp); + WriteAndRecord(&elf_nhdr, sizeof(Elf32_Nhdr), 1, fp); + WriteAndRecord(magic, sizeof(magic), 1, fp); uint32_t number = phnum; - fwrite(&number, 4, 1, fp); + WriteAndRecord(&number, 4, 1, fp); uint32_t page_size = sysconf(_SC_PAGE_SIZE); - fwrite(&page_size, 4, 1, fp); + WriteAndRecord(&page_size, 4, 1, fp); int index = 0; while(index < phnum){ - fwrite(&ntfile[index], sizeof(Elf32_ntfile), 1, fp); + WriteAndRecord(&ntfile[index], sizeof(Elf32_ntfile), 1, fp); index++; } - fwrite(buffer.data(), buffer.size(), 1, fp); + WriteAndRecord(buffer.data(), buffer.size(), 1, fp); } void OpencoreImpl::AlignNoteSegment(FILE* fp) @@ -352,7 +352,7 @@ void OpencoreImpl::AlignNoteSegment(FILE* fp) char *ptr = (char *)malloc(size); if (ptr) { memset(ptr, 0, size); - fwrite(ptr, size, 1, fp); + WriteAndRecord(ptr, size, 1, fp); free(ptr); } } @@ -395,13 +395,13 @@ void OpencoreImpl::WriteCoreLoadSegment(pid_t pid, FILE* fp) Elf32_Addr target = phdr[index].p_vaddr; while (target < phdr[index].p_vaddr + phdr[index].p_memsz) { int mem = ptrace(PTRACE_PEEKTEXT, pid, target, 0x0); - fwrite(&mem, sizeof(mem), 1, fp); + WriteAndRecord(&mem, sizeof(mem), 1, fp); target = target + sizeof(Elf32_Addr); } } break; case MODE_COPY: { if (InSelfMaps(phdr[index].p_vaddr)) { - uint32_t ret = fwrite((void *)phdr[index].p_vaddr, phdr[index].p_memsz, 1, fp); + uint32_t ret = WriteAndRecord((void *)phdr[index].p_vaddr, phdr[index].p_memsz, 1, fp); if (ret != 1) { need_padd_zero = true; JNI_LOGE("[0x%x] write load segment fail. %s %s", @@ -416,11 +416,11 @@ void OpencoreImpl::WriteCoreLoadSegment(pid_t pid, FILE* fp) Elf32_Addr target = phdr[index].p_vaddr; while (target < phdr[index].p_vaddr + phdr[index].p_memsz) { int mem = ptrace(PTRACE_PEEKTEXT, pid, target, 0x0); - fwrite(&mem, sizeof(mem), 1, fp); + WriteAndRecord(&mem, sizeof(mem), 1, fp); target = target + sizeof(Elf32_Addr); } } else { - uint32_t ret = fwrite((void *)phdr[index].p_vaddr, phdr[index].p_memsz, 1, fp); + uint32_t ret = WriteAndRecord((void *)phdr[index].p_vaddr, phdr[index].p_memsz, 1, fp); if (ret != 1) { need_padd_zero = true; JNI_LOGE("[0x%x] write load segment fail. %s %s", @@ -437,7 +437,7 @@ void OpencoreImpl::WriteCoreLoadSegment(pid_t pid, FILE* fp) } else { pread(fd, &zero, sizeof(zero), phdr[index].p_vaddr + (i * sizeof(zero))); } - uint32_t ret = fwrite(zero, sizeof(zero), 1, fp); + uint32_t ret = WriteAndRecord(zero, sizeof(zero), 1, fp); if (ret != 1) { need_padd_zero = true; JNI_LOGE("[0x%x] write load segment fail. %s %s", @@ -455,7 +455,7 @@ void OpencoreImpl::WriteCoreLoadSegment(pid_t pid, FILE* fp) fseek(fp, current_pos, SEEK_SET); int count = phdr[index].p_memsz / sizeof(zero); for (int i = 0; i < count; i++) { - uint32_t ret = fwrite(zero, sizeof(zero), 1, fp); + uint32_t ret = WriteAndRecord(zero, sizeof(zero), 1, fp); if (ret != 1) { JNI_LOGE("[0x%x] padding load segment fail. %s %s", phdr[index].p_vaddr, strerror(errno), maps[ntfile[index].start].c_str()); @@ -518,6 +518,7 @@ void OpencoreImpl::Prepare(const char* filename) buffer.clear(); maps.clear(); self_maps.clear(); + SetCoreFilePath(filename); } void OpencoreImpl::Finish() @@ -541,6 +542,7 @@ void OpencoreImpl::Finish() free(ntfile); ntfile = nullptr; } + RemoveCoreFileSuffix(); JNI_LOGI("Coredump Done."); } @@ -633,3 +635,21 @@ bool OpencoreImpl::NeedFilterFile(const char* filename, int offset) munmap(mem, sb.st_size); return ret; } + +int OpencoreImpl::WriteAndRecord(const void *buf, size_t size, size_t count, FILE *stream) { + if (GetFileLimit() >= 0 && file_size + size * count > GetFileLimit()) { + auto remaining = GetFileLimit() - file_size; + JNI_LOGE("Core file size exceeds limit: write %zu bytes and %ld bytes until limit, " + "core limit %d, truncated", size * count, remaining, GetFileLimit()); + size = remaining > 0 ? remaining / count : 0; + + fwrite(buf, size, count, stream); + Finish(); + + AddCoreFileSuffix("truncated"); + _exit(0); + } + int ret = fwrite(buf, size, count, stream); + file_size += size * count; + return ret; +} diff --git a/opencore/src/main/cpp/arm/opencore_impl.h b/opencore/src/main/cpp/arm/opencore_impl.h index 703999f..94ef860 100644 --- a/opencore/src/main/cpp/arm/opencore_impl.h +++ b/opencore/src/main/cpp/arm/opencore_impl.h @@ -89,7 +89,7 @@ class OpencoreImpl : public Opencore { void CreateCoreNoteHeader(); void CreateCorePrStatus(pid_t pid); void CreateCoreAUXV(pid_t pid); - + int WriteAndRecord(const void *buf, size_t size, size_t count, FILE *stream); // ELF Header void WriteCoreHeader(FILE* fp); diff --git a/opencore/src/main/cpp/arm64/opencore_impl.cpp b/opencore/src/main/cpp/arm64/opencore_impl.cpp index af3a392..87f5fcc 100644 --- a/opencore/src/main/cpp/arm64/opencore_impl.cpp +++ b/opencore/src/main/cpp/arm64/opencore_impl.cpp @@ -250,7 +250,7 @@ void OpencoreImpl::CreateCoreAUXV(pid_t pid) void OpencoreImpl::WriteCoreHeader(FILE* fp) { - fwrite((void *)&ehdr, sizeof(Elf64_Ehdr), 1, fp); + WriteAndRecord((void *)&ehdr, sizeof(Elf64_Ehdr), 1, fp); } void OpencoreImpl::WriteCoreNoteHeader(FILE* fp) @@ -262,7 +262,7 @@ void OpencoreImpl::WriteCoreNoteHeader(FILE* fp) ) * prnum; note.p_filesz += (sizeof(uint64_t) + sizeof(Elf64_Nhdr) + 8) * prnum; // NT_ARM_TAGGED_ADDR_CTRL note.p_filesz += sizeof(Elf64_ntfile) * phnum + sizeof(Elf64_Nhdr) + 8 + 2 * sizeof(unsigned long) + fileslen; - fwrite((void *)¬e, sizeof(Elf64_Phdr), 1, fp); + WriteAndRecord((void *)¬e, sizeof(Elf64_Phdr), 1, fp); } void OpencoreImpl::WriteCoreProgramHeaders(FILE* fp) @@ -274,12 +274,12 @@ void OpencoreImpl::WriteCoreProgramHeaders(FILE* fp) } phdr[0].p_offset = offset; - fwrite(&phdr[0], sizeof(Elf64_Phdr), 1, fp); + WriteAndRecord(&phdr[0], sizeof(Elf64_Phdr), 1, fp); int index = 1; while (index < ehdr.e_phnum - 1) { phdr[index].p_offset = phdr[index - 1].p_offset + phdr[index-1].p_filesz; - fwrite(&phdr[index], sizeof(Elf64_Phdr), 1, fp); + WriteAndRecord(&phdr[index], sizeof(Elf64_Phdr), 1, fp); index++; } } @@ -297,9 +297,9 @@ void OpencoreImpl::WriteCorePrStatus(FILE* fp) int index = 0; while (index < prnum) { - fwrite(&elf_nhdr, sizeof(Elf64_Nhdr), 1, fp); - fwrite(magic, sizeof(magic), 1, fp); - fwrite(&prstatus[index], sizeof(Elf64_prstatus), 1, fp); + WriteAndRecord(&elf_nhdr, sizeof(Elf64_Nhdr), 1, fp); + WriteAndRecord(magic, sizeof(magic), 1, fp); + WriteAndRecord(&prstatus[index], sizeof(Elf64_prstatus), 1, fp); WriteCorePAC(prstatus[index].pr_pid ,fp); WriteCoreMTE(prstatus[index].pr_pid ,fp); index++; @@ -317,12 +317,12 @@ void OpencoreImpl::WriteCoreAUXV(FILE* fp) memset(magic, 0, sizeof(magic)); snprintf(magic, NOTE_CORE_NAME_SZ, ELFCOREMAGIC); - fwrite(&elf_nhdr, sizeof(Elf64_Nhdr), 1, fp); - fwrite(magic, sizeof(magic), 1, fp); + WriteAndRecord(&elf_nhdr, sizeof(Elf64_Nhdr), 1, fp); + WriteAndRecord(magic, sizeof(magic), 1, fp); int index = 0; while (index < auxvnum) { - fwrite(&auxv[index], sizeof(Elf64_auxv), 1, fp); + WriteAndRecord(&auxv[index], sizeof(Elf64_auxv), 1, fp); index++; } } @@ -339,8 +339,8 @@ void OpencoreImpl::WriteCorePAC(pid_t tid, FILE* fp) memset(magic, 0, sizeof(magic)); snprintf(magic, NOTE_LINUX_NAME_SZ, ELFLINUXMAGIC); - fwrite(&elf_nhdr, sizeof(Elf64_Nhdr), 1, fp); - fwrite(magic, sizeof(magic), 1, fp); + WriteAndRecord(&elf_nhdr, sizeof(Elf64_Nhdr), 1, fp); + WriteAndRecord(magic, sizeof(magic), 1, fp); user_pac_mask uregs; struct iovec pac_mask_iov = { @@ -353,14 +353,14 @@ void OpencoreImpl::WriteCorePAC(pid_t tid, FILE* fp) uregs.data_mask = mask; uregs.insn_mask = mask; } - fwrite(&uregs, sizeof(user_pac_mask), 1, fp); + WriteAndRecord(&uregs, sizeof(user_pac_mask), 1, fp); // NT_ARM_PAC_ENABLED_KEYS elf_nhdr.n_descsz = sizeof(uint64_t); elf_nhdr.n_type = NT_ARM_PAC_ENABLED_KEYS; - fwrite(&elf_nhdr, sizeof(Elf64_Nhdr), 1, fp); - fwrite(magic, sizeof(magic), 1, fp); + WriteAndRecord(&elf_nhdr, sizeof(Elf64_Nhdr), 1, fp); + WriteAndRecord(magic, sizeof(magic), 1, fp); uint64_t pac_enabled_keys; struct iovec pac_enabled_keys_iov = { @@ -371,7 +371,7 @@ void OpencoreImpl::WriteCorePAC(pid_t tid, FILE* fp) reinterpret_cast(&pac_enabled_keys_iov)) == -1) { pac_enabled_keys = 0; } - fwrite(&pac_enabled_keys, sizeof(uint64_t), 1, fp); + WriteAndRecord(&pac_enabled_keys, sizeof(uint64_t), 1, fp); } void OpencoreImpl::WriteCoreMTE(pid_t tid, FILE* fp) @@ -386,8 +386,8 @@ void OpencoreImpl::WriteCoreMTE(pid_t tid, FILE* fp) memset(magic, 0, sizeof(magic)); snprintf(magic, NOTE_LINUX_NAME_SZ, ELFLINUXMAGIC); - fwrite(&elf_nhdr, sizeof(Elf64_Nhdr), 1, fp); - fwrite(magic, sizeof(magic), 1, fp); + WriteAndRecord(&elf_nhdr, sizeof(Elf64_Nhdr), 1, fp); + WriteAndRecord(magic, sizeof(magic), 1, fp); uint64_t tagged_addr_ctrl; struct iovec tagged_addr_ctrl_iov = { @@ -397,7 +397,7 @@ void OpencoreImpl::WriteCoreMTE(pid_t tid, FILE* fp) if (ptrace(PTRACE_GETREGSET, tid, NT_ARM_TAGGED_ADDR_CTRL, reinterpret_cast(&tagged_addr_ctrl_iov)) == -1) { } - fwrite(&tagged_addr_ctrl, sizeof(uint64_t), 1, fp); + WriteAndRecord(&tagged_addr_ctrl, sizeof(uint64_t), 1, fp); } void OpencoreImpl::WriteNtFile(FILE* fp) @@ -411,21 +411,20 @@ void OpencoreImpl::WriteNtFile(FILE* fp) memset(magic, 0, sizeof(magic)); snprintf(magic, NOTE_CORE_NAME_SZ, ELFCOREMAGIC); - fwrite(&elf_nhdr, sizeof(Elf64_Nhdr), 1, fp); - fwrite(magic, sizeof(magic), 1, fp); + WriteAndRecord(&elf_nhdr, sizeof(Elf64_Nhdr), 1, fp); + WriteAndRecord(magic, sizeof(magic), 1, fp); uint64_t number = phnum; - fwrite(&number, sizeof(unsigned long), 1, fp); + WriteAndRecord(&number, sizeof(unsigned long), 1, fp); uint64_t page_size = sysconf(_SC_PAGE_SIZE); - fwrite(&page_size, sizeof(unsigned long), 1, fp); - + WriteAndRecord(&page_size, sizeof(unsigned long), 1, fp); int index = 0; while(index < phnum){ - fwrite(&ntfile[index], sizeof(Elf64_ntfile), 1, fp); + WriteAndRecord(&ntfile[index], sizeof(Elf64_ntfile), 1, fp); index++; } - fwrite(buffer.data(), buffer.size(), 1, fp); + WriteAndRecord(buffer.data(), buffer.size(), 1, fp); } void OpencoreImpl::AlignNoteSegment(FILE* fp) @@ -435,7 +434,7 @@ void OpencoreImpl::AlignNoteSegment(FILE* fp) char *ptr = (char *)malloc(size); if (ptr) { memset(ptr, 0, size); - fwrite(ptr, size, 1, fp); + WriteAndRecord(ptr, size, 1, fp); free(ptr); } } @@ -471,13 +470,13 @@ void OpencoreImpl::WriteCoreLoadSegment(pid_t pid, FILE* fp) Elf64_Addr target = phdr[index].p_vaddr; while (target < phdr[index].p_vaddr + phdr[index].p_memsz) { long mem = ptrace(PTRACE_PEEKTEXT, pid, target, 0x0); - fwrite(&mem, sizeof(mem), 1, fp); + WriteAndRecord(&mem, sizeof(mem), 1, fp); target = target + sizeof(Elf64_Addr); } } break; case MODE_COPY: { if (InSelfMaps(phdr[index].p_vaddr)) { - uint64_t ret = fwrite((void *)phdr[index].p_vaddr, phdr[index].p_memsz, 1, fp); + uint64_t ret = WriteAndRecord((void *)phdr[index].p_vaddr, phdr[index].p_memsz, 1, fp); if (ret != 1) { need_padd_zero = true; JNI_LOGE("[%p] write load segment fail. %s %s", @@ -492,11 +491,11 @@ void OpencoreImpl::WriteCoreLoadSegment(pid_t pid, FILE* fp) Elf64_Addr target = phdr[index].p_vaddr; while (target < phdr[index].p_vaddr + phdr[index].p_memsz) { long mem = ptrace(PTRACE_PEEKTEXT, pid, target, 0x0); - fwrite(&mem, sizeof(mem), 1, fp); + WriteAndRecord(&mem, sizeof(mem), 1, fp); target = target + sizeof(Elf64_Addr); } } else { - uint64_t ret = fwrite((void *)phdr[index].p_vaddr, phdr[index].p_memsz, 1, fp); + uint64_t ret = WriteAndRecord((void *)phdr[index].p_vaddr, phdr[index].p_memsz, 1, fp); if (ret != 1) { need_padd_zero = true; JNI_LOGE("[%p] write load segment fail. %s %s", @@ -509,7 +508,7 @@ void OpencoreImpl::WriteCoreLoadSegment(pid_t pid, FILE* fp) for (int i = 0; i < count; i++) { memset(&zero, 0x0, sizeof(zero)); pread(fd, &zero, sizeof(zero), phdr[index].p_vaddr + (i * sizeof(zero))); - uint64_t ret = fwrite(zero, sizeof(zero), 1, fp); + uint64_t ret = WriteAndRecord(zero, sizeof(zero), 1, fp); if (ret != 1) { need_padd_zero = true; JNI_LOGE("[%p] write load segment fail. %s %s", @@ -527,7 +526,7 @@ void OpencoreImpl::WriteCoreLoadSegment(pid_t pid, FILE* fp) fseek(fp, current_pos, SEEK_SET); int count = phdr[index].p_memsz / sizeof(zero); for (int i = 0; i < count; i++) { - uint64_t ret = fwrite(zero, sizeof(zero), 1, fp); + uint64_t ret = WriteAndRecord(zero, sizeof(zero), 1, fp); if (ret != 1) { JNI_LOGE("[%p] padding load segment fail. %s %s", (void *)phdr[index].p_vaddr, strerror(errno), maps[ntfile[index].start].c_str()); @@ -590,6 +589,7 @@ void OpencoreImpl::Prepare(const char* filename) buffer.clear(); maps.clear(); self_maps.clear(); + SetCoreFilePath(filename); } void OpencoreImpl::Finish() @@ -613,6 +613,7 @@ void OpencoreImpl::Finish() free(ntfile); ntfile = nullptr; } + RemoveCoreFileSuffix(); JNI_LOGI("Coredump Done."); } @@ -705,3 +706,21 @@ bool OpencoreImpl::NeedFilterFile(const char* filename, int offset) munmap(mem, sb.st_size); return ret; } + +int OpencoreImpl::WriteAndRecord(const void *buf, size_t size, size_t count, FILE *stream) { + if (GetFileLimit() >= 0 && file_size + size * count > GetFileLimit()) { + auto remaining = GetFileLimit() - file_size; + JNI_LOGE("Core file size exceeds limit: write %zu bytes and %ld bytes until limit, " + "core limit %d, truncated", size * count, remaining, GetFileLimit()); + size = remaining > 0 ? remaining / count : 0; + + fwrite(buf, size, count, stream); + Finish(); + + AddCoreFileSuffix("truncated"); + _exit(0); + } + int ret = fwrite(buf, size, count, stream); + file_size += size * count; + return ret; +} diff --git a/opencore/src/main/cpp/arm64/opencore_impl.h b/opencore/src/main/cpp/arm64/opencore_impl.h index 671990a..6b42fed 100644 --- a/opencore/src/main/cpp/arm64/opencore_impl.h +++ b/opencore/src/main/cpp/arm64/opencore_impl.h @@ -87,7 +87,7 @@ class OpencoreImpl : public Opencore { void CreateCoreNoteHeader(); void CreateCorePrStatus(pid_t pid); void CreateCoreAUXV(pid_t pid); - + int WriteAndRecord(const void *buf, size_t size, size_t count, FILE *stream); // ELF Header void WriteCoreHeader(FILE* fp); diff --git a/opencore/src/main/cpp/opencore.cpp b/opencore/src/main/cpp/opencore.cpp index 70eb432..3ab7f54 100644 --- a/opencore/src/main/cpp/opencore.cpp +++ b/opencore/src/main/cpp/opencore.cpp @@ -168,7 +168,7 @@ void Opencore::dump(bool java, int tid, const char* filename) if (!prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY)) need_restore_ptrace = true; - + output.append(".temp"); impl->DoCoreDump(output.c_str()); if (need_restore_dumpable) prctl(PR_SET_DUMPABLE, ori_dumpable); @@ -181,6 +181,7 @@ void Opencore::dump(bool java, int tid, const char* filename) if (callback) { callback(java, output.c_str()); } + } void Opencore::HandleSignal(int sig) @@ -277,6 +278,14 @@ void Opencore::setFlag(int flag) } } +void Opencore::setLimit(long limit) +{ + Opencore* impl = GetInstance(); + if (impl) { + impl->SetLimit(limit); + } +} + void Opencore::setTimeout(int sec) { Opencore* impl = GetInstance(); @@ -295,7 +304,14 @@ void Opencore::setFilter(int filter) void Opencore::TimeoutHandle(int) { - JNI_LOGI("Coredump timeout."); + Opencore* impl = GetInstance(); + if (impl) { + if (remove(impl->GetCoreFilePath().c_str()) == 0) { + JNI_LOGI("Coredump timeout, delete temp file"); + } else { + JNI_LOGI("Coredump timeout, delete temp file failed: %s", strerror(errno)); + } + } _exit(0); } @@ -337,3 +353,27 @@ bool Opencore::IsFilterSegment(char* flags, int inode, std::string segment, int return false; } + +void Opencore::AddCoreFileSuffix(const char *suffix) { + auto newFilePath = GetCoreFilePath() + '.' + suffix; + + if(rename(GetCoreFilePath().c_str(), newFilePath.c_str()) != 0) { + JNI_LOGE("Coredump rename %s to %s failed: %s", GetCoreFilePath().c_str(), newFilePath.c_str(), strerror(errno)); + } + SetCoreFilePath(newFilePath); + return; +} + +void Opencore::RemoveCoreFileSuffix() { + auto pos = GetCoreFilePath().rfind('.'); + if(pos == std::string::npos) { + JNI_LOGE("Error: No suffix found in core name"); + return; + } + std::string newFilePath = GetCoreFilePath().substr(0, pos); + + if(rename(GetCoreFilePath().c_str(), newFilePath.c_str()) != 0) { + JNI_LOGE("Coredump rename %s to %s failed: %s", GetCoreFilePath().c_str(), newFilePath.c_str(), strerror(errno)); + } + SetCoreFilePath(newFilePath); +} diff --git a/opencore/src/main/cpp/opencore.h b/opencore/src/main/cpp/opencore.h index ae1d88e..8f86e46 100644 --- a/opencore/src/main/cpp/opencore.h +++ b/opencore/src/main/cpp/opencore.h @@ -97,6 +97,8 @@ class Opencore { static const int DEF_TIMEOUT = 30; + static const long DEF_LIMIT = -1L; // unlimited + static const int INVALID_TID = 0; static const int FILTER_NONE = 0x0; @@ -116,6 +118,7 @@ class Opencore { static void setCallback(DumpCallback cb); static void setMode(int mode); static void setFlag(int flag); + static void setLimit(long limit); static void setTimeout(int sec); static void setFilter(int filter); static const char* getVersion() { return OPENCORE_VERSION; } @@ -126,22 +129,30 @@ class Opencore { flag = FLAG_CORE | FLAG_TID; state = STATE_OFF; timeout = DEF_TIMEOUT; + file_limit = DEF_LIMIT; tid = INVALID_TID; filter = FILTER_NONE; } + long file_size = 0; virtual bool DoCoreDump(const char* filename) = 0; virtual bool NeedFilterFile(const char* filename, int offset) = 0; std::string GetCoreDir() { return dir; } + std::string GetCoreFilePath() { return core_path; } + void SetCoreFilePath(std::string path) { core_path = path; } DumpCallback GetCallback() { return cb; } int GetMode() { return mode; } int GetFlag() { return flag; } int GetTimeout() { return timeout; } + int GetFileLimit() { return file_limit; } int GetFilter() { return filter; } + void AddCoreFileSuffix(const char *suffix); + void RemoveCoreFileSuffix(); private: void SetCoreDir(std::string d) { dir = d; } void SetCallback(DumpCallback c) { cb = c; } void SetMode(int m) { mode = m; } void SetFlag(int f) { flag = f; } + void SetLimit(long l) { file_limit = l; } void SetTimeout(int t) { timeout = t; } void SetFilter(int f) { filter = f; } void SetState(int s) { state = s; } @@ -150,10 +161,12 @@ class Opencore { DumpCallback cb; std::string dir; + std::string core_path; int mode; int flag; int state; int timeout; + long file_limit; int tid; int filter; }; diff --git a/opencore/src/main/cpp/opencore_jni.cpp b/opencore/src/main/cpp/opencore_jni.cpp index 457f5e5..d24ef89 100644 --- a/opencore/src/main/cpp/opencore_jni.cpp +++ b/opencore/src/main/cpp/opencore_jni.cpp @@ -95,6 +95,7 @@ JNIEXPORT jboolean JNICALL Java_penguin_opencore_sdk_Coredump_native_1doCoredump(JNIEnv *env, jobject /*thiz*/, jint tid, jstring filename) { jboolean isCopy; + if (filename != NULL) { const char *cstr = env->GetStringUTFChars(filename, &isCopy); Opencore::dump(true, tid, cstr); @@ -129,6 +130,12 @@ Java_penguin_opencore_sdk_Coredump_native_1setCoreFlag(JNIEnv *env, jobject /*th Opencore::setFlag(flag); } +extern "C" +JNIEXPORT void JNICALL +Java_penguin_opencore_sdk_Coredump_native_1setCoreLimit(JNIEnv *env, jobject /*thiz*/, jlong limit) { + Opencore::setLimit(limit); +} + extern "C" JNIEXPORT void JNICALL Java_penguin_opencore_sdk_Coredump_native_1setCoreTimeout(JNIEnv *env, jobject /*thiz*/, jint sec) { diff --git a/opencore/src/main/java/penguin/opencore/sdk/Coredump.java b/opencore/src/main/java/penguin/opencore/sdk/Coredump.java index 5c92d9d..6177929 100644 --- a/opencore/src/main/java/penguin/opencore/sdk/Coredump.java +++ b/opencore/src/main/java/penguin/opencore/sdk/Coredump.java @@ -45,6 +45,7 @@ public class Coredump { public static final int MODE_MAX = MODE_COPY2; private int mFlag = FLAG_CORE | FLAG_TID; + private long mLimit = DEF_LIMIT; public static final int FLAG_CORE = 1 << 0; public static final int FLAG_PROCESS_COMM = 1 << 1; public static final int FLAG_PID = 1 << 2; @@ -54,6 +55,8 @@ public class Coredump { private int mTimeout = DEF_TIMEOUT; public static final int DEF_TIMEOUT = 30; + // default unlimited, set to 10GB + public static final long DEF_LIMIT = 10L << 30; private int mFilter = FILTER_NONE; public static final int FILTER_NONE = 0x0; @@ -171,6 +174,11 @@ public void setCoreFlag(int flag) { native_setCoreFlag(mFlag); } + public void setCoreLimit(long limit) { + mLimit = limit; + native_setCoreLimit(mLimit); + } + public void setCoreTimeout(int sec) { mTimeout = sec; native_setCoreTimeout(sec); @@ -189,6 +197,7 @@ public void setCoreFilter(int filter) { private native void native_setCoreDir(String dir); private native void native_setCoreMode(int mode); private native void native_setCoreFlag(int flag); + private native void native_setCoreLimit(long limit); private native void native_setCoreTimeout(int sec); private native void native_setCoreFilter(int filter);