diff --git a/OAT.xml b/OAT.xml
index 790c1717a4b39925a0a3cbc9d5bd9c4532e9acd7..25a6918d8e1887b07690848ebb1549fa908c3fcb 100644
--- a/OAT.xml
+++ b/OAT.xml
@@ -78,6 +78,8 @@ Note:If the text contains special characters, please escape them according to th
+
+
@@ -91,6 +93,8 @@ Note:If the text contains special characters, please escape them according to th
+
+
diff --git a/common/cutil/dfx_cutil.c b/common/cutil/dfx_cutil.c
index 3a36b13db422d23cdbc544d857a3407c1251b66a..14b1be1598f94709f52321038b43a90319860583 100644
--- a/common/cutil/dfx_cutil.c
+++ b/common/cutil/dfx_cutil.c
@@ -86,22 +86,6 @@ uint64_t GetTimeMilliseconds(void)
(((uint64_t)ts.tv_nsec) / NUMBER_ONE_MILLION); // 1000000 : nanosecond to millisecond convert ratio
}
-bool TrimAndDupStr(const char* src, char* dst)
-{
- if (src == NULL || dst == NULL) {
- return false;
- }
-
- for (char ch = *src; ch != '\0' && ch != '\n';) {
- if (ch != ' ') {
- *dst++ = ch;
- }
- ch = *++src;
- }
- *dst = '\0';
- return true;
-}
-
uint64_t GetAbsTimeMilliSecondsCInterce(void)
{
struct timespec ts;
diff --git a/common/cutil/dfx_cutil.h b/common/cutil/dfx_cutil.h
index 8863644fa2deccb7724ee46dff417aed4dc0675e..c2e5325d8130f2ea0f25566b04f81d55ce3cd8d0 100644
--- a/common/cutil/dfx_cutil.h
+++ b/common/cutil/dfx_cutil.h
@@ -34,8 +34,6 @@ AT_SYMBOL_HIDDEN bool GetProcessName(char* buffer, size_t bufferSz);
AT_SYMBOL_HIDDEN uint64_t GetTimeMilliseconds(void);
-AT_SYMBOL_HIDDEN bool TrimAndDupStr(const char* src, char* dst);
-
AT_SYMBOL_HIDDEN uint64_t GetAbsTimeMilliSecondsCInterce(void);
AT_SYMBOL_HIDDEN void ParseSiValue(const siginfo_t* si, uint64_t* endTime, int* tid);
diff --git a/common/dfxutil/proc_util.cpp b/common/dfxutil/proc_util.cpp
index a3180d693dc07763209dc61ddb08455db9571f28..b96707b5180d6afa980016c7e9742d5b0eadabe7 100644
--- a/common/dfxutil/proc_util.cpp
+++ b/common/dfxutil/proc_util.cpp
@@ -45,7 +45,6 @@ bool Schedstat::ParseSchedstat(const std::string& schedstatPath)
{
char realPath[PATH_MAX] = {0};
if (realpath(schedstatPath.c_str(), realPath) == nullptr) {
- DFXLOGE("path invalid. %{public}s", schedstatPath.c_str());
return false;
}
@@ -104,6 +103,7 @@ bool ThreadInfo::ParserThreadInfo(pid_t tid)
ProcessInfo info;
if (!ParseProcInfo(tid, info)) {
+ DFXLOGE("read %{public}d info failed.", tid);
return false;
}
@@ -222,7 +222,6 @@ bool ParseStat(const std::string& statPath, ProcessInfo& info)
{
char realPath[PATH_MAX] = {0};
if (realpath(statPath.c_str(), realPath) == nullptr) {
- DFXLOGE("path invalid. %{public}s", statPath.c_str());
return false;
}
diff --git a/common/dfxutil/smart_fd.h b/common/dfxutil/smart_fd.h
index f24d67f43ee83777064f889f9f0f5ab7ad657f8a..6eb414ae5bb989bf612400ce36ec1060a4527eff 100644
--- a/common/dfxutil/smart_fd.h
+++ b/common/dfxutil/smart_fd.h
@@ -27,9 +27,11 @@ public:
SmartFd() = default;
explicit SmartFd(int fd, bool fdsan = true) : fd_(fd), fdsan_(fdsan)
{
+#ifndef is_host
if (fd_ >= 0 && fdsan_) {
fdsan_exchange_owner_tag(fd_, 0, fdsan_create_owner_tag(FDSAN_OWNER_TYPE_FILE, DFX_FDSAN_DOMAIN));
}
+#endif // is_host
}
~SmartFd()
@@ -84,10 +86,12 @@ private:
if (fd_ < 0) {
return;
}
+#ifndef is_host
if (fdsan_) {
fdsan_close_with_tag(fd_, fdsan_create_owner_tag(FDSAN_OWNER_TYPE_FILE, DFX_FDSAN_DOMAIN));
return;
}
+#endif // is_host
close(fd_);
}
diff --git a/interfaces/innerkits/dump_catcher/lite_perf.cpp b/interfaces/innerkits/dump_catcher/lite_perf.cpp
index 0b89c8ff117770d9c8cbf08171a0c8ed9ea267d9..c1bfd55c1cde004b2c637efacbcee55c6ef9bec0 100644
--- a/interfaces/innerkits/dump_catcher/lite_perf.cpp
+++ b/interfaces/innerkits/dump_catcher/lite_perf.cpp
@@ -300,9 +300,9 @@ int LitePerf::Impl::ExecDump(const std::vector& tids, int freq, int duratio
}
pid_t pid = 0;
- pid = vfork();
+ pid = fork();
if (pid < 0) {
- DFXLOGE("Failed to vfork.");
+ DFXLOGE("Failed to fork.");
return -1;
}
if (pid == 0) {
@@ -312,9 +312,9 @@ int LitePerf::Impl::ExecDump(const std::vector& tids, int freq, int duratio
_exit(-1);
}
- pid_t dumpPid = vfork();
+ pid_t dumpPid = fork();
if (dumpPid < 0) {
- DFXLOGE("Failed to vfork.");
+ DFXLOGE("Failed to fork.");
_exit(-1);
}
if (dumpPid == 0) {
diff --git a/interfaces/innerkits/formatter/dfx_json_formatter.cpp b/interfaces/innerkits/formatter/dfx_json_formatter.cpp
index ac349891bac541a3055b61ea8456da37a51cb195..477d733883e87d2dc68c4f6dd3ea432507390c57 100644
--- a/interfaces/innerkits/formatter/dfx_json_formatter.cpp
+++ b/interfaces/innerkits/formatter/dfx_json_formatter.cpp
@@ -27,6 +27,14 @@ namespace HiviewDFX {
#ifndef is_ohos_lite
namespace {
const int FRAME_BUF_LEN = 1024;
+static std::string JsonAsString(const Json::Value& val)
+{
+ if (val.isConvertibleTo(Json::stringValue)) {
+ return val.asString();
+ }
+ return "";
+}
+
static bool FormatJsFrame(const Json::Value& frames, const uint32_t& frameIdx, std::string& outStr)
{
const int jsIdxLen = 10;
@@ -36,18 +44,18 @@ static bool FormatJsFrame(const Json::Value& frames, const uint32_t& frameIdx, s
return false;
}
outStr = std::string(buf);
- std::string symbol = frames[frameIdx]["symbol"].asString();
+ std::string symbol = JsonAsString(frames[frameIdx]["symbol"]);
if (!symbol.empty()) {
outStr.append(" " + symbol);
}
- std::string packageName = frames[frameIdx]["packageName"].asString();
+ std::string packageName = JsonAsString(frames[frameIdx]["packageName"]);
if (!packageName.empty()) {
outStr.append(" " + packageName);
}
- std::string file = frames[frameIdx]["file"].asString();
+ std::string file = JsonAsString(frames[frameIdx]["file"]);
if (!file.empty()) {
- std::string line = frames[frameIdx]["line"].asString();
- std::string column = frames[frameIdx]["column"].asString();
+ std::string line = JsonAsString(frames[frameIdx]["line"]);
+ std::string column = JsonAsString(frames[frameIdx]["column"]);
outStr.append(" (" + file + ":" + line + ":" + column + ")");
}
return true;
@@ -57,11 +65,11 @@ static bool FormatNativeFrame(const Json::Value& frames, const uint32_t& frameId
{
char buf[FRAME_BUF_LEN] = {0};
char format[] = "#%02u pc %s %s";
- std::string buildId = frames[frameIdx]["buildId"].asString();
- std::string file = frames[frameIdx]["file"].asString();
- std::string offset = frames[frameIdx]["offset"].asString();
- std::string pc = frames[frameIdx]["pc"].asString();
- std::string symbol = frames[frameIdx]["symbol"].asString();
+ std::string buildId = JsonAsString(frames[frameIdx]["buildId"]);
+ std::string file = JsonAsString(frames[frameIdx]["file"]);
+ std::string offset = JsonAsString(frames[frameIdx]["offset"]);
+ std::string pc = JsonAsString(frames[frameIdx]["pc"]);
+ std::string symbol = JsonAsString(frames[frameIdx]["symbol"]);
if (snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, format, frameIdx, pc.c_str(),
file.empty() ? "Unknown" : file.c_str()) <= 0) {
return false;
@@ -85,19 +93,30 @@ bool DfxJsonFormatter::FormatJsonStack(const std::string& jsonStack, std::string
outStackStr.append("Failed to parse json stack info.");
return false;
}
-
+ constexpr int maxThreadCount = 10000;
+ if (threads.size() > maxThreadCount) {
+ outStackStr.append("Thread count exceeds limit(10000).");
+ return false;
+ }
for (uint32_t i = 0; i < threads.size(); ++i) {
std::string ss;
Json::Value thread = threads[i];
if (thread["tid"].isConvertibleTo(Json::stringValue) &&
thread["thread_name"].isConvertibleTo(Json::stringValue)) {
- ss += "Tid:" + thread["tid"].asString() + ", Name:" + thread["thread_name"].asString() + "\n";
+ ss += "Tid:" + JsonAsString(thread["tid"]) + ", Name:" + JsonAsString(thread["thread_name"]) + "\n";
+ }
+ if (!thread.isMember("frames") || !thread["frames"].isArray()) {
+ continue;
}
const Json::Value frames = thread["frames"];
+ constexpr int maxFrameNum = 1000;
+ if (frames.size() > maxFrameNum) {
+ continue;
+ }
for (uint32_t j = 0; j < frames.size(); ++j) {
std::string frameStr = "";
bool formatStatus = false;
- if (frames[j]["line"].asString().empty()) {
+ if (JsonAsString(frames[j]["line"]).empty()) {
formatStatus = FormatNativeFrame(frames, j, frameStr);
} else {
formatStatus = FormatJsFrame(frames, j, frameStr);
@@ -110,6 +129,7 @@ bool DfxJsonFormatter::FormatJsonStack(const std::string& jsonStack, std::string
return false;
}
}
+
outStackStr.append(ss);
}
return true;
diff --git a/interfaces/innerkits/signal_handler/BUILD.gn b/interfaces/innerkits/signal_handler/BUILD.gn
index 28af9149b8522a9f3c15e045664b2752e6b010d6..48ca8f28ad61b3d4003dea0424d388285b0cd762 100644
--- a/interfaces/innerkits/signal_handler/BUILD.gn
+++ b/interfaces/innerkits/signal_handler/BUILD.gn
@@ -83,7 +83,7 @@ if (defined(ohos_lite)) {
]
innerapi_tags = [
- "chipsetsdk_indirect",
+ "chipsetsdk_sp_indirect",
"platformsdk_indirect",
]
install_enable = true
diff --git a/interfaces/innerkits/signal_handler/dfx_dumprequest.c b/interfaces/innerkits/signal_handler/dfx_dumprequest.c
index be28a8955b2f5776b49738e025877d27e1967a4e..88e040a029d44307909ec8b97d4fc877795f5d63 100644
--- a/interfaces/innerkits/signal_handler/dfx_dumprequest.c
+++ b/interfaces/innerkits/signal_handler/dfx_dumprequest.c
@@ -395,16 +395,16 @@ static bool StartProcessdump(void)
} else if (pid == 0) {
if (!InitPipe()) {
DFXLOGE("init pipe fail");
- _exit(errno);
+ syscall(SYS_exit, errno);
}
pid_t processDumpPid = ForkBySyscall();
if (processDumpPid < 0) {
DFXLOGE("Failed to fork processdump(%{public}d)", errno);
- _exit(errno);
+ syscall(SYS_exit, errno);
} else if (processDumpPid > 0) {
int ret = ReadProcessDumpGetRegsMsg() == true ? 0 : errno;
DFXLOGI("exit the processdump parent process.");
- _exit(ret);
+ syscall(SYS_exit, ret);
} else {
uint64_t endTime;
int tid;
@@ -422,7 +422,7 @@ static bool StartProcessdump(void)
} else {
DFXLOGI("current has spend all time, not execl processdump");
}
- _exit(0);
+ syscall(SYS_exit, 0);
}
}
return WaitProcessExitTimeout(pid, WAITPID_TIMEOUT);
@@ -430,7 +430,7 @@ static bool StartProcessdump(void)
static bool StartVMProcessUnwind(void)
{
- uint32_t startTime = GetAbsTimeMilliSecondsCInterce();
+ uint64_t startTime = GetAbsTimeMilliSecondsCInterce();
pid_t pid = ForkBySyscall();
if (pid < 0) {
DFXLOGE("Failed to fork vm process(%{public}d)", errno);
@@ -443,10 +443,10 @@ static bool StartVMProcessUnwind(void)
GetAbsTimeMilliSecondsCInterce() - startTime);
g_vmRealPid = GetRealPid();
DFXLOGI("vm prorcecc read pid = %{public}ld", g_vmRealPid);
- _exit(0);
+ syscall(SYS_exit, 0);
} else {
DFXLOGI("exit dummy vm process");
- _exit(0);
+ syscall(SYS_exit, 0);
}
}
diff --git a/interfaces/innerkits/unwinder/BUILD.gn b/interfaces/innerkits/unwinder/BUILD.gn
index fa4028c2ffb498b6825ee8809fabec4ba59478f3..12a6da598603fd2c4f42aa79512796214dc22164 100644
--- a/interfaces/innerkits/unwinder/BUILD.gn
+++ b/interfaces/innerkits/unwinder/BUILD.gn
@@ -333,6 +333,9 @@ if (defined(ohos_lite)) {
"is_emulator=${is_emulator}",
"DFX_NO_PRINT_LOG",
]
+ if (is_linux || is_mingw) {
+ defines += [ "is_host" ]
+ }
}
ohos_static_library("unwinder_host") {
diff --git a/interfaces/innerkits/unwinder/src/unwind_local/thread_context.cpp b/interfaces/innerkits/unwinder/src/unwind_local/thread_context.cpp
index 7895fa4f5e6f7ea608fef6cb5470f80a304190bd..b41bd3770aa6591e2f5cc1f1037eeb2502bf6d74 100644
--- a/interfaces/innerkits/unwinder/src/unwind_local/thread_context.cpp
+++ b/interfaces/innerkits/unwinder/src/unwind_local/thread_context.cpp
@@ -50,6 +50,9 @@ namespace {
std::mutex g_localMutex;
std::map> g_contextMap {};
constexpr std::chrono::seconds TIME_OUT = std::chrono::seconds(1);
+#ifndef __aarch64__
+constexpr std::chrono::seconds TIME_OUT_IN_COPY_CONTEXT = std::chrono::seconds(3);
+#endif
void CreateContext(std::shared_ptr& threadContext)
{
@@ -175,7 +178,7 @@ NO_SANITIZE void CopyContextAndWaitTimeout(int sig, siginfo_t *si, void *context
ctxPtr->tid = static_cast(ThreadContextStatus::CONTEXT_READY);
ctxPtr->cv.notify_all();
- ctxPtr->cv.wait_for(lock, TIME_OUT);
+ ctxPtr->cv.wait_for(lock, TIME_OUT_IN_COPY_CONTEXT);
ctxPtr->tid = static_cast(ThreadContextStatus::CONTEXT_UNUSED);
#endif
}
diff --git a/services/BUILD.gn b/services/BUILD.gn
index aa5b93dab08bea6e967d051be56feaa5b3217f7b..720a9d10b49b1b13a7b5614a092d4bd304acf462 100644
--- a/services/BUILD.gn
+++ b/services/BUILD.gn
@@ -1,4 +1,4 @@
-# Copyright (c) 2021-2024 Huawei Device Co., Ltd.
+# Copyright (c) 2021-2025 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
@@ -20,7 +20,6 @@ faultloggerd_sources = [
"fault_logger_server.cpp",
"fault_logger_service.cpp",
"temp_file_manager.cpp",
- "fault_coredump_service.cpp",
"fault_common_util.cpp"
]
@@ -78,6 +77,14 @@ if (defined(ohos_lite)) {
}
} else {
faultloggerd_sources += [
+ "./coredump/coredump_callback_service.cpp",
+ "./coredump/coredump_facade.cpp",
+ "./coredump/coredump_manager_service.cpp",
+ "./coredump/coredump_session_manager.cpp",
+ "./coredump/coredump_session_service.cpp",
+ "./coredump/coredump_session_state.cpp",
+ "./coredump/coredump_signal_service.cpp",
+ "./coredump/coredump_task_scheduler.cpp",
"./snapshot/kernel_snapshot_content_builder.cpp",
"./snapshot/kernel_snapshot_kernel_frame.cpp",
"./snapshot/kernel_snapshot_manager.cpp",
@@ -94,6 +101,7 @@ if (defined(ohos_lite)) {
include_dirs = [
".",
+ "./coredump",
"./snapshot",
"$faultloggerd_interfaces_path/common",
"$faultloggerd_path/common/dfxlog",
@@ -142,6 +150,12 @@ if (defined(ohos_lite)) {
subsystem_name = "hiviewdfx"
}
+ ohos_prebuilt_etc("fault_coredump.json") {
+ source = "config/fault_coredump.json"
+ part_name = "faultloggerd"
+ subsystem_name = "hiviewdfx"
+ }
+
ohos_executable("faultloggerd") {
install_enable = true
configs = [
@@ -156,13 +170,13 @@ if (defined(ohos_lite)) {
"DFX_LOG_HILOG_BASE",
"DFX_ENABLE_TRACE",
]
-
deps = [
":faultlogger.conf",
":faultloggerd.para",
":faultloggerd.para.dac",
":faultloggerd_config.json",
+ ":fault_coredump.json",
"$faultloggerd_frameworks_path/localhandler:dfx_local_handler_src",
"$faultloggerd_interfaces_path/innerkits/procinfo:libdfx_procinfo",
"$faultloggerd_path/common/dfxlog:dfx_hilog_base",
diff --git a/services/config/fault_coredump.json b/services/config/fault_coredump.json
new file mode 100644
index 0000000000000000000000000000000000000000..bc9ee7170456cb2c6e0c6f0a9d94a42bb274477f
--- /dev/null
+++ b/services/config/fault_coredump.json
@@ -0,0 +1,34 @@
+{
+ "whitelist": [0, 1202, 7005],
+ "coredumpProfiles": {
+ "FULL": {
+ "process": {
+ "prpsinfo": true,
+ "multiThread": true,
+ "auxv": true,
+ "dumpMappings": true
+ },
+ "threads": {
+ "prstatus": true,
+ "fpregset": true,
+ "siginfo": true,
+ "dumpAll": true,
+ "armPacMask": true,
+ "armTaggedAddrCtrl": true
+ },
+ "dumpType": "FULL",
+ "outputPath": "/data/storage/el2/base/files",
+ "maxCoredumpSize": 0,
+ "includeTags": true,
+ "hwsanTagRegion": 1048576,
+ "isPtraceBySelf": false,
+ "isNeedDumpPid": false,
+ "loadCfg": {
+ "coredumpFilter": 0,
+ "excludePaths": "[vvar]",
+ "requiredPriority": "r",
+ "excludeSubstrings": "CMGC"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/services/coredump/coredump_callback_service.cpp b/services/coredump/coredump_callback_service.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f7c5b6d2edcbdd2642d5aa8afb48a949a62c94cd
--- /dev/null
+++ b/services/coredump/coredump_callback_service.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "coredump_callback_service.h"
+#include "faultloggerd_socket.h"
+
+namespace OHOS {
+namespace HiviewDFX {
+int32_t CoredumpCallbackService::OnRequest(const std::string& socketName, int32_t connectionFd,
+ const CoreDumpStatusData& requestData)
+{
+ DFXLOGI("Receive coredump status request for pid:%{public}d, status:%{public}d", requestData.pid,
+ requestData.coredumpStatus);
+
+ int res = CoredumpCallbackValidator::ValidateRequest(socketName, connectionFd, requestData);
+ if (res != 0) {
+ SendMsgToSocket(connectionFd, &res, sizeof(res));
+ return res;
+ }
+
+ if (requestData.coredumpStatus == CoreDumpStatus::CORE_DUMP_START) {
+ res = HandleUpdateWorkerPid(requestData);
+ } else {
+ res = HandleReport(requestData);
+ }
+ SendMsgToSocket(connectionFd, &res, sizeof(res));
+ return res;
+}
+
+int32_t CoredumpCallbackService::HandleUpdateWorkerPid(const CoreDumpStatusData& requestData)
+{
+ if (requestData.processDumpPid <= 0) {
+ DFXLOGE("workpid is invalid, targetpid %{public}d errno%{public}d", requestData.pid, requestData.retCode);
+ }
+
+ CoredumpCallbackReport req;
+ req.workerPid = requestData.processDumpPid;
+ bool ret = cf_.UpdateWorkerPid(requestData.pid, req.workerPid);
+ return ret ? ResponseCode::REQUEST_SUCCESS : ResponseCode::ABNORMAL_SERVICE;
+}
+
+int32_t CoredumpCallbackService::HandleReport(const CoreDumpStatusData& requestData)
+{
+ CoredumpCallbackReport req;
+ req.status = requestData.retCode == 0 ? CoredumpStatus::SUCCESS : CoredumpStatus::FAILED;
+ req.filePath = requestData.fileName;
+ cf_.ReportResult(requestData.pid, req);
+
+ return ResponseCode::REQUEST_SUCCESS;
+}
+
+int32_t CoredumpCallbackValidator::ValidateRequest(const std::string& socketName, int32_t connectionFd,
+ const CoreDumpStatusData& requestData)
+{
+ if (!IsValidPid(requestData.pid)) {
+ DFXLOGE("Invalid PID: %{public}d", requestData.pid);
+ return ResponseCode::REQUEST_REJECT;
+ }
+
+ if (!IsAuthorizedSocket(socketName)) {
+ DFXLOGE("Unauthorized socket: %{public}s", socketName.c_str());
+ return ResponseCode::REQUEST_REJECT;
+ }
+ return 0;
+}
+
+bool CoredumpCallbackValidator::IsValidPid(pid_t pid)
+{
+ return pid > 0;
+}
+
+bool CoredumpCallbackValidator::IsAuthorizedSocket(const std::string& socketName)
+{
+ return socketName == SERVER_SOCKET_NAME;
+}
+}
+}
diff --git a/services/coredump/coredump_callback_service.h b/services/coredump/coredump_callback_service.h
new file mode 100644
index 0000000000000000000000000000000000000000..340817fc59671d66843c84a055fa05120bc70bfb
--- /dev/null
+++ b/services/coredump/coredump_callback_service.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef COREDUMP_CALLBACK_SERVICE_H
+#define COREDUMP_CALLBACK_SERVICE_H
+
+#include "dfx_socket_request.h"
+#include "fault_logger_service.h"
+#include "coredump_facade.h"
+
+namespace OHOS {
+namespace HiviewDFX {
+class CoredumpCallbackService : public FaultLoggerService {
+public:
+ int32_t OnRequest(const std::string& socketName, int32_t connectionFd,
+ const CoreDumpStatusData& requestData) override;
+private:
+ int32_t HandleUpdateWorkerPid(const CoreDumpStatusData& requestData);
+ int32_t HandleReport(const CoreDumpStatusData& requestData);
+ CoredumpFacade cf_;
+};
+
+class CoredumpCallbackValidator {
+public:
+ static int32_t ValidateRequest(const std::string& socketName, int32_t connectionFd,
+ const CoreDumpStatusData& requestData);
+private:
+ static bool IsValidPid(pid_t pid);
+ static bool IsAuthorizedSocket(const std::string& socketName);
+};
+}
+}
+#endif
diff --git a/services/coredump/coredump_facade.cpp b/services/coredump/coredump_facade.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..53dee5113f33f9bb53a4e079d88b303222678729
--- /dev/null
+++ b/services/coredump/coredump_facade.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "coredump_facade.h"
+#include "coredump_session_manager.h"
+
+namespace OHOS {
+namespace HiviewDFX {
+bool CoredumpFacade::CreateCoredump(const CreateCoredumpRequest& req)
+{
+ sessionService_.CreateSession(req);
+ signalService_.SendStartSignal(req.targetPid);
+ constexpr int32_t maxCoredumpDelayTime = 10 * 1000;
+ taskScheduler_.ScheduleCancelTime(req.targetPid, maxCoredumpDelayTime);
+ return true;
+}
+
+void CoredumpFacade::CancelCoredump(SessionId sessionId)
+{
+ sessionService_.CancelSession(sessionId);
+ const auto session = CoredumpSessionManager::Instance().GetSession(sessionId);
+ if (!session) {
+ return;
+ }
+ stateContext_.HandleEvent(*session, CoredumpEvent::CANCEL);
+}
+
+bool CoredumpFacade::UpdateWorkerPid(SessionId sessionId, pid_t workerPid)
+{
+ DFXLOGI("%{public}s sessionId %{public}d, workerPid %{public}d", __func__, sessionId, workerPid);
+ sessionService_.UpdateWorkerPid(sessionId, workerPid);
+
+ const auto session = CoredumpSessionManager::Instance().GetSession(sessionId);
+ if (!session) {
+ return false;
+ }
+ stateContext_.HandleEvent(*session, CoredumpEvent::UPDATE_DUMPER);
+ return true;
+}
+
+void CoredumpFacade::ReportResult(SessionId sessionId, const CoredumpCallbackReport& rpt)
+{
+ DFXLOGI("%{public}s sessionId %{public}d path %{public}s", __func__, sessionId, rpt.filePath.c_str());
+ sessionService_.UpdateReport(sessionId, rpt);
+ const auto session = CoredumpSessionManager::Instance().GetSession(sessionId);
+ if (!session) {
+ return;
+ }
+ if (rpt.status == CoredumpStatus::SUCCESS) {
+ stateContext_.HandleEvent(*session, CoredumpEvent::REPORT_SUCCESS);
+ } else {
+ stateContext_.HandleEvent(*session, CoredumpEvent::REPORT_FAIL);
+ }
+}
+
+void CoredumpFacade::OnTimeout(SessionId sessionId)
+{
+ const auto session = CoredumpSessionManager::Instance().GetSession(sessionId);
+ if (!session) {
+ return;
+ }
+ stateContext_.HandleEvent(*session, CoredumpEvent::TIMEOUT);
+}
+}
+}
diff --git a/services/coredump/coredump_facade.h b/services/coredump/coredump_facade.h
new file mode 100644
index 0000000000000000000000000000000000000000..ba45e66f3b88f6244d4e5154e7452625a1832245
--- /dev/null
+++ b/services/coredump/coredump_facade.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef COREDUMP_FACADE_H
+#define COREDUMP_FACADE_H
+
+#include "coredump_session_service.h"
+#include "coredump_signal_service.h"
+#include "coredump_task_scheduler.h"
+#include "coredump_session_state.h"
+
+namespace OHOS {
+namespace HiviewDFX {
+class CoredumpFacade {
+public:
+ bool CreateCoredump(const CreateCoredumpRequest& req);
+ void CancelCoredump(SessionId sessionId);
+ bool UpdateWorkerPid(SessionId sessionId, pid_t workerPid);
+ void ReportResult(SessionId sessionId, const CoredumpCallbackReport& rpt);
+ void OnTimeout(SessionId sessionId);
+private:
+ CoredumpSessionService sessionService_;
+ CoredumpSignalService signalService_;
+ CoredumpTaskScheduler taskScheduler_;
+ SessionStateContext stateContext_;
+};
+}
+}
+#endif
diff --git a/services/coredump/coredump_manager_service.cpp b/services/coredump/coredump_manager_service.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..87208c0e36a5d3ecb4b79d11af8db411780d9d34
--- /dev/null
+++ b/services/coredump/coredump_manager_service.cpp
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "coredump_manager_service.h"
+
+#include
+#include
+
+#include "coredump_model.h"
+#include "fault_common_util.h"
+#include "faultloggerd_socket.h"
+#include "file_util.h"
+
+namespace OHOS {
+namespace HiviewDFX {
+int32_t CoredumpManagerService::OnRequest(const std::string& socketName, int32_t connectionFd,
+ const CoreDumpRequestData& requestData)
+{
+ DFXLOGI("Receive coredump request for pid:%{public}d, action:%{public}s.", requestData.pid,
+ requestData.coredumpAction == 0 ? "save":"cancel");
+
+ int res = CoredumpRequestValidator::ValidateRequest(socketName, connectionFd, requestData);
+ if (res != ResponseCode::REQUEST_SUCCESS) {
+ SendMsgToSocket(connectionFd, &res, sizeof(res));
+ return res;
+ }
+
+ if (requestData.coredumpAction == CoreDumpAction::DO_CORE_DUMP) {
+ res = HandleCreate(connectionFd, requestData);
+ } else if (requestData.coredumpAction == CoreDumpAction::CANCEL_CORE_DUMP) {
+ res = HandleCancel(requestData);
+ }
+ SendMsgToSocket(connectionFd, &res, sizeof(res));
+ return res;
+}
+
+int32_t CoredumpManagerService::HandleCreate(int32_t connectionFd, const CoreDumpRequestData& requestData)
+{
+ auto session = sessionManager_.GetSession(requestData.pid);
+ if (session) {
+ DFXLOGI("coredump pid %{public}d is dumping", requestData.pid);
+ return ResponseCode::CORE_DUMP_REPEAT;
+ }
+
+ CreateCoredumpRequest request;
+ request.endTime = requestData.endTime;
+ request.clientFd = dup(connectionFd);
+ if (request.clientFd == -1) {
+ DFXLOGE("dup connection socket fd error %{public}d", errno);
+ return ResponseCode::DEFAULT_ERROR_CODE;
+ }
+ request.targetPid = requestData.pid;
+ return cf_.CreateCoredump(request) ? ResponseCode::REQUEST_SUCCESS : ResponseCode::DEFAULT_ERROR_CODE;
+}
+
+int32_t CoredumpManagerService::HandleCancel(const CoreDumpRequestData& requestData)
+{
+ auto session = sessionManager_.GetSession(requestData.pid);
+ if (!session) {
+ DFXLOGI("pid %{public}d is not dumping, just return!", requestData.pid);
+ return ResponseCode::DEFAULT_ERROR_CODE;
+ }
+
+ cf_.CancelCoredump(requestData.pid);
+ return ResponseCode::REQUEST_SUCCESS;
+}
+
+bool CoredumpRequestValidator::CheckCoredumpUID(uint32_t callerUid)
+{
+ const std::string configPath = "/system/etc/fault_coredump.json";
+ FaultCoredumpConfig::GetInstance(configPath);
+
+ if (FaultCoredumpConfig::GetInstance().Contains(callerUid)) {
+ DFXLOGI("UID %{public}d is whitelisted.", callerUid);
+ return true;
+ } else {
+ DFXLOGI("UID %{public}d is NOT whitelisted.", callerUid);
+ return false;
+ }
+}
+
+int32_t CoredumpRequestValidator::ValidateRequest(const std::string& socketName, int32_t connectionFd,
+ const CoreDumpRequestData& requestData)
+{
+ if (!IsValidPid(requestData.pid)) {
+ DFXLOGE("Invalid PID: %{public}d", requestData.pid);
+ return ResponseCode::REQUEST_REJECT;
+ }
+
+ if (!IsAuthorizedSocket(socketName)) {
+ DFXLOGE("Unauthorized socket: %{public}s", socketName.c_str());
+ return ResponseCode::REQUEST_REJECT;
+ }
+
+ if (!IsAuthorizedUid(connectionFd)) {
+ DFXLOGE("Unauthorized UID:");
+ return ResponseCode::REQUEST_REJECT;
+ }
+
+ if (TempFileManager::CheckCrashFileRecord(requestData.pid)) {
+ DFXLOGW(" pid(%{public}d) has been crashed, break.",
+ requestData.pid);
+ return ResponseCode::CORE_PROCESS_CRASHED;
+ }
+ return ResponseCode::REQUEST_SUCCESS;
+}
+
+bool CoredumpRequestValidator::IsValidPid(pid_t pid)
+{
+ return pid > 0;
+}
+
+bool CoredumpRequestValidator::IsAuthorizedSocket(const std::string& socketName)
+{
+ return socketName == SERVER_SOCKET_NAME;
+}
+
+bool CoredumpRequestValidator::IsAuthorizedUid(int32_t connectionFd)
+{
+ struct ucred creds;
+ if (!FaultCommonUtil::GetUcredByPeerCred(creds, connectionFd)) {
+ return false;
+ }
+ return CheckCoredumpUID(creds.uid);
+}
+
+FaultCoredumpConfig& FaultCoredumpConfig::GetInstance(const std::string& jsonFilePath)
+{
+ static FaultCoredumpConfig instance;
+ static bool initialized = false;
+
+ if (!initialized && !jsonFilePath.empty()) {
+ std::string jsonText;
+ if (!LoadStringFromFile(jsonFilePath, jsonText)) {
+ DFXLOGE("Failed to read JSON file.");
+ } else if (!instance.Parse(jsonText)) {
+ DFXLOGE("Failed to parse whitelist.");
+ } else {
+ initialized = true;
+ }
+ }
+
+ return instance;
+}
+
+bool FaultCoredumpConfig::Contains(uint32_t uid) const
+{
+ for (uint32_t allowed : uids) {
+ if (allowed == uid) return true;
+ }
+ return false;
+}
+
+bool FaultCoredumpConfig::Parse(const std::string& jsonText)
+{
+ cJSON* root = cJSON_Parse(jsonText.c_str());
+ if (!root) {
+ DFXLOGE("Failed to parse JSON: %{public}s", cJSON_GetErrorPtr());
+ return false;
+ }
+
+ const cJSON* whitelistArray = cJSON_GetObjectItem(root, "whitelist");
+ if (!cJSON_IsArray(whitelistArray)) {
+ DFXLOGE("whitelist is missing or not an array");
+ cJSON_Delete(root);
+ return false;
+ }
+
+ cJSON* uid = nullptr;
+ cJSON_ArrayForEach(uid, whitelistArray) {
+ if (!cJSON_IsNumber(uid) || uid->valueint < 0) {
+ char *printed = cJSON_Print(uid);
+ DFXLOGE("Invalid UID in whitelist: %{public}s", printed);
+ cJSON_free(printed);
+ continue;
+ }
+ uids.push_back(static_cast(uid->valueint));
+ }
+
+ cJSON_Delete(root);
+ return true;
+}
+}
+}
diff --git a/services/coredump/coredump_manager_service.h b/services/coredump/coredump_manager_service.h
new file mode 100644
index 0000000000000000000000000000000000000000..509823bb6898d2594afa21a0d1c3d9fff4df426c
--- /dev/null
+++ b/services/coredump/coredump_manager_service.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef COREDUMP_MANAGER_SERVICE_H
+#define COREDUMP_MANAGER_SERVICE_H
+
+#include "coredump_facade.h"
+#include "dfx_socket_request.h"
+#include "fault_logger_service.h"
+
+namespace OHOS {
+namespace HiviewDFX {
+class CoredumpManagerService : public FaultLoggerService {
+public:
+ CoredumpManagerService(): sessionManager_(CoredumpSessionManager::Instance()) {}
+ int32_t OnRequest(const std::string& socketName, int32_t connectionFd,
+ const CoreDumpRequestData& requestData) override;
+private:
+ int32_t HandleCreate(int32_t connectionFd, const CoreDumpRequestData& requestData);
+ int32_t HandleCancel(const CoreDumpRequestData& requestData);
+ CoredumpFacade cf_;
+ CoredumpSessionManager& sessionManager_;
+};
+
+class CoredumpRequestValidator {
+public:
+ static int32_t ValidateRequest(const std::string& socketName, int32_t connectionFd,
+ const CoreDumpRequestData& requestData);
+private:
+ static bool IsValidPid(pid_t pid);
+ static bool IsAuthorizedSocket(const std::string& socketName);
+ static bool IsAuthorizedUid(int32_t connectionFd);
+ static bool CheckCoredumpUID(uint32_t callerUid);
+};
+
+class FaultCoredumpConfig {
+public:
+ static FaultCoredumpConfig& GetInstance(const std::string& jsonFilePath = "");
+
+ bool Contains(uint32_t uid) const;
+private:
+ FaultCoredumpConfig() = default;
+ FaultCoredumpConfig(const FaultCoredumpConfig&) = delete;
+ FaultCoredumpConfig& operator=(const FaultCoredumpConfig&) = delete;
+
+ bool Parse(const std::string& jsonText);
+
+ std::vector uids;
+};
+}
+}
+#endif
diff --git a/services/coredump/coredump_model.h b/services/coredump/coredump_model.h
new file mode 100644
index 0000000000000000000000000000000000000000..cb212a97b300ac150c6f37fbe0ced11eb0f827fe
--- /dev/null
+++ b/services/coredump/coredump_model.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef COREDUMP_MODEL_H
+#define COREDUMP_MODEL_H
+
+#include
+#include
+#include "dfx_log.h"
+
+namespace OHOS {
+namespace HiviewDFX {
+enum class CoredumpStatus {
+ PENDING, // 请求已接收,正在等待核心转储开始
+ RUNNING, // 核心转储进行中
+ SUCCESS, // 核心转储成功完成
+ FAILED, // 核心转储失败
+ CANCEL_PENDING, // 收到取消请求,正在等待取消执行
+ CANCELED, // 已成功取消核心转储
+ CANCEL_TIMEOUT, // 取消操作超时,核心转储未及时终止
+ INVALID_STATUS
+};
+
+enum class CoredumpEvent {
+ UPDATE_DUMPER, // Worker 上报 PID
+ CANCEL, // 客户端发起取消
+ REPORT_SUCCESS, // Worker 上报成功
+ REPORT_FAIL, // Worker 上报失败
+ TIMEOUT, // 超时未上报
+ INVALID_EVENT
+};
+
+struct CreateCoredumpRequest {
+ pid_t targetPid;
+ std::string dumpType;
+ int clientFd;
+ uint64_t endTime;
+};
+
+struct CoredumpCallbackReport {
+ pid_t workerPid;
+ CoredumpStatus status;
+ std::string filePath;
+ int errorCode;
+};
+
+using SessionId = pid_t;
+struct CoredumpSession {
+ SessionId sessionId {0};
+ pid_t workerPid {0};
+ bool cancelRequest {false};
+ CoredumpStatus status {CoredumpStatus::PENDING};
+ std::string filePath;
+ int errorCode {0};
+ int clientFd {-1};
+ uint64_t startTime {0};
+ uint64_t endTime {0};
+ int32_t timerFd {0};
+
+ std::string StatusToString(CoredumpStatus coredumpStatus) const
+ {
+ switch (coredumpStatus) {
+ case CoredumpStatus::PENDING:
+ return "PENDING";
+ case CoredumpStatus::RUNNING:
+ return "RUNNING";
+ case CoredumpStatus::SUCCESS:
+ return "SUCCESS";
+ case CoredumpStatus::FAILED:
+ return "FAILED";
+ case CoredumpStatus::CANCEL_PENDING:
+ return "CANCEL_PENDING";
+ case CoredumpStatus::CANCELED:
+ return "CANCELED";
+ case CoredumpStatus::CANCEL_TIMEOUT:
+ return "CANCEL_TIMEOUT";
+ default:
+ return "UNKNOWN";
+ }
+ }
+
+ std::string ToString() const
+ {
+ return std::string("sessionId: ") + std::to_string(sessionId) + " " + StatusToString(status);
+ }
+};
+}
+}
+#endif
diff --git a/services/coredump/coredump_session_manager.cpp b/services/coredump/coredump_session_manager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..15f9a23328edca49dc66400d17fdb2f07989c773
--- /dev/null
+++ b/services/coredump/coredump_session_manager.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "coredump_session_manager.h"
+#include "coredump_task_scheduler.h"
+#include
+
+namespace OHOS {
+namespace HiviewDFX {
+
+CoredumpSessionManager& CoredumpSessionManager::Instance()
+{
+ static CoredumpSessionManager sessionManager;
+ return sessionManager;
+}
+
+SessionId CoredumpSessionManager::CreateSession(const CreateCoredumpRequest& request)
+{
+ CoredumpSession session;
+ session.sessionId = request.targetPid;
+ session.clientFd = request.clientFd;
+ session.status = CoredumpStatus::PENDING;
+ session.endTime = request.endTime;
+
+ sessions_.emplace(session.sessionId, std::move(session));
+
+ DFXLOGI("success create session id %{public}d ", session.sessionId);
+
+ return session.sessionId;
+}
+
+CoredumpSession* CoredumpSessionManager::GetSession(SessionId sessionId)
+{
+ auto session = sessions_.find(sessionId);
+ if (session == sessions_.end()) {
+ DFXLOGW("fail to get sessin by id %{public}d", sessionId);
+ return nullptr;
+ }
+ return &session->second;
+}
+
+void CoredumpSessionManager::RemoveSession(SessionId sessionId)
+{
+ if (auto it = sessions_.find(sessionId); it != sessions_.end()) {
+ DFXLOGI("success remove session %{public}d", sessionId);
+ if (int& fd = it->second.clientFd; fd >= 0) {
+ close(fd);
+ fd = -1;
+ }
+
+ CoredumpTaskScheduler().CancelTimeout(sessionId);
+ sessions_.erase(it);
+ }
+}
+}
+}
diff --git a/services/coredump/coredump_session_manager.h b/services/coredump/coredump_session_manager.h
new file mode 100644
index 0000000000000000000000000000000000000000..195b0d5aba6353bc022fe3b30553b732907dc601
--- /dev/null
+++ b/services/coredump/coredump_session_manager.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef COREDUMP_SESSION_MANAGER_H
+#define COREDUMP_SESSION_MANAGER_H
+
+#include
+
+#include "coredump_model.h"
+
+namespace OHOS {
+namespace HiviewDFX {
+class CoredumpSessionManager {
+public:
+ static CoredumpSessionManager& Instance();
+ SessionId CreateSession(const CreateCoredumpRequest& request);
+ CoredumpSession* GetSession(SessionId sessionId);
+ void RemoveSession(SessionId sessionId);
+
+ CoredumpSessionManager(const CoredumpSessionManager&) = delete;
+ CoredumpSessionManager& operator =(const CoredumpSessionManager&) = delete;
+private:
+ CoredumpSessionManager() = default;
+ std::unordered_map sessions_;
+};
+}
+}
+#endif
diff --git a/services/coredump/coredump_session_service.cpp b/services/coredump/coredump_session_service.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2974f03e4804b40e6610cecf4e4222fa82ca210c
--- /dev/null
+++ b/services/coredump/coredump_session_service.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "coredump_session_service.h"
+#include "securec.h"
+#include "faultloggerd_socket.h"
+
+namespace OHOS {
+namespace HiviewDFX {
+SessionId CoredumpSessionService::CreateSession(const CreateCoredumpRequest& request)
+{
+ return sessionManager_.CreateSession(request);
+}
+
+bool CoredumpSessionService::CancelSession(SessionId sessionId)
+{
+ auto session = sessionManager_.GetSession(sessionId);
+ if (!session) {
+ return false;
+ }
+ session->cancelRequest = true;
+ return true;
+}
+
+bool CoredumpSessionService::UpdateWorkerPid(SessionId sessionId, pid_t workerPid)
+{
+ auto session = sessionManager_.GetSession(sessionId);
+ if (!session) {
+ return false;
+ }
+ session->workerPid = workerPid;
+ return true;
+}
+
+void CoredumpSessionService::UpdateReport(SessionId sessionId, const CoredumpCallbackReport& rpt)
+{
+ auto session = sessionManager_.GetSession(sessionId);
+ if (!session) {
+ return;
+ }
+ session->filePath = rpt.filePath;
+ session->errorCode = rpt.errorCode;
+}
+
+int CoredumpSessionService::GetClientFd(SessionId sessionId) const
+{
+ auto session = sessionManager_.GetSession(sessionId);
+ if (!session) {
+ return -1;
+ }
+ return session->clientFd;
+}
+
+bool CoredumpSessionService::WriteTimeoutAndClose(SessionId sessionId)
+{
+ CoreDumpResult coredumpRequst;
+ coredumpRequst.retCode = -1;
+ coredumpRequst.fileName[0] = '\0';
+ return WriteResult(sessionId, coredumpRequst);
+}
+
+bool CoredumpSessionService::WriteResultAndClose(SessionId sessionId)
+{
+ DFXLOGI("%{public}s sessionId %{public}d ", __func__, sessionId);
+
+ auto session = sessionManager_.GetSession(sessionId);
+ if (!session) {
+ return false;
+ }
+
+ CoreDumpResult coredumpResult;
+ if (strncpy_s(coredumpResult.fileName, sizeof(coredumpResult.fileName),
+ session->filePath.c_str(), session->filePath.size()) != 0) {
+ DFXLOGE("%{public}s :: strncpy failed.", __func__);
+ return false;
+ }
+ coredumpResult.retCode = session->errorCode;
+
+ return WriteResult(sessionId, coredumpResult);
+}
+
+bool CoredumpSessionService::WriteResult(SessionId sessionId, const CoreDumpResult& coredumpResult)
+{
+ auto session = sessionManager_.GetSession(sessionId);
+ if (!session) {
+ return false;
+ }
+
+ int32_t savedConnectionFd = session->clientFd;
+ SendMsgToSocket(savedConnectionFd, &coredumpResult, sizeof(coredumpResult));
+ sessionManager_.RemoveSession(sessionId);
+ return true;
+}
+}
+}
diff --git a/services/coredump/coredump_session_service.h b/services/coredump/coredump_session_service.h
new file mode 100644
index 0000000000000000000000000000000000000000..fb862a3fd8abd375ab9935b2036be881f50809db
--- /dev/null
+++ b/services/coredump/coredump_session_service.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef COREDUMP_SESSION_SERVICE_H
+#define COREDUMP_SESSION_SERVICE_H
+
+#include "coredump_model.h"
+#include "coredump_session_manager.h"
+#include "dfx_socket_request.h"
+
+namespace OHOS {
+namespace HiviewDFX {
+class CoredumpSessionService {
+public:
+ CoredumpSessionService():sessionManager_(CoredumpSessionManager::Instance()) {}
+
+ SessionId CreateSession(const CreateCoredumpRequest& req);
+ bool CancelSession(SessionId sessionId);
+ bool UpdateWorkerPid(SessionId sessionId, pid_t workerPid);
+ void UpdateReport(SessionId sessionId, const CoredumpCallbackReport& rpt);
+
+ int GetClientFd(SessionId sessionId) const;
+
+ bool WriteTimeoutAndClose(SessionId sessionId);
+ bool WriteResultAndClose(SessionId sessionId);
+private:
+ bool WriteResult(SessionId sessionId, const CoreDumpResult& result);
+ CoredumpSessionManager& sessionManager_;
+};
+}
+}
+#endif
diff --git a/services/coredump/coredump_session_state.cpp b/services/coredump/coredump_session_state.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..97a67e36c1d5a4cec95b66da3e6f653ad98a3a32
--- /dev/null
+++ b/services/coredump/coredump_session_state.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "coredump_session_state.h"
+
+#include "dfx_log.h"
+
+namespace OHOS {
+namespace HiviewDFX {
+
+std::unique_ptr SessionStateContext::CreateState(CoredumpStatus status)
+{
+ switch (status) {
+ case CoredumpStatus::PENDING:
+ return std::make_unique();
+ case CoredumpStatus::RUNNING:
+ return std::make_unique();
+ case CoredumpStatus::CANCEL_PENDING:
+ return std::make_unique();
+ default:
+ return nullptr;
+ }
+}
+
+void SessionStateContext::HandleEvent(CoredumpSession& session, CoredumpEvent event)
+{
+ auto stateHandler = CreateState(session.status);
+ if (!stateHandler) {
+ return;
+ }
+ stateHandler->OnEvent(event, session);
+}
+
+void PendingState::OnEvent(CoredumpEvent event, CoredumpSession& session)
+{
+ switch (event) {
+ case CoredumpEvent::UPDATE_DUMPER:
+ session.status = CoredumpStatus::RUNNING;
+ break;
+ case CoredumpEvent::CANCEL:
+ session.cancelRequest = true;
+ session.status = CoredumpStatus::CANCEL_PENDING;
+ break;
+ case CoredumpEvent::TIMEOUT:
+ sessionService_.WriteTimeoutAndClose(session.sessionId);
+ session.status = CoredumpStatus::CANCEL_TIMEOUT;
+ break;
+ default:
+ DFXLOGW("pending state recevie invalid event");
+ break;
+ }
+}
+
+void RunningState::OnEvent(CoredumpEvent event, CoredumpSession& session)
+{
+ switch (event) {
+ case CoredumpEvent::REPORT_SUCCESS:
+ sessionService_.WriteResultAndClose(session.sessionId);
+ session.status = CoredumpStatus::SUCCESS;
+ break;
+ case CoredumpEvent::REPORT_FAIL:
+ sessionService_.WriteResultAndClose(session.sessionId);
+ session.status = CoredumpStatus::FAILED;
+ break;
+ case CoredumpEvent::CANCEL:
+ signalService_.SendCancelSignal(session.workerPid);
+ sessionService_.WriteResultAndClose(session.sessionId);
+ session.status = CoredumpStatus::CANCELED;
+ break;
+ default:
+ DFXLOGI("running state receive invalid event");
+ break;
+ }
+}
+
+void CancelPendingState::OnEvent(CoredumpEvent event, CoredumpSession& session)
+{
+ switch (event) {
+ case CoredumpEvent::UPDATE_DUMPER:
+ signalService_.SendCancelSignal(session.workerPid);
+ sessionService_.WriteResultAndClose(session.sessionId);
+ session.status = CoredumpStatus::CANCELED;
+ break;
+ case CoredumpEvent::TIMEOUT:
+ sessionService_.WriteTimeoutAndClose(session.sessionId);
+ session.status = CoredumpStatus::CANCEL_TIMEOUT;
+ break;
+ default:
+ DFXLOGI("cancel pending receive invalid event");
+ break;
+ }
+}
+}
+}
\ No newline at end of file
diff --git a/services/coredump/coredump_session_state.h b/services/coredump/coredump_session_state.h
new file mode 100644
index 0000000000000000000000000000000000000000..5497a9aa773084e48d708d6f273b3478d00dfd17
--- /dev/null
+++ b/services/coredump/coredump_session_state.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef COREDUMP_SESSION_STATE_H
+#define COREDUMP_SESSION_STATE_H
+
+#include "coredump_task_scheduler.h"
+#include "coredump_signal_service.h"
+#include "coredump_session_service.h"
+
+namespace OHOS {
+namespace HiviewDFX {
+
+class SessionState;
+
+class SessionStateContext {
+public:
+ void HandleEvent(CoredumpSession& session, CoredumpEvent event);
+ static std::unique_ptr CreateState(CoredumpStatus status);
+};
+
+class SessionState {
+public:
+ virtual ~SessionState() = default;
+ virtual void OnEvent(CoredumpEvent event, CoredumpSession& session) = 0;
+};
+
+class PendingState : public SessionState {
+public:
+ void OnEvent(CoredumpEvent event, CoredumpSession& session) override;
+private:
+ CoredumpSessionService sessionService_;
+};
+
+class RunningState : public SessionState {
+public:
+ void OnEvent(CoredumpEvent event, CoredumpSession& session) override;
+private:
+ CoredumpSessionService sessionService_;
+ CoredumpSignalService signalService_;
+};
+
+class CancelPendingState : public SessionState {
+public:
+ void OnEvent(CoredumpEvent event, CoredumpSession& session) override;
+private:
+ CoredumpSessionService sessionService_;
+ CoredumpSignalService signalService_;
+};
+}
+}
+#endif
diff --git a/services/coredump/coredump_signal_service.cpp b/services/coredump/coredump_signal_service.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..534a9cb17d8adcbbe0c68834ab28d64658015edf
--- /dev/null
+++ b/services/coredump/coredump_signal_service.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "coredump_signal_service.h"
+
+#include
+
+#include "dfx_log.h"
+#include "dfx_define.h"
+#include "dfx_socket_request.h"
+#include "faultloggerd_socket.h"
+#include "proc_util.h"
+#include "procinfo.h"
+#include "fault_common_util.h"
+
+namespace OHOS {
+namespace HiviewDFX {
+
+int32_t CoredumpSignalService::SendStartSignal(pid_t targetPid)
+{
+ siginfo_t si{0};
+ si.si_signo = SIGLEAK_STACK;
+ si.si_errno = 0;
+ si.si_code = SIGLEAK_STACK_COREDUMP;
+ if (auto ret = FaultCommonUtil::SendSignalToProcess(targetPid, si); ret != ResponseCode::REQUEST_SUCCESS) {
+ return ret;
+ }
+ return ResponseCode::REQUEST_SUCCESS;
+}
+
+int32_t CoredumpSignalService::SendCancelSignal(pid_t workerPid)
+{
+ siginfo_t si{0};
+ si.si_signo = SIGTERM;
+ si.si_errno = 0;
+ si.si_code = SIGLEAK_STACK_COREDUMP;
+#ifndef FAULTLOGGERD_TEST
+ if (syscall(SYS_rt_sigqueueinfo, workerPid, si.si_signo, &si) != 0) {
+ DFXLOGE("Failed to SYS_rt_sigqueueinfo signal(%{public}d), errno(%{public}d).",
+ si.si_signo, errno);
+ return ResponseCode::CORE_DUMP_NOPROC;
+ }
+#endif
+ return ResponseCode::REQUEST_SUCCESS;
+}
+}
+}
diff --git a/services/coredump/coredump_signal_service.h b/services/coredump/coredump_signal_service.h
new file mode 100644
index 0000000000000000000000000000000000000000..fa71171b6d0f5a4ea2437e2010cf9fb3b412cb8b
--- /dev/null
+++ b/services/coredump/coredump_signal_service.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef COREDUMP_SIGNAL_SERVICE_H
+#define COREDUMP_SIGNAL_SERVICE_H
+
+#include
+
+namespace OHOS {
+namespace HiviewDFX {
+class CoredumpSignalService {
+public:
+ int32_t SendStartSignal(pid_t targetPid);
+ int32_t SendCancelSignal(pid_t workerPid);
+};
+}
+}
+#endif
diff --git a/services/coredump/coredump_task_scheduler.cpp b/services/coredump/coredump_task_scheduler.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..87f38795dfaa885ca6c985e1f45c8b344886cf06
--- /dev/null
+++ b/services/coredump/coredump_task_scheduler.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "coredump_task_scheduler.h"
+#include "coredump_session_manager.h"
+#include "dfx_util.h"
+#include "epoll_manager.h"
+#include "fault_logger_daemon.h"
+
+namespace OHOS {
+namespace HiviewDFX {
+
+void CoredumpTaskScheduler::ScheduleCancelTime(SessionId sessionId, int timeoutMs)
+{
+ auto session = sessionManager_.GetSession(sessionId);
+ if (!session) {
+ return;
+ }
+
+ auto endTime = session->endTime;
+ auto removeTask = [session]() {
+ CoredumpSessionManager::Instance().RemoveSession(session->sessionId);
+ DFXLOGI("timer real remove %{public}d", session->sessionId);
+ };
+
+ constexpr int32_t maxDelaySec = 60; // 60 : 60s
+ auto curTime = GetAbsTimeMilliSeconds();
+ int32_t delaySec = endTime > curTime ? static_cast((endTime - curTime) / 1000) : 0;
+ delaySec = std::min(delaySec, maxDelaySec);
+
+ auto delayTask = DelayTask::CreateInstance(removeTask, delaySec);
+ if (delayTask) {
+ session->timerFd = delayTask->GetFd();
+ FaultLoggerDaemon::GetEpollManager(EpollManagerType::MAIN_SERVER).AddListener(std::move(delayTask));
+ }
+}
+
+void CoredumpTaskScheduler::CancelTimeout(SessionId sessionId)
+{
+ auto session = sessionManager_.GetSession(sessionId);
+ if (!session) {
+ return;
+ }
+
+ FaultLoggerDaemon::GetEpollManager(EpollManagerType::MAIN_SERVER).RemoveListener(session->timerFd);
+}
+}
+}
diff --git a/services/coredump/coredump_task_scheduler.h b/services/coredump/coredump_task_scheduler.h
new file mode 100644
index 0000000000000000000000000000000000000000..1fc3c3e05d250ada660aac73371f29870926374a
--- /dev/null
+++ b/services/coredump/coredump_task_scheduler.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef COREDUMP_TASK_SCHEDULER_H
+#define COREDUMP_TASK_SCHEDULER_H
+
+#include "coredump_model.h"
+#include "coredump_session_manager.h"
+
+namespace OHOS {
+namespace HiviewDFX {
+class CoredumpTaskScheduler {
+public:
+ CoredumpTaskScheduler() : sessionManager_(CoredumpSessionManager::Instance()) {}
+ void ScheduleCancelTime(SessionId sessionId, int timeoutMs);
+ void CancelTimeout(SessionId sessionId);
+private:
+ CoredumpSessionManager& sessionManager_;
+};
+}
+}
+#endif
diff --git a/services/fault_common_util.cpp b/services/fault_common_util.cpp
index e574434a3c0968fa0798fcf00fd771c10050404f..1d483d0d44b231981b87f2bc1f0716db9c9e965c 100644
--- a/services/fault_common_util.cpp
+++ b/services/fault_common_util.cpp
@@ -63,8 +63,8 @@ int32_t SendSignalToHapWatchdogThread(pid_t pid, const siginfo_t& si)
}
#ifndef FAULTLOGGERD_TEST
if (syscall(SYS_rt_tgsigqueueinfo, pid, tid, si.si_signo, &si) != 0) {
- DFXLOGE("%{public}s :: Failed to SYS_rt_tgsigqueueinfo signal(%{public}d), errno(%{public}d).",
- FAULTLOGGERD_SERVICE_TAG, si.si_signo, errno);
+ DFXLOGE("Failed to SYS_rt_tgsigqueueinfo signal(%{public}d), errno(%{public}d).",
+ si.si_signo, errno);
return ResponseCode::SDK_DUMP_NOPROC;
}
#endif
@@ -79,8 +79,8 @@ int32_t SendSignalToProcess(pid_t pid, const siginfo_t& si)
}
#ifndef FAULTLOGGERD_TEST
if (syscall(SYS_rt_sigqueueinfo, pid, si.si_signo, &si) != 0) {
- DFXLOGE("%{public}s :: Failed to SYS_rt_sigqueueinfo signal(%{public}d), errno(%{public}d).",
- FAULTLOGGERD_SERVICE_TAG, si.si_signo, errno);
+ DFXLOGE("Failed to SYS_rt_sigqueueinfo signal(%{public}d), errno(%{public}d).",
+ si.si_signo, errno);
return ResponseCode::SDK_DUMP_NOPROC;
}
#endif
@@ -88,4 +88,4 @@ int32_t SendSignalToProcess(pid_t pid, const siginfo_t& si)
}
}
}
-}
\ No newline at end of file
+}
diff --git a/services/fault_common_util.h b/services/fault_common_util.h
index bb1159b5a53f494e7138c1096ca761bb57c82963..33249f1f9288d69e4084f4c78e9c0eca2e5a838f 100644
--- a/services/fault_common_util.h
+++ b/services/fault_common_util.h
@@ -23,12 +23,10 @@
namespace OHOS {
namespace HiviewDFX {
namespace FaultCommonUtil {
+bool GetUcredByPeerCred(struct ucred& rcred, int32_t connectionFd);
int32_t SendSignalToHapWatchdogThread(pid_t pid, const siginfo_t& si);
int32_t SendSignalToProcess(pid_t pid, const siginfo_t& si);
-
-bool GetUcredByPeerCred(struct ucred& rcred, int32_t connectionFd);
}
}
}
-
-#endif
\ No newline at end of file
+#endif
diff --git a/services/fault_coredump_service.cpp b/services/fault_coredump_service.cpp
deleted file mode 100644
index 9e03dd84065496c2e1229b5c47e6e07972518c77..0000000000000000000000000000000000000000
--- a/services/fault_coredump_service.cpp
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Copyright (c) 2025 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "fault_coredump_service.h"
-
-#include
-#include
-#include
-#include
-#include "dfx_define.h"
-#include "dfx_log.h"
-#include "dfx_trace.h"
-#include "dfx_util.h"
-#include "fault_logger_daemon.h"
-#include "faultloggerd_socket.h"
-#include "fault_common_util.h"
-#include "procinfo.h"
-#include "proc_util.h"
-#include "string_printf.h"
-
-namespace OHOS {
-namespace HiviewDFX {
-
-namespace {
-constexpr const char* const FAULTLOGGERD_SERVICE_TAG = "FAULT_COREDUMP_SERVICE";
-bool CheckCoredumpUID(uint32_t callerUid)
-{
- const uint32_t whitelist[] = {
- 0, // rootUid
- 1202, // dumpcatcherUid
- 7005, // taskManagerUid
- };
- if (std::find(std::begin(whitelist), std::end(whitelist), callerUid) == std::end(whitelist)) {
- DFXLOGW("%{public}s :: CheckCoredumpUID :: Coredump Uid(%{public}d) is unexpectly.",
- FAULTLOGGERD_SERVICE_TAG, callerUid);
- return false;
- }
- return true;
-}
-
-int32_t SendCancelSignal(int32_t processDumpPid)
-{
- siginfo_t si{0};
- si.si_signo = SIGTERM;
- si.si_errno = 0;
- si.si_code = SIGLEAK_STACK_COREDUMP;
-#ifndef FAULTLOGGERD_TEST
- if (syscall(SYS_rt_sigqueueinfo, processDumpPid, si.si_signo, &si) != 0) {
- DFXLOGE("%{public}s :: Failed to SYS_rt_sigqueueinfo signal(%{public}d), errno(%{public}d).",
- FAULTLOGGERD_SERVICE_TAG, si.si_signo, errno);
- return ResponseCode::CORE_DUMP_NOPROC;
- }
-#endif
- return ResponseCode::REQUEST_SUCCESS;
-}
-
-bool SendMsgToCoredumpClient(int32_t targetPid, int32_t responseCode, const std::string& fileName,
- RecorderProcessMap& coredumpRecorder)
-{
- int32_t savedConnectionFd = -1;
-
- coredumpRecorder.GetCoredumpSocketId(targetPid, savedConnectionFd);
- if (savedConnectionFd < 0) {
- DFXLOGE("%{public}s :: Client sockFd has been crashed.", __func__);
- return false;
- }
-
- CoreDumpResult coredumpResult;
- if (strncpy_s(coredumpResult.fileName, sizeof(coredumpResult.fileName),
- fileName.c_str(), fileName.size()) != 0) {
- DFXLOGE("%{public}s :: strncpy failed.", __func__);
- return false;
- }
- coredumpResult.retCode = responseCode;
-
- if (SendMsgToSocket(savedConnectionFd, &coredumpResult, sizeof(coredumpResult))) {
- return true;
- }
- return false;
-}
-
-bool HandleCoredumpAndCleanup(int32_t targetPid, int32_t retCode, const std::string& fileName,
- RecorderProcessMap& coredumpRecorder)
-{
- if (!SendMsgToCoredumpClient(targetPid, retCode, fileName, coredumpRecorder)) {
- DFXLOGE("Send message to client failed, %{public}s %{public}d", __func__, __LINE__);
- }
-
- if (!coredumpRecorder.ClearTargetPid(targetPid)) {
- DFXLOGE("Remove targetpid %{public}d failed, %{public}s %{public}d", targetPid, __func__, __LINE__);
- return false;
- }
- return true;
-}
-}
-
-RecorderProcessMap& RecorderProcessMap::GetInstance()
-{
- static RecorderProcessMap instance;
- return instance;
-}
-
-bool RecorderProcessMap::IsEmpty()
-{
- return coredumpProcessMap.empty();
-}
-
-bool RecorderProcessMap::HasTargetPid(int32_t targetPid)
-{
- return coredumpProcessMap.find(targetPid) != coredumpProcessMap.end();
-}
-
-void RecorderProcessMap::AddProcessMap(int32_t targetPid, const CoredumpProcessInfo& processInfo)
-{
- coredumpProcessMap.emplace(
- targetPid,
- CoredumpProcessInfo(processInfo.processDumpPid, processInfo.coredumpSocketId,
- processInfo.endTime, processInfo.cancelFlag)
- );
-}
-
-bool RecorderProcessMap::ClearTargetPid(int32_t targetPid)
-{
- auto it = coredumpProcessMap.find(targetPid);
- if (it != coredumpProcessMap.end()) {
- close(it->second.coredumpSocketId);
- coredumpProcessMap.erase(it);
- return true;
- }
- return false;
-}
-
-bool RecorderProcessMap::SetCancelFlag(int32_t targetPid, bool flag)
-{
- auto it = coredumpProcessMap.find(targetPid);
- if (it != coredumpProcessMap.end()) {
- it->second.cancelFlag = flag;
- return true;
- }
- return false;
-}
-
-bool RecorderProcessMap::SetProcessDumpPid(int32_t targetPid, int32_t processDumpPid)
-{
- auto it = coredumpProcessMap.find(targetPid);
- if (it != coredumpProcessMap.end()) {
- it->second.processDumpPid = processDumpPid;
- return true;
- }
- return false;
-}
-
-bool RecorderProcessMap::GetCoredumpSocketId(int32_t targetPid, int32_t& coredumpSocketId)
-{
- auto it = coredumpProcessMap.find(targetPid);
- if (it != coredumpProcessMap.end()) {
- coredumpSocketId = it->second.coredumpSocketId;
- return true;
- }
- return false;
-}
-
-bool RecorderProcessMap::GetProcessDumpPid(int32_t targetPid, int32_t& processDumpPid)
-{
- auto it = coredumpProcessMap.find(targetPid);
- if (it != coredumpProcessMap.end()) {
- processDumpPid = it->second.processDumpPid;
- return true;
- }
- return false;
-}
-
-bool RecorderProcessMap::GetCancelFlag(int32_t targetPid, bool& flag)
-{
- auto it = coredumpProcessMap.find(targetPid);
- if (it != coredumpProcessMap.end()) {
- flag = it->second.cancelFlag;
- return true;
- }
- return false;
-}
-
-#ifndef is_ohos_lite
-bool CoredumpStatusService::HandleProcessDumpPid(int32_t targetPid, int32_t processDumpPid)
-{
- if (processDumpPid <= 0 || targetPid <= 0) {
- return false;
- }
-
- if (!coredumpRecorder.HasTargetPid(targetPid)) {
- return false;
- }
-
- bool cancelFlag = false;
- if (coredumpRecorder.GetCancelFlag(targetPid, cancelFlag)) {
- if (!cancelFlag) {
- coredumpRecorder.SetProcessDumpPid(targetPid, processDumpPid);
- return true;
- }
- }
-
- if (SendCancelSignal(processDumpPid) != ResponseCode::REQUEST_SUCCESS) {
- return false;
- }
-
- int32_t retCode = ResponseCode::CORE_DUMP_CANCEL;
- std::string fileName = "";
- HandleCoredumpAndCleanup(targetPid, retCode, fileName, coredumpRecorder);
- return true;
-}
-
-int32_t CoredumpStatusService::OnRequest(const std::string& socketName, int32_t connectionFd,
- const CoreDumpStatusData& requestData)
-{
- DFX_TRACE_SCOPED("CoredumpStatusServiceOnRequest");
- DFXLOGI("Receive coredump status request for pid:%{public}d, status:%{public}d", requestData.pid,
- requestData.coredumpStatus);
-
- int32_t res = ResponseCode::REQUEST_SUCCESS;
- if (requestData.coredumpStatus == CoreDumpStatus::CORE_DUMP_START) {
- DFXLOGI("Processdump start %{public}s %{public}d", __func__, __LINE__);
- int32_t processDumpPid = requestData.processDumpPid;
-
- if (!HandleProcessDumpPid(requestData.pid, processDumpPid)) {
- DFXLOGE("Handle processDumpPid %{public}d failed", processDumpPid);
- res = ResponseCode::ABNORMAL_SERVICE;
- return res;
- }
- } else if (requestData.coredumpStatus == CoreDumpStatus::CORE_DUMP_END) {
- DFXLOGI("Processdump finish %{public}s %{public}d", __func__, __LINE__);
-
- int32_t targetPid = requestData.pid;
- char cfileName[256];
- if (strncpy_s(cfileName, sizeof(cfileName), requestData.fileName, sizeof(requestData.fileName)) != 0) {
- DFXLOGE("%{public}s :: strncpy failed.", __func__);
- return ResponseCode::DEFAULT_ERROR_CODE;
- }
- int32_t retCode = requestData.retCode;
- HandleCoredumpAndCleanup(targetPid, retCode, cfileName, coredumpRecorder);
- }
-
- SendMsgToSocket(connectionFd, &res, sizeof(res));
- return res;
-}
-
-int32_t CoredumpService::Filter(const std::string& socketName, const CoreDumpRequestData& requestData, uint32_t uid)
-{
- if (requestData.pid <= 0 || socketName != SERVER_SOCKET_NAME || !CheckCoredumpUID(uid)) {
- DFXLOGE("%{public}s :: HandleCoreDumpRequest :: pid(%{public}d) or socketName(%{public}s) fail.",
- FAULTLOGGERD_SERVICE_TAG, requestData.pid, socketName.c_str());
- return ResponseCode::REQUEST_REJECT;
- }
- if (TempFileManager::CheckCrashFileRecord(requestData.pid)) {
- DFXLOGW("%{public}s :: pid(%{public}d) has been crashed, break.",
- FAULTLOGGERD_SERVICE_TAG, requestData.pid);
- return ResponseCode::CORE_PROCESS_CRASHED;
- }
- return ResponseCode::REQUEST_SUCCESS;
-}
-
-int32_t CoredumpService::DoCoredumpRequest(const std::string& socketName, int32_t connectionFd,
- const CoreDumpRequestData& requestData)
-{
- struct ucred creds;
- if (!FaultCommonUtil::GetUcredByPeerCred(creds, connectionFd)) {
- DFXLOGE("Core dump pid(%{public}d) request failed to get cred.", requestData.pid);
- return ResponseCode::REQUEST_REJECT;
- }
- int32_t responseCode = Filter(socketName, requestData, creds.uid);
- if (responseCode != ResponseCode::REQUEST_SUCCESS) {
- return responseCode;
- }
-
- int32_t res = ResponseCode::REQUEST_SUCCESS;
- int32_t coredumpSocketId = dup(connectionFd);
- int32_t targetPid = requestData.pid;
- if (coredumpRecorder.HasTargetPid(targetPid)) {
- DFXLOGE("%{public}d is generating coredump, please do not repeat dump!", targetPid);
- res = ResponseCode::CORE_DUMP_REPEAT;
- SendMsgToSocket(coredumpSocketId, &res, sizeof(res));
- close(coredumpSocketId);
- return res;
- }
-
- siginfo_t si{0};
- si.si_signo = SIGLEAK_STACK;
- si.si_errno = 0;
- si.si_code = SIGLEAK_STACK_COREDUMP;
- si.si_pid = static_cast(creds.pid);
- if (auto ret = FaultCommonUtil::SendSignalToProcess(targetPid, si); ret != ResponseCode::REQUEST_SUCCESS) {
- SendMsgToSocket(coredumpSocketId, &ret, sizeof(ret));
- close(coredumpSocketId);
- return ret;
- }
-
- int32_t processDumpPid = -1;
- uint64_t endTime = requestData.endTime;
- coredumpRecorder.AddProcessMap(targetPid, {processDumpPid, coredumpSocketId, endTime, false});
- SendMsgToSocket(coredumpSocketId, &res, sizeof(res));
-
- auto removeTask = [targetPid, coredumpRecorderPtr = &coredumpRecorder]() {
- coredumpRecorderPtr->ClearTargetPid(targetPid);
- };
-
- constexpr int32_t minDelays = 60; // 60 : 60s
- int32_t delays = static_cast((endTime - GetAbsTimeMilliSeconds()) / 1000);
- delays = std::min(delays, minDelays);
- StartDelayTask(removeTask, delays);
- return res;
-}
-
-int32_t CoredumpService::CancelCoredumpRequest(int32_t connectionFd, const CoreDumpRequestData& requestData)
-{
- int32_t targetPid = requestData.pid;
- int32_t res = ResponseCode::REQUEST_SUCCESS;
- if (!coredumpRecorder.HasTargetPid(targetPid)) {
- DFXLOGE("No need to cancel!");
- res = ResponseCode::DEFAULT_ERROR_CODE;
- SendMsgToSocket(connectionFd, &res, sizeof(res));
- return res;
- }
-
- int32_t processDumpPid = -1;
- if (coredumpRecorder.GetProcessDumpPid(targetPid, processDumpPid)) {
- if (processDumpPid == -1) {
- DFXLOGE("Can not get processdump pid!");
- coredumpRecorder.SetCancelFlag(targetPid, true);
- } else {
- DFXLOGI("processDumpPid get %{public}d %{public}d", processDumpPid, __LINE__);
-
- res = SendCancelSignal(processDumpPid);
- if (res != ResponseCode::REQUEST_SUCCESS) {
- return res;
- }
- int32_t retCode = ResponseCode::CORE_DUMP_CANCEL;
- std::string fileName = "";
- HandleCoredumpAndCleanup(targetPid, retCode, fileName, coredumpRecorder);
- }
- }
-
- SendMsgToSocket(connectionFd, &res, sizeof(res));
- return res;
-}
-
-int32_t CoredumpService::OnRequest(const std::string& socketName, int32_t connectionFd,
- const CoreDumpRequestData& requestData)
-{
- DFX_TRACE_SCOPED("CoredumpServiceOnRequest");
- DFXLOGI("Receive coredump request for pid:%{public}d, action:%{public}d.", requestData.pid,
- requestData.coredumpAction);
-
- int32_t res = ResponseCode::REQUEST_SUCCESS;
- if (requestData.coredumpAction == CoreDumpAction::DO_CORE_DUMP) {
- DFXLOGI("Do coredump %{public}s %{public}d", __func__, __LINE__);
- res = DoCoredumpRequest(socketName, connectionFd, requestData);
- } else if (requestData.coredumpAction == CoreDumpAction::CANCEL_CORE_DUMP) {
- DFXLOGI("Cancel coredump %{public}s %{public}d", __func__, __LINE__);
- res = CancelCoredumpRequest(connectionFd, requestData);
- }
- return res;
-}
-
-void CoredumpService::StartDelayTask(std::function workFunc, int32_t delayTime)
-{
- auto delayTask = DelayTask::CreateInstance(workFunc, delayTime);
- FaultLoggerDaemon::GetEpollManager(EpollManagerType::MAIN_SERVER).AddListener(std::move(delayTask));
-}
-#endif
-}
-}
\ No newline at end of file
diff --git a/services/fault_coredump_service.h b/services/fault_coredump_service.h
deleted file mode 100644
index 51180318d16e7ded607d1a63f370379aafb49e3a..0000000000000000000000000000000000000000
--- a/services/fault_coredump_service.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2025 Huawei Device Co., Ltd.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef FAULT_COREDUMP_SERVICE_H
-#define FAULT_COREDUMP_SERVICE_H
-
-#include "csignal"
-#include "cstdint"
-#include "fault_logger_service.h"
-
-namespace OHOS {
-namespace HiviewDFX {
-struct CoredumpProcessInfo {
- int32_t processDumpPid;
- int32_t coredumpSocketId;
- int endTime;
- bool cancelFlag;
-
- CoredumpProcessInfo(int32_t processDump, int32_t connectionFd, int time, bool flag)
- : processDumpPid(processDump), coredumpSocketId(connectionFd), endTime(time), cancelFlag(flag) {}
-};
-
-class RecorderProcessMap {
-public:
- RecorderProcessMap(const RecorderProcessMap&) = delete;
- RecorderProcessMap& operator=(const RecorderProcessMap&) = delete;
-
- bool IsEmpty();
- bool HasTargetPid(int32_t targetPid);
- void AddProcessMap(int32_t targetPid, const CoredumpProcessInfo& processInfo);
- bool ClearTargetPid(int32_t targetPid);
- bool GetCoredumpSocketId(int32_t targetPid, int32_t& coredumpSocketId);
- bool GetCancelFlag(int32_t targetPid, bool& flag);
- bool GetProcessDumpPid(int32_t targetPid, int32_t& processDumpPid);
- bool SetCancelFlag(int32_t targetPid, bool flag);
- bool SetProcessDumpPid(int32_t targetPid, int32_t processDumpPid);
- static RecorderProcessMap& GetInstance();
-
-private:
- RecorderProcessMap() = default;
- std::unordered_map coredumpProcessMap;
-};
-
-#ifndef is_ohos_lite
-class CoredumpService : public FaultLoggerService {
-public:
- CoredumpService() : coredumpRecorder(RecorderProcessMap::GetInstance()) {}
- int32_t OnRequest(const std::string& socketName, int32_t connectionFd,
- const CoreDumpRequestData& requestData) override;
-
-private:
- static int32_t Filter(const std::string& socketName, const CoreDumpRequestData& requestData, uint32_t uid);
- void StartDelayTask(std::function workFunc, int32_t delayTime);
- int32_t DoCoredumpRequest(const std::string& socketName, int32_t connectionFd,
- const CoreDumpRequestData& requestData);
- int32_t CancelCoredumpRequest(int32_t connectionFd, const CoreDumpRequestData& requestData);
- RecorderProcessMap& coredumpRecorder;
-};
-
-
-class CoredumpStatusService : public FaultLoggerService {
-public:
- CoredumpStatusService() : coredumpRecorder(RecorderProcessMap::GetInstance()) {}
- int32_t OnRequest(const std::string& socketName, int32_t connectionFd,
- const CoreDumpStatusData& requestData) override;
-
-private:
- bool HandleProcessDumpPid(int32_t targetPid, int32_t processDumpPid);
- RecorderProcessMap& coredumpRecorder;
-};
-#endif
-}
-}
-
-#endif
\ No newline at end of file
diff --git a/services/fault_logger_server.cpp b/services/fault_logger_server.cpp
index 618dfe81267502587a0b5d20876ddbdc443e6abf..7f60123108bce92e3bf8ea0b37af7ed873d4b11f 100644
--- a/services/fault_logger_server.cpp
+++ b/services/fault_logger_server.cpp
@@ -22,7 +22,10 @@
#include "dfx_define.h"
#include "dfx_log.h"
#include "faultloggerd_socket.h"
-#include "fault_coredump_service.h"
+#ifndef is_ohos_lite
+#include "coredump_callback_service.h"
+#include "coredump_manager_service.h"
+#endif
namespace OHOS {
namespace HiviewDFX {
@@ -47,8 +50,8 @@ bool SocketServer::Init()
return false;
}
#ifndef is_ohos_lite
- AddService(COREDUMP_CLIENT, std::make_unique());
- AddService(COREDUMP_PROCESS_DUMP_CLIENT, std::make_unique());
+ AddService(COREDUMP_CLIENT, std::make_unique());
+ AddService(COREDUMP_PROCESS_DUMP_CLIENT, std::make_unique());
AddService(PIPE_FD_CLIENT, std::make_unique());
AddService(SDK_DUMP_CLIENT, std::make_unique());
diff --git a/services/fault_logger_service.cpp b/services/fault_logger_service.cpp
index 5f853165b0cd310889b0217ba39c1a14ac8960e6..1384a0af883a990f9af3204638c6f84a0c0e6f3e 100644
--- a/services/fault_logger_service.cpp
+++ b/services/fault_logger_service.cpp
@@ -332,7 +332,8 @@ int32_t SdkDumpService::OnRequest(const std::string& socketName, int32_t connect
*/
auto& faultLoggerPipe = FaultLoggerPipePair::CreateSdkDumpPipePair(requestData.pid, requestData.time);
- if (auto ret = FaultCommonUtil::SendSignalToProcess(requestData.pid, si); ret != ResponseCode::REQUEST_SUCCESS) {
+ if (auto ret = FaultCommonUtil::SendSignalToProcess(requestData.pid, si);
+ ret != ResponseCode::REQUEST_SUCCESS) {
FaultLoggerPipePair::DelSdkDumpPipePair(requestData.pid);
return ret;
}
diff --git a/services/snapshot/i_kernel_snapshot_reporter.h b/services/snapshot/i_kernel_snapshot_reporter.h
index 78efcca29238435f3d27e039685230a6cfa6f2e1..ab414283a61a1c5ebb8821495aada4f5f269f474 100644
--- a/services/snapshot/i_kernel_snapshot_reporter.h
+++ b/services/snapshot/i_kernel_snapshot_reporter.h
@@ -22,7 +22,7 @@ namespace OHOS {
namespace HiviewDFX {
class IKernelSnapshotReporter {
public:
- virtual void ReportEvents(std::vector& outputs) = 0;
+ virtual void ReportEvents(std::vector& outputs, const std::string& snapshot) = 0;
virtual ~IKernelSnapshotReporter() = default;
};
} // namespace HiviewDFX
diff --git a/services/snapshot/kernel_snapshot_manager.cpp b/services/snapshot/kernel_snapshot_manager.cpp
index 6b09d3ca39aa89129ab7408b5a4ff61e15e9ad5d..70828cc0fb4ff131f2b8b83bc9a5c75ffc68c39c 100644
--- a/services/snapshot/kernel_snapshot_manager.cpp
+++ b/services/snapshot/kernel_snapshot_manager.cpp
@@ -89,6 +89,9 @@ void KernelSnapshotManager::MonitorCrashKernelSnapshot()
break;
}
std::string snapshotCont = ReadKernelSnapshot();
+ if (snapshotCont.empty()) {
+ continue;
+ }
processor->Process(snapshotCont);
}
}
diff --git a/services/snapshot/kernel_snapshot_processor_impl.cpp b/services/snapshot/kernel_snapshot_processor_impl.cpp
index e8b973c7b68038a5674b04e95d2c8324dd4f4bf3..c11de435050b72b6d50ae05a02d39398d6d91db5 100644
--- a/services/snapshot/kernel_snapshot_processor_impl.cpp
+++ b/services/snapshot/kernel_snapshot_processor_impl.cpp
@@ -37,7 +37,7 @@ void KernelSnapshotProcessorImpl::Process(const std::string& snapshot)
DFXLOGE("reporter is null");
return;
}
- reporter_->ReportEvents(crashMaps);
+ reporter_->ReportEvents(crashMaps, snapshot);
}
} // namespace HiviewDFX
} // namespace OHOS
diff --git a/services/snapshot/kernel_snapshot_reporter.cpp b/services/snapshot/kernel_snapshot_reporter.cpp
index c66195884aae2bd9e46209594e1ecd7215b5d57e..b16be5474001e25b18f7b1d33a5ca6177b7e110b 100644
--- a/services/snapshot/kernel_snapshot_reporter.cpp
+++ b/services/snapshot/kernel_snapshot_reporter.cpp
@@ -20,25 +20,28 @@
#include "dfx_log.h"
#ifndef HISYSEVENT_DISABLE
#include "hisysevent.h"
+#include "hisysevent_c.h"
#endif
#include "kernel_snapshot_content_builder.h"
+#include "dfx_util.h"
namespace OHOS {
namespace HiviewDFX {
-void KernelSnapshotReporter::ReportEvents(std::vector& outputs)
+void KernelSnapshotReporter::ReportEvents(std::vector& outputs, const std::string& snapshot)
{
for (auto& output : outputs) {
+ if (output[CrashSection::UID].empty()) {
+ DFXLOGE("msg format fail, report raw msg");
+ ReportRawMsg(snapshot);
+ return;
+ }
ReportCrashNoLogEvent(output);
}
}
bool KernelSnapshotReporter::ReportCrashNoLogEvent(CrashMap& output)
{
- if (output[CrashSection::UID].empty()) {
- DFXLOGE("uid is empty, not report");
- return false;
- }
#ifndef HISYSEVENT_DISABLE
int32_t uid = static_cast(strtol(output[CrashSection::UID].c_str(), nullptr, DECIMAL_BASE));
int32_t pid = static_cast(strtol(output[CrashSection::PID].c_str(), nullptr, DECIMAL_BASE));
@@ -55,7 +58,50 @@ bool KernelSnapshotReporter::ReportCrashNoLogEvent(CrashMap& output)
"PROCESS_NAME", output[CrashSection::PROCESS_NAME],
"HAPPEN_TIME", timeStamp,
"SUMMARY", KernelSnapshotContentBuilder(output).GenerateSummary());
- DFXLOGI("Report kernel snapshot event done, ret %{public}d", ret);
+ DFXLOGI("Report pid %{public}d kernel snapshot complate event ret %{public}d", pid, ret);
+ return ret == 0;
+#else
+ DFXLOGI("Not supported for kernel snapshot report.");
+ return true;
+#endif
+}
+
+int32_t KernelSnapshotReporter::GetSnapshotPid(const std::string& content)
+{
+ std::string pidKey = "pid=";
+ auto pos = content.find(pidKey);
+ if (pos == std::string::npos) {
+ return 0;
+ }
+ auto end = content.find_first_of(')', pos);
+ if (end == std::string::npos) {
+ return 0;
+ }
+ pos += pidKey.size();
+ std::string pidStr = content.substr(pos, end - pos);
+ auto pid = static_cast(strtol(pidStr.c_str(), nullptr, 10));
+ if (errno == ERANGE) {
+ return 0;
+ }
+ return pid;
+}
+
+bool KernelSnapshotReporter::ReportRawMsg(const std::string& content)
+{
+ if (content.empty()) {
+ return false;
+ }
+#ifndef HISYSEVENT_DISABLE
+ int32_t pid = GetSnapshotPid(content);
+ char procName[] = "encrypt_snapshot_proc";
+ HiSysEventParam params[] = {
+ {.name = "PID", .t = HISYSEVENT_UINT32, .v = { .ui32 = pid}, .arraySize = 0},
+ {.name = "PROCESS_NAME", .t = HISYSEVENT_STRING, .v = {.s = procName}, .arraySize = 0},
+ {.name = "HAPPEN_TIME", .t = HISYSEVENT_UINT64, .v = {.ui64 = GetTimeMilliSeconds()}, .arraySize = 0},
+ };
+ int ret = OH_HiSysEvent_Write("RELIABILITY", "CPP_CRASH_NO_LOG",
+ HISYSEVENT_FAULT, params, sizeof(params) / sizeof(params[0]));
+ DFXLOGI("Report pid %{public}d kernel snapshot raw event ret %{public}d", pid, ret);
return ret == 0;
#else
DFXLOGI("Not supported for kernel snapshot report.");
diff --git a/services/snapshot/kernel_snapshot_reporter.h b/services/snapshot/kernel_snapshot_reporter.h
index c2422dea3c39ce52601cfa747cd748200303a637..70eb92f363a8ebfdb64d9b35ad07e218e39194ff 100644
--- a/services/snapshot/kernel_snapshot_reporter.h
+++ b/services/snapshot/kernel_snapshot_reporter.h
@@ -22,9 +22,11 @@ namespace OHOS {
namespace HiviewDFX {
class KernelSnapshotReporter : public IKernelSnapshotReporter {
public:
- void ReportEvents(std::vector& outputs) override;
+ void ReportEvents(std::vector& outputs, const std::string& snapshot) override;
private:
+ bool ReportRawMsg(const std::string& content);
bool ReportCrashNoLogEvent(CrashMap& output);
+ int32_t GetSnapshotPid(const std::string& content);
};
} // namespace HiviewDFX
} // namespace OHOS
diff --git a/test/fuzztest/faultloggerdunwinder_fuzzer/faultloggerdunwinder_fuzzer.cpp b/test/fuzztest/faultloggerdunwinder_fuzzer/faultloggerdunwinder_fuzzer.cpp
index 2836e8e4d1df296f2dc315e46979bf47a7df3c7e..51b52b6f5895381c11a6f20d67926eb9a21cd76b 100644
--- a/test/fuzztest/faultloggerdunwinder_fuzzer/faultloggerdunwinder_fuzzer.cpp
+++ b/test/fuzztest/faultloggerdunwinder_fuzzer/faultloggerdunwinder_fuzzer.cpp
@@ -28,7 +28,7 @@
namespace OHOS {
namespace HiviewDFX {
-const int FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH = 50;
+
struct TestArkFrameData {
uintptr_t pc;
uintptr_t fp;
@@ -195,20 +195,21 @@ void TestThreadContext(const uint8_t* data, size_t size)
void TestDfxInstrStatistic(const uint8_t* data, size_t size)
{
+ constexpr int maxStringLength = 50;
struct TestData {
uint32_t type;
uint64_t val;
uint64_t errInfo;
+ char soName[maxStringLength];
};
if (data == nullptr || size < sizeof(TestData)) {
return;
}
auto testData = reinterpret_cast(data);
- std::string soName(reinterpret_cast(data), FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH);
- data += FAULTLOGGER_FUZZTEST_MAX_STRING_LENGTH;
InstrStatisticType statisticType = (testData->type % 10) ? InstructionEntriesArmExidx : UnsupportedArmExidx;
DfxInstrStatistic& statistic = DfxInstrStatistic::GetInstance();
- statistic.SetCurrentStatLib(soName);
+ std::string testSoName(testData->soName, maxStringLength);
+ statistic.SetCurrentStatLib(testSoName);
statistic.AddInstrStatistic(statisticType, testData->val, testData->errInfo);
std::vector> result;
statistic.DumpInstrStatResult(result);
diff --git a/test/unittest/common/common_cutil_test.cpp b/test/unittest/common/common_cutil_test.cpp
index ec0f7222844661a078967c0d4b5f53d262e69dd4..3c24122bfe1d70a1723645ffce86ec71463c6dfb 100644
--- a/test/unittest/common/common_cutil_test.cpp
+++ b/test/unittest/common/common_cutil_test.cpp
@@ -78,34 +78,6 @@ HWTEST_F(CommonCutilTest, DfxCutilTest003, TestSize.Level2)
GTEST_LOG_(INFO) << "DfxCutilTest003: end.";
}
-/**
- * @tc.name: DfxCutilTest004
- * @tc.desc: test cutil functions TrimAndDupStr
- * @tc.type: FUNC
- */
-HWTEST_F(CommonCutilTest, DfxCutilTest004, TestSize.Level2)
-{
- GTEST_LOG_(INFO) << "DfxCutilTest004: start.";
- ASSERT_FALSE(TrimAndDupStr(nullptr, nullptr));
- GTEST_LOG_(INFO) << "DfxCutilTest004: end.";
-}
-
-/**
- * @tc.name: DfxCutilTest005
- * @tc.desc: test cutil functions TrimAndDupStr
- * @tc.type: FUNC
- */
-HWTEST_F(CommonCutilTest, DfxCutilTest005, TestSize.Level2)
-{
- GTEST_LOG_(INFO) << "DfxCutilTest005: start.";
- const char src[] = "ab cd \n ef";
- char dst[11] = {0}; // 11: The length is consistent with the src[] array
- ASSERT_TRUE(TrimAndDupStr(src, dst));
- GTEST_LOG_(INFO) << "dst:" << dst;
- ASSERT_EQ(strncmp(dst, "abcd", 5), 0); // 5:length of "abcd"
- GTEST_LOG_(INFO) << "DfxCutilTest005: end.";
-}
-
/**
* @tc.name: TraceTest001
* @tc.desc: test Trace functions DfxStartTraceDlsym
diff --git a/test/unittest/common/common_test.cpp b/test/unittest/common/common_test.cpp
index 2a8a8cf7dd1ba1d9ffb7997aa2a2ce862bddcd8d..d473028d89fdacc471eb3185633c19fd8f7400df 100644
--- a/test/unittest/common/common_test.cpp
+++ b/test/unittest/common/common_test.cpp
@@ -46,8 +46,8 @@ static void getLibPathsBySystemBits(vector &filePaths)
"/system/lib64/libstacktrace_rust.dylib.so",
"/system/lib64/libpanic_handler.dylib.so",
"/system/lib64/platformsdk/libjson_stack_formatter.z.so",
- "/system/lib64/chipset-sdk/libdfx_signalhandler.z.so",
"/system/lib64/chipset-sdk/libcrash_exception.z.so",
+ "/system/lib64/chipset-sdk-sp/libdfx_signalhandler.z.so",
"/system/lib64/chipset-sdk-sp/librustc_demangle.z.so",
"/system/lib64/chipset-sdk-sp/libasync_stack.z.so",
"/system/lib64/chipset-sdk-sp/libdfx_dumpcatcher.z.so",
@@ -61,8 +61,8 @@ static void getLibPathsBySystemBits(vector &filePaths)
"/system/lib/libstacktrace_rust.dylib.so",
"/system/lib/libpanic_handler.dylib.so",
"/system/lib/platformsdk/libjson_stack_formatter.z.so",
- "/system/lib/chipset-sdk/libdfx_signalhandler.z.so",
"/system/lib/chipset-sdk/libcrash_exception.z.so",
+ "/system/lib/chipset-sdk-sp/libdfx_signalhandler.z.so",
"/system/lib/chipset-sdk-sp/librustc_demangle.z.so",
"/system/lib/chipset-sdk-sp/libasync_stack.z.so",
"/system/lib/chipset-sdk-sp/libdfx_dumpcatcher.z.so",
diff --git a/test/unittest/faultloggerd/BUILD.gn b/test/unittest/faultloggerd/BUILD.gn
index 4538769eb57e2c0d32c9ce52e983831cba504c4d..93904c827dbc540b653574767c2c062e91a0d059 100644
--- a/test/unittest/faultloggerd/BUILD.gn
+++ b/test/unittest/faultloggerd/BUILD.gn
@@ -64,7 +64,6 @@ if (defined(ohos_lite)) {
"$faultloggerd_path/services/fault_logger_service.cpp",
"$faultloggerd_path/services/temp_file_manager.cpp",
"$faultloggerd_path/services/fault_common_util.cpp",
- "$faultloggerd_path/services/fault_coredump_service.cpp",
"faultlogger_server_test.cpp",
"faultloggerd_test.cpp",
"temp_file_manager_test.cpp",
@@ -116,12 +115,14 @@ if (defined(ohos_lite)) {
"$faultloggerd_interfaces_path/innerkits/procinfo/include",
"$faultloggerd_path/services",
"$faultloggerd_path/test/utils",
+ "$faultloggerd_path/services/coredump",
]
sources = [
"$faultloggerd_path/interfaces/innerkits/faultloggerd_client/faultloggerd_client.cpp",
"$faultloggerd_path/interfaces/innerkits/faultloggerd_client/faultloggerd_socket.cpp",
"faultlogger_server_test.cpp",
"faultloggerd_client_test.cpp",
+ "faultloggerd_coredump_test.cpp",
"faultloggerd_test.cpp",
"temp_file_manager_test.cpp",
]
diff --git a/test/unittest/faultloggerd/faultloggerd_client_test.cpp b/test/unittest/faultloggerd/faultloggerd_client_test.cpp
index 2a832cbb306157afde1bf48f59513976c0d5d5a1..f07109bbc289d6f7ea6ed6c3cea52beda521e425 100644
--- a/test/unittest/faultloggerd/faultloggerd_client_test.cpp
+++ b/test/unittest/faultloggerd/faultloggerd_client_test.cpp
@@ -30,7 +30,6 @@
#include "dfx_util.h"
#include "faultloggerd_client.h"
#include "fault_common_util.h"
-#include "fault_coredump_service.h"
#include "faultloggerd_test.h"
#include "fault_logger_daemon.h"
#include "smart_fd.h"
@@ -58,34 +57,6 @@ void FaultloggerdClientTest::SetUpTestCase()
std::this_thread::sleep_for(std::chrono::milliseconds(waitTime));
}
-/**
- * @tc.name: SendSignalToHapWatchdogThreadTest
- * @tc.desc: Test send signal to watchdog thread
- * @tc.type: FUNC
- */
-HWTEST_F(FaultloggerdClientTest, SendSignalToHapWatchdogThreadTest, TestSize.Level2)
-{
- GTEST_LOG_(INFO) << "SendSignalToHapWatchdogThreadTest: start.";
- pid_t pid = -1;
- siginfo_t si = {};
- ASSERT_EQ(FaultCommonUtil::SendSignalToHapWatchdogThread(pid, si), ResponseCode::DEFAULT_ERROR_CODE);
- GTEST_LOG_(INFO) << "SendSignalToHapWatchdogThreadTest: end.";
-}
-
-/**
- * @tc.name: SendSignalToProcessTest
- * @tc.desc: SendSignalToProcess
- * @tc.type: FUNC
- */
-HWTEST_F(FaultloggerdClientTest, SendSignalToProcessTest, TestSize.Level2)
-{
- GTEST_LOG_(INFO) << "SendSignalToProcessTest: start.";
- pid_t pid = -1;
- siginfo_t si = {};
- ASSERT_EQ(FaultCommonUtil::SendSignalToProcess(pid, si), ResponseCode::REQUEST_SUCCESS);
- GTEST_LOG_(INFO) << "SendSignalToProcessTest: end.";
-}
-
/**
* @tc.name: GetUcredByPeerCredTest
* @tc.desc: GetUcredByPeerCred
@@ -101,210 +72,6 @@ HWTEST_F(FaultloggerdClientTest, GetUcredByPeerCredTest, TestSize.Level2)
GTEST_LOG_(INFO) << "GetUcredByPeerCredTest: end.";
}
-/**
- * @tc.name: HandleProcessDumpPidTest001
- * @tc.desc: HandleProcessDumpPid
- * @tc.type: FUNC
- */
-HWTEST_F(FaultloggerdClientTest, HandleProcessDumpPidTest001, TestSize.Level2)
-{
- GTEST_LOG_(INFO) << "HandleProcessDumpPidTest001: start.";
- int32_t targetPid = 123;
- int32_t processDumpPid = -1;
- CoredumpStatusService coredumpStatusService;
- EXPECT_FALSE(coredumpStatusService.HandleProcessDumpPid(targetPid, processDumpPid));
-
- GTEST_LOG_(INFO) << "HandleProcessDumpPidTest001: end.";
-}
-
-/**
- * @tc.name: HandleProcessDumpPidTest002
- * @tc.desc: HandleProcessDumpPid
- * @tc.type: FUNC
- */
-HWTEST_F(FaultloggerdClientTest, HandleProcessDumpPidTest002, TestSize.Level2)
-{
- GTEST_LOG_(INFO) << "HandleProcessDumpPidTest002: start.";
- int32_t targetPid = 123;
- int32_t processDumpPid = 456;
- CoredumpStatusService coredumpStatusService;
- EXPECT_FALSE(coredumpStatusService.HandleProcessDumpPid(targetPid, processDumpPid));
- GTEST_LOG_(INFO) << "HandleProcessDumpPidTest002: end.";
-}
-
-/**
- * @tc.name: DoCoredumpRequestTest
- * @tc.desc: DoCoredumpRequest
- * @tc.type: FUNC
- */
-HWTEST_F(FaultloggerdClientTest, DoCoredumpRequestTest, TestSize.Level2)
-{
- GTEST_LOG_(INFO) << "DoCoredumpRequestTest: start.";
- std::string socketName = "test_socket";
- int32_t connectionFd = 1;
- CoreDumpRequestData requestData = {};
- CoredumpService coredumpService;
- ASSERT_EQ(coredumpService.DoCoredumpRequest(socketName, connectionFd, requestData), ResponseCode::REQUEST_REJECT);
- GTEST_LOG_(INFO) << "DoCoredumpRequestTest: end.";
-}
-
-/**
- * @tc.name: RecorderProcessMapTest
- * @tc.desc: RecorderProcessMap
- * @tc.type: FUNC
- */
-HWTEST_F(FaultloggerdClientTest, RecorderProcessMapTest, TestSize.Level2)
-{
- GTEST_LOG_(INFO) << "RecorderProcessMapTest: start.";
- RecorderProcessMap recorderProcessMap;
- int32_t coredumpSocketId = 0;
- int32_t processDumpPid = getpid();
- bool flag = false;
- EXPECT_FALSE(recorderProcessMap.ClearTargetPid(getpid()));
- EXPECT_FALSE(recorderProcessMap.SetCancelFlag(getpid(), true));
- EXPECT_FALSE(recorderProcessMap.SetProcessDumpPid(getpid(), getpid()));
- EXPECT_FALSE(recorderProcessMap.GetCoredumpSocketId(getpid(), coredumpSocketId));
- EXPECT_FALSE(recorderProcessMap.GetProcessDumpPid(getpid(), processDumpPid));
- EXPECT_FALSE(recorderProcessMap.GetCancelFlag(getpid(), flag));
- GTEST_LOG_(INFO) << "RecorderProcessMapTest: end.";
-}
-
-/**
- * @tc.name: CoreDumpCbTest001
- * @tc.desc: Test startcoredumpcb and finishcoredumpcb process
- * @tc.type: FUNC
- */
-HWTEST_F(FaultloggerdClientTest, CoreDumpCbTest001, TestSize.Level2)
-{
- GTEST_LOG_(INFO) << "CoreDumpCbTest001: start.";
- int32_t retCode = ResponseCode::REQUEST_SUCCESS;
- std::string fileName = "com.ohos.sceneboard.dmp";
- ASSERT_EQ(StartCoredumpCb(getpid(), getpid()), ResponseCode::ABNORMAL_SERVICE);
- ASSERT_EQ(FinishCoredumpCb(getpid(), fileName, retCode), ResponseCode::REQUEST_SUCCESS);
- GTEST_LOG_(INFO) << "CoreDumpCbTest001: end.";
-}
-
-/**
- * @tc.name: CoreDumpCbTest002
- * @tc.desc: Test coredump process
- * @tc.type: FUNC
- */
-HWTEST_F(FaultloggerdClientTest, CoreDumpCbTest002, TestSize.Level2)
-{
- GTEST_LOG_(INFO) << "CoreDumpCbTest002: start.";
- int32_t retCode = ResponseCode::REQUEST_SUCCESS;
- std::string fileName = "com.ohos.sceneboard.dmp";
-
- auto threadFunc = [&fileName, retCode]() {
- sleep(1);
- StartCoredumpCb(getpid(), getpid());
- FinishCoredumpCb(getpid(), fileName, retCode);
- };
-
- std::thread t(threadFunc);
- t.detach();
- auto ret = SaveCoredumpToFileTimeout(getpid());
- ASSERT_EQ(ret, "com.ohos.sceneboard.dmp");
- GTEST_LOG_(INFO) << "CoreDumpCbTest002: end.";
-}
-
-/**
- * @tc.name: CoreDumpCbTest003
- * @tc.desc: Test coredump cancel process
- * @tc.type: FUNC
- */
-HWTEST_F(FaultloggerdClientTest, CoreDumpCbTest003, TestSize.Level2)
-{
- GTEST_LOG_(INFO) << "CoreDumpCbTest003: start.";
- auto threadFunc = []() {
- sleep(1);
- ASSERT_EQ(CancelCoredump(getpid()), ResponseCode::REQUEST_SUCCESS);
- StartCoredumpCb(getpid(), getpid()); // to clean processmap
- };
-
- std::thread t(threadFunc);
- t.detach();
- auto ret = SaveCoredumpToFileTimeout(getpid());
- ASSERT_EQ(ret, "");
- GTEST_LOG_(INFO) << "CoreDumpCbTest003: end.";
-}
-
-/**
- * @tc.name: CoreDumpCbTest004
- * @tc.desc: Test coredump cancel process
- * @tc.type: FUNC
- */
-HWTEST_F(FaultloggerdClientTest, CoreDumpCbTest004, TestSize.Level2)
-{
- GTEST_LOG_(INFO) << "CoreDumpCbTest004: start.";
- auto threadFunc = []() {
- sleep(1);
- StartCoredumpCb(getpid(), getpid());
- ASSERT_EQ(CancelCoredump(getpid()), ResponseCode::REQUEST_SUCCESS);
- };
-
- std::thread t(threadFunc);
- t.detach();
- auto ret = SaveCoredumpToFileTimeout(getpid());
- ASSERT_EQ(ret, "");
- GTEST_LOG_(INFO) << "CoreDumpCbTest004: end.";
-}
-
-/**
- * @tc.name: CoreDumpCbTest005
- * @tc.desc: Test coredump cancel process
- * @tc.type: FUNC
- */
-HWTEST_F(FaultloggerdClientTest, CoreDumpCbTest005, TestSize.Level2)
-{
- GTEST_LOG_(INFO) << "CoreDumpCbTest005: start.";
- ASSERT_EQ(CancelCoredump(getpid()), ResponseCode::DEFAULT_ERROR_CODE);
- GTEST_LOG_(INFO) << "CoreDumpCbTest005: end.";
-}
-
-/**
- * @tc.name: CoreDumpCbTest006
- * @tc.desc: Test coredump repeat process
- * @tc.type: FUNC
- */
-HWTEST_F(FaultloggerdClientTest, CoreDumpCbTest006, TestSize.Level2)
-{
- GTEST_LOG_(INFO) << "CoreDumpCbTest006: start.";
- int32_t retCode = ResponseCode::REQUEST_SUCCESS;
- std::string fileName = "com.ohos.sceneboard.dmp";
-
- auto threadFunc = [&fileName, retCode]() {
- sleep(1);
- ASSERT_EQ(SaveCoredumpToFileTimeout(getpid()), "");
- StartCoredumpCb(getpid(), getpid());
- FinishCoredumpCb(getpid(), fileName, retCode);
- };
-
- std::thread t(threadFunc);
- t.detach();
- auto ret = SaveCoredumpToFileTimeout(getpid());
- ASSERT_EQ(ret, "com.ohos.sceneboard.dmp");
- GTEST_LOG_(INFO) << "CoreDumpCbTest006: end.";
-}
-
-/**
- * @tc.name: CoreDumpCbTest007
- * @tc.desc: Test coredump process when targetPid = -1
- * @tc.type: FUNC
- */
-HWTEST_F(FaultloggerdClientTest, CoreDumpCbTest007, TestSize.Level2)
-{
- GTEST_LOG_(INFO) << "CoreDumpCbTest007: start.";
- int32_t targetPid = -1;
- int32_t retCode = ResponseCode::REQUEST_SUCCESS;
- std::string fileName = "com.ohos.sceneboard.dmp";
- ASSERT_EQ(SaveCoredumpToFileTimeout(targetPid), "");
- ASSERT_EQ(CancelCoredump(targetPid), ResponseCode::DEFAULT_ERROR_CODE);
- ASSERT_EQ(StartCoredumpCb(targetPid, getpid()), ResponseCode::DEFAULT_ERROR_CODE);
- ASSERT_EQ(FinishCoredumpCb(targetPid, fileName, retCode), ResponseCode::DEFAULT_ERROR_CODE);
- GTEST_LOG_(INFO) << "CoreDumpCbTest007: end.";
-}
-
/**
* @tc.name: RequestSdkDumpTest001
* @tc.desc: test the function for RequestSdkDump.
diff --git a/test/unittest/faultloggerd/faultloggerd_coredump_test.cpp b/test/unittest/faultloggerd/faultloggerd_coredump_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4ce3458063401abb3716ef5c2878bfc0854fec10
--- /dev/null
+++ b/test/unittest/faultloggerd/faultloggerd_coredump_test.cpp
@@ -0,0 +1,596 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include
+#include
+#include
+
+#if defined(HAS_LIB_SELINUX)
+#include
+#endif
+
+#include
+#include
+#include
+#include
+#include "dfx_test_util.h"
+#include "dfx_util.h"
+#include "faultloggerd_client.h"
+#include "fault_common_util.h"
+#include "coredump_manager_service.h"
+#include "faultloggerd_test.h"
+#include "fault_logger_daemon.h"
+#include "smart_fd.h"
+#include "coredump_callback_service.h"
+
+using namespace testing;
+using namespace testing::ext;
+
+namespace OHOS {
+namespace HiviewDFX {
+class FaultloggerdCoredumpTest : public testing::Test {
+public:
+ static void SetUpTestCase();
+ static void TearDownTestCase();
+};
+
+void FaultloggerdCoredumpTest::TearDownTestCase()
+{
+}
+
+void FaultloggerdCoredumpTest::SetUpTestCase()
+{
+ FaultLoggerdTestServer::GetInstance();
+ constexpr int waitTime = 1500; // 1.5s;
+ std::this_thread::sleep_for(std::chrono::milliseconds(waitTime));
+}
+
+/**
+ * @tc.name: SendSignalToHapWatchdogThreadTest
+ * @tc.desc: Test send signal to watchdog thread
+ * @tc.type: FUNC
+ */
+ HWTEST_F(FaultloggerdCoredumpTest, SendSignalToHapWatchdogThreadTest, TestSize.Level2)
+ {
+ GTEST_LOG_(INFO) << "SendSignalToHapWatchdogThreadTest: start.";
+ pid_t pid = -1;
+ siginfo_t si = {};
+ EXPECT_EQ(FaultCommonUtil::SendSignalToHapWatchdogThread(pid, si), ResponseCode::DEFAULT_ERROR_CODE);
+
+ pid = GetProcessPid("com.ohos.sceneboard");
+ FaultCommonUtil::SendSignalToHapWatchdogThread(pid, si);
+
+ GTEST_LOG_(INFO) << "SendSignalToHapWatchdogThreadTest: end.";
+}
+
+/**
+ * @tc.name: SendSignalToProcessTest
+ * @tc.desc: SendSignalToProcess
+ * @tc.type: FUNC
+ */
+ HWTEST_F(FaultloggerdCoredumpTest, SendSignalToProcessTest, TestSize.Level2)
+ {
+ GTEST_LOG_(INFO) << "SendSignalToProcessTest: start.";
+ pid_t pid = -1;
+ siginfo_t si = {};
+ EXPECT_EQ(FaultCommonUtil::SendSignalToProcess(pid, si), ResponseCode::REQUEST_SUCCESS);
+ pid = GetProcessPid("com.ohos.sceneboard");
+ EXPECT_EQ(FaultCommonUtil::SendSignalToProcess(pid, si), ResponseCode::REQUEST_SUCCESS);
+ GTEST_LOG_(INFO) << "SendSignalToProcessTest: end.";
+}
+
+/**
+ * @tc.name: SendStartSignal
+ * @tc.desc: SendSignalToProcess
+ * @tc.type: FUNC
+ */
+ HWTEST_F(FaultloggerdCoredumpTest, SendStartSignal, TestSize.Level2)
+ {
+ GTEST_LOG_(INFO) << "SendStartSignal: start.";
+ pid_t pid = -1;
+ siginfo_t si = {};
+ CoredumpSignalService().SendStartSignal(pid);
+ GTEST_LOG_(INFO) << "SendStartSignal: end.";
+}
+
+/**
+ * @tc.name: GetUcredByPeerCredTest
+ * @tc.desc: GetUcredByPeerCred
+ * @tc.type: FUNC
+ */
+HWTEST_F(FaultloggerdCoredumpTest, GetUcredByPeerCredTest, TestSize.Level2)
+{
+ GTEST_LOG_(INFO) << "GetUcredByPeerCredTest: start.";
+ int32_t connectionFd = 0;
+ struct ucred rcred;
+ bool result = FaultCommonUtil::GetUcredByPeerCred(rcred, connectionFd);
+ EXPECT_FALSE(result);
+ GTEST_LOG_(INFO) << "GetUcredByPeerCredTest: end.";
+}
+
+/**
+ * @tc.name: HandleProcessDumpPidTest001
+ * @tc.desc: HandleProcessDumpPid
+ * @tc.type: FUNC
+ */
+HWTEST_F(FaultloggerdCoredumpTest, HandleProcessDumpPidTest001, TestSize.Level2)
+{
+ GTEST_LOG_(INFO) << "HandleProcessDumpPidTest001: start.";
+ int32_t targetPid = 123;
+ int32_t processDumpPid = -1;
+
+ CoreDumpStatusData data;
+ CoredumpCallbackService coredumpStatusService;
+ coredumpStatusService.HandleUpdateWorkerPid(data);
+
+ GTEST_LOG_(INFO) << "HandleProcessDumpPidTest001: end.";
+}
+
+/**
+ * @tc.name: HandleProcessDumpPidTest002
+ * @tc.desc: HandleProcessDumpPid
+ * @tc.type: FUNC
+ */
+HWTEST_F(FaultloggerdCoredumpTest, HandleProcessDumpPidTest002, TestSize.Level2)
+{
+ GTEST_LOG_(INFO) << "HandleProcessDumpPidTest002: start.";
+ int32_t targetPid = 123;
+ int32_t processDumpPid = 456;
+
+ CoreDumpStatusData data;
+ CoredumpCallbackService coredumpStatusService;
+ coredumpStatusService.HandleUpdateWorkerPid(data);
+
+ auto ret = coredumpStatusService.OnRequest("", -1, data);
+ EXPECT_EQ(ret, ResponseCode::REQUEST_REJECT);
+ GTEST_LOG_(INFO) << "HandleProcessDumpPidTest002: end.";
+}
+
+/**
+ * @tc.name: DoCoredumpRequestTest
+ * @tc.desc: DoCoredumpRequest
+ * @tc.type: FUNC
+ */
+HWTEST_F(FaultloggerdCoredumpTest, DoCoredumpRequestTest, TestSize.Level2)
+{
+ GTEST_LOG_(INFO) << "DoCoredumpRequestTest: start.";
+ std::string socketName = "test_socket";
+ int32_t connectionFd = 1;
+ CoreDumpRequestData requestData = {
+ .pid = 666
+ };
+ CoredumpManagerService coredumpService;
+ auto ret = coredumpService.HandleCreate(connectionFd, requestData);
+ coredumpService.HandleCancel(requestData);
+ requestData.pid = 999;
+ coredumpService.HandleCancel(requestData);
+
+ GTEST_LOG_(INFO) << "DoCoredumpRequestTest: end.";
+}
+
+/**
+ * @tc.name: RecorderProcessMapTest
+ * @tc.desc: test sessionManager
+ * @tc.type: FUNC
+ */
+HWTEST_F(FaultloggerdCoredumpTest, RecorderProcessMapTest, TestSize.Level2)
+{
+ GTEST_LOG_(INFO) << "RecorderProcessMapTest: start.";
+ auto& sessionManager = CoredumpSessionManager::Instance();
+ sessionManager.RemoveSession(0);
+ GTEST_LOG_(INFO) << "RecorderProcessMapTest: end.";
+}
+
+/**
+ * @tc.name: CoreDumpCbTest001
+ * @tc.desc: Test startcoredumpcb and finishcoredumpcb process
+ * @tc.type: FUNC
+ */
+HWTEST_F(FaultloggerdCoredumpTest, CoreDumpCbTest001, TestSize.Level2)
+{
+ GTEST_LOG_(INFO) << "CoreDumpCbTest001: start.";
+ int32_t retCode = ResponseCode::REQUEST_SUCCESS;
+ std::string fileName = "com.ohos.sceneboard.dmp";
+ ASSERT_EQ(StartCoredumpCb(getpid(), getpid()), ResponseCode::ABNORMAL_SERVICE);
+ ASSERT_EQ(FinishCoredumpCb(getpid(), fileName, retCode), ResponseCode::REQUEST_SUCCESS);
+ GTEST_LOG_(INFO) << "CoreDumpCbTest001: end.";
+}
+
+/**
+ * @tc.name: CoreDumpCbTest002
+ * @tc.desc: Test coredump process
+ * @tc.type: FUNC
+ */
+HWTEST_F(FaultloggerdCoredumpTest, CoreDumpCbTest002, TestSize.Level2)
+{
+ GTEST_LOG_(INFO) << "CoreDumpCbTest002: start.";
+ int32_t retCode = ResponseCode::REQUEST_SUCCESS;
+ std::string fileName = "com.ohos.sceneboard.dmp";
+
+ auto threadFunc = [&fileName, retCode]() {
+ sleep(1);
+ StartCoredumpCb(getpid(), getpid());
+ FinishCoredumpCb(getpid(), fileName, retCode);
+ };
+
+ std::thread t(threadFunc);
+ t.detach();
+ auto ret = SaveCoredumpToFileTimeout(getpid());
+ ASSERT_EQ(ret, "com.ohos.sceneboard.dmp");
+ GTEST_LOG_(INFO) << "CoreDumpCbTest002: end.";
+}
+
+/**
+ * @tc.name: CoreDumpCbTest003
+ * @tc.desc: Test coredump cancel process
+ * @tc.type: FUNC
+ */
+HWTEST_F(FaultloggerdCoredumpTest, CoreDumpCbTest003, TestSize.Level2)
+{
+ GTEST_LOG_(INFO) << "CoreDumpCbTest003: start.";
+ auto threadFunc = []() {
+ sleep(1);
+ ASSERT_EQ(CancelCoredump(getpid()), ResponseCode::REQUEST_SUCCESS);
+ StartCoredumpCb(getpid(), getpid()); // to clean processmap
+ };
+
+ std::thread t(threadFunc);
+ t.detach();
+ auto ret = SaveCoredumpToFileTimeout(getpid());
+ ASSERT_EQ(ret, "");
+ GTEST_LOG_(INFO) << "CoreDumpCbTest003: end.";
+}
+
+/**
+ * @tc.name: CoreDumpCbTest004
+ * @tc.desc: Test coredump cancel process
+ * @tc.type: FUNC
+ */
+HWTEST_F(FaultloggerdCoredumpTest, CoreDumpCbTest004, TestSize.Level2)
+{
+ GTEST_LOG_(INFO) << "CoreDumpCbTest004: start.";
+ auto threadFunc = []() {
+ sleep(1);
+ StartCoredumpCb(getpid(), getpid());
+ ASSERT_EQ(CancelCoredump(getpid()), ResponseCode::REQUEST_SUCCESS);
+ };
+
+ std::thread t(threadFunc);
+ t.detach();
+ auto ret = SaveCoredumpToFileTimeout(getpid());
+ ASSERT_EQ(ret, "");
+ GTEST_LOG_(INFO) << "CoreDumpCbTest004: end.";
+}
+
+/**
+ * @tc.name: CoreDumpCbTest005
+ * @tc.desc: Test coredump cancel process
+ * @tc.type: FUNC
+ */
+HWTEST_F(FaultloggerdCoredumpTest, CoreDumpCbTest005, TestSize.Level2)
+{
+ GTEST_LOG_(INFO) << "CoreDumpCbTest005: start.";
+ ASSERT_EQ(CancelCoredump(getpid()), ResponseCode::DEFAULT_ERROR_CODE);
+ GTEST_LOG_(INFO) << "CoreDumpCbTest005: end.";
+}
+
+/**
+ * @tc.name: CoreDumpCbTest006
+ * @tc.desc: Test coredump repeat process
+ * @tc.type: FUNC
+ */
+HWTEST_F(FaultloggerdCoredumpTest, CoreDumpCbTest006, TestSize.Level2)
+{
+ GTEST_LOG_(INFO) << "CoreDumpCbTest006: start.";
+ int32_t retCode = ResponseCode::REQUEST_SUCCESS;
+ std::string fileName = "com.ohos.sceneboard.dmp";
+
+ auto threadFunc = [&fileName, retCode]() {
+ sleep(1);
+ ASSERT_EQ(SaveCoredumpToFileTimeout(getpid()), "");
+ StartCoredumpCb(getpid(), getpid());
+ FinishCoredumpCb(getpid(), fileName, retCode);
+ };
+
+ std::thread t(threadFunc);
+ t.detach();
+ auto ret = SaveCoredumpToFileTimeout(getpid());
+ ASSERT_EQ(ret, "com.ohos.sceneboard.dmp");
+ GTEST_LOG_(INFO) << "CoreDumpCbTest006: end.";
+}
+
+/**
+ * @tc.name: CoreDumpCbTest007
+ * @tc.desc: Test coredump process when targetPid = -1
+ * @tc.type: FUNC
+ */
+HWTEST_F(FaultloggerdCoredumpTest, CoreDumpCbTest007, TestSize.Level2)
+{
+ GTEST_LOG_(INFO) << "CoreDumpCbTest007: start.";
+ int32_t targetPid = -1;
+ int32_t retCode = ResponseCode::REQUEST_SUCCESS;
+ std::string fileName = "com.ohos.sceneboard.dmp";
+ ASSERT_EQ(SaveCoredumpToFileTimeout(targetPid), "");
+ ASSERT_EQ(CancelCoredump(targetPid), ResponseCode::DEFAULT_ERROR_CODE);
+ ASSERT_EQ(StartCoredumpCb(targetPid, getpid()), ResponseCode::DEFAULT_ERROR_CODE);
+ ASSERT_EQ(FinishCoredumpCb(targetPid, fileName, retCode), ResponseCode::DEFAULT_ERROR_CODE);
+ GTEST_LOG_(INFO) << "CoreDumpCbTest007: end.";
+}
+
+/**
+ * @tc.name: CoredumpSessionService001
+ * @tc.desc: test CoredumpSessionService
+ * @tc.type: FUNC
+ */
+HWTEST_F(FaultloggerdCoredumpTest, CoredumpSessionService001, TestSize.Level2)
+{
+ GTEST_LOG_(INFO) << "CoredumpSessionService001: start.";
+ CoredumpSessionService sessionService;
+
+ CreateCoredumpRequest request;
+ pid_t testPid = 666;
+ pid_t validPid = 999;
+ request.targetPid = 666;
+
+ auto sessionId = sessionService.CreateSession(request);
+ EXPECT_EQ(sessionId, testPid);
+
+ auto ret = sessionService.UpdateWorkerPid(sessionId, 124);
+ EXPECT_TRUE(ret);
+ ret = sessionService.UpdateWorkerPid(validPid, 124);
+ EXPECT_FALSE(ret);
+
+ CoredumpCallbackReport reportReq;
+ sessionService.UpdateReport(sessionId, reportReq);
+ sessionService.UpdateReport(validPid, reportReq);
+
+ sessionService.GetClientFd(sessionId);
+ sessionService.GetClientFd(validPid);
+
+ sessionService.WriteTimeoutAndClose(sessionId);
+ sessionService.WriteTimeoutAndClose(validPid);
+
+ sessionService.WriteResultAndClose(sessionId);
+ sessionService.WriteResultAndClose(validPid);
+
+ CoreDumpResult result;
+ sessionService.WriteResult(sessionId, result);
+ sessionService.WriteResult(validPid, result);
+
+ ret = sessionService.CancelSession(sessionId);
+ ret = sessionService.CancelSession(validPid);
+ EXPECT_FALSE(ret);
+
+ GTEST_LOG_(INFO) << "CoredumpSessionService001: end.";
+}
+
+/**
+ * @tc.name: FaultCoredumpConfig001
+ * @tc.desc: test FaultCoredumpConfig
+ * @tc.type: FUNC
+ */
+HWTEST_F(FaultloggerdCoredumpTest, FaultCoredumpConfig001, TestSize.Level2)
+{
+ GTEST_LOG_(INFO) << "FaultCoredumpConfig001: start.";
+ FaultCoredumpConfig::GetInstance();
+
+ string path = "/system/etc/fault_coredump.json";
+ auto& coredumpConfig = FaultCoredumpConfig::GetInstance(path);
+
+ coredumpConfig.Contains(999);
+
+ std::string content = R"({
+ "Profiles": {
+
+ })";
+ auto ret = coredumpConfig.Parse(content);
+ EXPECT_FALSE(ret);
+
+ content = R"({
+ "Profiles": {
+ }
+ })";
+
+ ret = coredumpConfig.Parse(content);
+ EXPECT_FALSE(ret);
+
+ content = R"({
+ "whitelist": 123
+ })";
+ ret = coredumpConfig.Parse(content);
+ EXPECT_FALSE(ret);
+ content = R"({
+ "whitelist": ["ABC"]
+ })";
+ ret = coredumpConfig.Parse(content);
+
+ content = R"({
+ "whitelist": [0, 134]
+ })";
+ ret = coredumpConfig.Parse(content);
+ EXPECT_TRUE(ret);
+
+ GTEST_LOG_(INFO) << "FaultCoredumpConfig001: end.";
+}
+
+/**
+ * @tc.name: CoredumpRequestValidator001
+ * @tc.desc: test CoredumpRequestValidator
+ * @tc.type: FUNC
+ */
+HWTEST_F(FaultloggerdCoredumpTest, CoredumpRequestValidator001, TestSize.Level2)
+{
+ GTEST_LOG_(INFO) << "CoredumpRequestValidator001: start.";
+ CoredumpRequestValidator validator;
+ std::string socketName = "server";
+ int32_t connectionFd = -1;
+ CoreDumpRequestData request;
+ request.pid = -1;
+ validator.ValidateRequest(socketName, -1, request);
+
+ request.pid = 666;
+ validator.ValidateRequest(socketName, -1, request);
+
+ socketName = "faultloggerd.server";
+ validator.ValidateRequest(socketName, -1, request);
+
+ auto ret = CoredumpRequestValidator::CheckCoredumpUID(9999);
+ EXPECT_FALSE(ret);
+
+ int fd = open("dev/null", O_RDONLY);
+ CoredumpRequestValidator::IsAuthorizedUid(fd);
+ close(fd);
+
+ GTEST_LOG_(INFO) << "CoredumpRequestValidator001: end.";
+}
+
+/**
+ * @tc.name: CoredumpFacade001
+ * @tc.desc: test facade
+ * @tc.type: FUNC
+ */
+HWTEST_F(FaultloggerdCoredumpTest, CoredumpFacade001, TestSize.Level2)
+{
+ GTEST_LOG_(INFO) << "CoredumpFacade001: start.";
+
+ CoredumpFacade facade;
+ CreateCoredumpRequest request;
+ request.targetPid = 666;
+ bool ret = facade.CreateCoredump(request);
+ EXPECT_TRUE(ret);
+
+ facade.OnTimeout(666);
+ facade.OnTimeout(999);
+
+ request.targetPid = 555;
+ facade.CreateCoredump(request);
+ facade.CancelCoredump(999);
+ facade.CancelCoredump(555);
+
+ GTEST_LOG_(INFO) << "CoredumpFacade001: end.";
+}
+
+/**
+ * @tc.name: SessionStateContext001
+ * @tc.desc: test SessionStateContext
+ * @tc.type: FUNC
+ */
+HWTEST_F(FaultloggerdCoredumpTest, SessionStateContext001, TestSize.Level2)
+{
+ GTEST_LOG_(INFO) << "SessionStateContext001: start.";
+
+ auto ret = SessionStateContext::CreateState(CoredumpStatus::PENDING);
+ EXPECT_TRUE(ret);
+ SessionStateContext::CreateState(CoredumpStatus::RUNNING);
+ SessionStateContext::CreateState(CoredumpStatus::SUCCESS);
+ SessionStateContext::CreateState(CoredumpStatus::FAILED);
+ SessionStateContext::CreateState(CoredumpStatus::CANCEL_PENDING);
+ SessionStateContext::CreateState(CoredumpStatus::CANCELED);
+ SessionStateContext::CreateState(CoredumpStatus::CANCEL_TIMEOUT);
+ SessionStateContext::CreateState(CoredumpStatus::PENDING);
+ ret = SessionStateContext::CreateState(CoredumpStatus::INVALID_STATUS);
+ EXPECT_FALSE(ret);
+
+ SessionStateContext stateContext;
+ CoredumpEvent event = CoredumpEvent::TIMEOUT;
+ CoredumpSession session;
+ session.status = CoredumpStatus::INVALID_STATUS;
+ stateContext.HandleEvent(session, event);
+
+ GTEST_LOG_(INFO) << "SessionStateContext001: end.";
+}
+
+/**
+ * @tc.name: SessionStateContext002
+ * @tc.desc: RecorderProcessMap
+ * @tc.type: FUNC
+ */
+HWTEST_F(FaultloggerdCoredumpTest, SessionStateContext002, TestSize.Level2)
+{
+ GTEST_LOG_(INFO) << "SessionStateContext002: start.";
+ SessionStateContext stateContext;
+ CoredumpEvent event = CoredumpEvent::INVALID_EVENT;
+
+ CoredumpSession session;
+ session.status = CoredumpStatus::INVALID_STATUS;
+ stateContext.HandleEvent(session, event);
+
+ auto pendingState = SessionStateContext::CreateState(CoredumpStatus::PENDING);
+ pendingState->OnEvent(CoredumpEvent::INVALID_EVENT, session);
+
+ auto runningState = SessionStateContext::CreateState(CoredumpStatus::RUNNING);
+ runningState->OnEvent(CoredumpEvent::REPORT_FAIL, session);
+ runningState->OnEvent(CoredumpEvent::INVALID_EVENT, session);
+
+ auto cancelPendingState = SessionStateContext::CreateState(CoredumpStatus::CANCEL_PENDING);
+ cancelPendingState->OnEvent(CoredumpEvent::TIMEOUT, session);
+ cancelPendingState->OnEvent(CoredumpEvent::INVALID_EVENT, session);
+ EXPECT_TRUE(cancelPendingState);
+
+ pendingState->OnEvent(CoredumpEvent::INVALID_EVENT, session);
+ GTEST_LOG_(INFO) << "SessionStateContext002: end.";
+}
+
+/**
+ * @tc.name: CoredumpCallbackValidator001
+ * @tc.desc: RecorderProcessMap
+ * @tc.type: FUNC
+ */
+HWTEST_F(FaultloggerdCoredumpTest, CoredumpCallbackValidator001, TestSize.Level2)
+{
+ GTEST_LOG_(INFO) << "CoredumpCallbackValidator001: start.";
+
+ std::string socketName = "server";
+ int32_t connectionFd = 999;
+ CoreDumpStatusData data;
+ data.pid = -1;
+
+ auto ret = CoredumpCallbackValidator::ValidateRequest(socketName, connectionFd, data);
+ EXPECT_EQ(ret, ResponseCode::REQUEST_REJECT);
+
+ data.pid = getpid();
+ CoredumpCallbackValidator::ValidateRequest(socketName, connectionFd, data);
+ EXPECT_EQ(ret, ResponseCode::REQUEST_REJECT);
+ GTEST_LOG_(INFO) << "CoredumpCallbackValidator001: end.";
+}
+
+/**
+ * @tc.name: CoredumpTaskScheduler001
+ * @tc.desc: RecorderProcessMap
+ * @tc.type: FUNC
+ */
+HWTEST_F(FaultloggerdCoredumpTest, CoredumpTaskScheduler001, TestSize.Level2)
+{
+ GTEST_LOG_(INFO) << "CoredumpTaskScheduler001: start.";
+
+ CoredumpTaskScheduler scheduler;
+ auto& sessionManager = CoredumpSessionManager::Instance();
+
+ CreateCoredumpRequest request;
+ request.targetPid = 666;
+ request.endTime = GetAbsTimeMilliSeconds();
+ scheduler.ScheduleCancelTime(request.targetPid, 1 * 1000);
+ sessionManager.CreateSession(request);
+ scheduler.ScheduleCancelTime(request.targetPid, 1 * 1000);
+ CoredumpSession* session = sessionManager.GetSession(request.targetPid);
+ EXPECT_TRUE(session);
+ sleep(2);
+ session = sessionManager.GetSession(request.targetPid);
+ GTEST_LOG_(INFO) << "CoredumpTaskScheduler001: end.";
+
+ scheduler.CancelTimeout(-999);
+}
+} // namespace HiviewDFX
+} // namepsace OHOS
diff --git a/test/unittest/kernel_snapshot/kernel_snapshot_test.cpp b/test/unittest/kernel_snapshot/kernel_snapshot_test.cpp
index b1227faf160535d38106f7f936bb6453de22c1fd..0b77f0256c19f0cbd2f0e63bc24bd009991973de 100644
--- a/test/unittest/kernel_snapshot/kernel_snapshot_test.cpp
+++ b/test/unittest/kernel_snapshot/kernel_snapshot_test.cpp
@@ -576,18 +576,59 @@ HWTEST_F(KernelSnapshotTest, KernelSnapshotTest051, TestSize.Level2)
KernelSnapshotReporter reporter;
CrashMap output;
- auto ret = reporter.ReportCrashNoLogEvent(output);
- ASSERT_FALSE(ret);
-
output[CrashSection::UID] = "123";
output[CrashSection::PID] = "156";
output[CrashSection::TIME_STAMP] = "152451571481";
output[CrashSection::PROCESS_NAME] = "testProcess";
- ret = reporter.ReportCrashNoLogEvent(output);
+ auto ret = reporter.ReportCrashNoLogEvent(output);
ASSERT_TRUE(ret);
GTEST_LOG_(INFO) << "KernelSnapshotTest051: end.";
}
+/**
+ * @tc.name: KernelSnapshotReporter002
+ * @tc.desc: test ReportRawMsg
+ * @tc.type: FUNC
+ */
+HWTEST_F(KernelSnapshotTest, KernelSnapshotReporter002, TestSize.Level2)
+{
+ GTEST_LOG_(INFO) << "KernelSnapshotReporter002: start.";
+ KernelSnapshotReporter reporter;
+
+ std::string snapshot;
+ std::vector outputs;
+ CrashMap output;
+ output[CrashSection::UID] = "";
+ output[CrashSection::PID] = "156";
+ output[CrashSection::TIME_STAMP] = "152451571481";
+ output[CrashSection::PROCESS_NAME] = "testProcess";
+ outputs.push_back(output);
+ reporter.ReportEvents(outputs, snapshot);
+
+ auto ret = reporter.ReportRawMsg(snapshot);
+ EXPECT_FALSE(ret);
+ snapshot = "kernel_snapshot";
+ ret = reporter.ReportRawMsg(snapshot);
+ EXPECT_TRUE(ret);
+ GTEST_LOG_(INFO) << "KernelSnapshotReporter002: end.";
+}
+
+/**
+ * @tc.name: KernelSnapshotReporter003
+ * @tc.desc: test GetSnapshotPid
+ * @tc.type: FUNC
+ */
+HWTEST_F(KernelSnapshotTest, KernelSnapshotReporter003, TestSize.Level2)
+{
+ GTEST_LOG_(INFO) << "KernelSnapshotReporter003: start.";
+ KernelSnapshotReporter reporter;
+ EXPECT_EQ(reporter.GetSnapshotPid("12)"), 0);
+ EXPECT_EQ(reporter.GetSnapshotPid("abcpid=123"), 0);
+ EXPECT_EQ(reporter.GetSnapshotPid("abcpid=abc)"), 0);
+ EXPECT_EQ(reporter.GetSnapshotPid("abcpid=123)"), 123);
+ GTEST_LOG_(INFO) << "KernelSnapshotReporter003: end.";
+}
+
/**
* @tc.name: KernelSnapshotTest052
* @tc.desc: test kernel snapshot trie insert
diff --git a/test/unittest/process_dump/thread_dump_info_test.cpp b/test/unittest/process_dump/thread_dump_info_test.cpp
index a5e09de61efa1dfabf8acdc7aeef161a11f806a3..3aba65807ca2bbb3d99110b88a025fd493db5612 100644
--- a/test/unittest/process_dump/thread_dump_info_test.cpp
+++ b/test/unittest/process_dump/thread_dump_info_test.cpp
@@ -110,7 +110,7 @@ HWTEST_F(ThreadDumpInfoTest, ThreadDumpInfoTest001, TestSize.Level2)
Unwinder unwinder(pid, nsPid, request.type == ProcessDumpType::DUMP_TYPE_CPP_CRASH);
unwinder.EnableFillFrames(false);
KeyThreadDumpInfo dumpInfo;
- EXPECT_GT(dumpInfo.UnwindStack(process, unwinder), 0);
+ EXPECT_GT(dumpInfo.UnwindStack(process, request, unwinder), 0);
dumpInfo.Symbolize(process, unwinder);
dumpInfo.Print(process, request, unwinder);
std::vector keyWords = {
@@ -167,7 +167,7 @@ HWTEST_F(ThreadDumpInfoTest, ThreadDumpInfoTest002, TestSize.Level2)
Unwinder unwinder(pid, nsPid, request.type == ProcessDumpType::DUMP_TYPE_CPP_CRASH);
unwinder.EnableFillFrames(false);
KeyThreadDumpInfo dumpInfo;
- EXPECT_GT(dumpInfo.UnwindStack(process, unwinder), 0);
+ EXPECT_GT(dumpInfo.UnwindStack(process, request, unwinder), 0);
dumpInfo.Symbolize(process, unwinder);
dumpInfo.Print(process, request, unwinder);
std::vector keyWords = {
@@ -215,7 +215,7 @@ HWTEST_F(ThreadDumpInfoTest, ThreadDumpInfoTest003, TestSize.Level2)
Unwinder unwinder(pid, nsPid, request.type == ProcessDumpType::DUMP_TYPE_CPP_CRASH);
unwinder.EnableFillFrames(false);
KeyThreadDumpInfo dumpInfo;
- EXPECT_GT(dumpInfo.UnwindStack(process, unwinder), 0);
+ EXPECT_GT(dumpInfo.UnwindStack(process, request, unwinder), 0);
dumpInfo.Symbolize(process, unwinder);
dumpInfo.Print(process, request, unwinder);
std::vector keyWords = {
@@ -257,7 +257,7 @@ HWTEST_F(ThreadDumpInfoTest, ThreadDumpInfoTest004, TestSize.Level2)
Unwinder unwinder(pid, nsPid, request.type == ProcessDumpType::DUMP_TYPE_CPP_CRASH);
unwinder.EnableFillFrames(false);
OtherThreadDumpInfo dumpInfo;
- EXPECT_GT(dumpInfo.UnwindStack(process, unwinder), 0);
+ EXPECT_GT(dumpInfo.UnwindStack(process, request, unwinder), 0);
dumpInfo.Symbolize(process, unwinder);
dumpInfo.Print(process, request, unwinder);
std::vector keyWords = {
@@ -300,7 +300,7 @@ HWTEST_F(ThreadDumpInfoTest, ThreadDumpInfoTest005, TestSize.Level2)
Unwinder unwinder(pid, nsPid, request.type == ProcessDumpType::DUMP_TYPE_CPP_CRASH);
unwinder.EnableFillFrames(false);
OtherThreadDumpInfo dumpInfo;
- EXPECT_GT(dumpInfo.UnwindStack(process, unwinder), 0);
+ EXPECT_GT(dumpInfo.UnwindStack(process, request, unwinder), 0);
dumpInfo.Symbolize(process, unwinder);
dumpInfo.Print(process, request, unwinder);
std::vector keyWords = {
@@ -345,7 +345,7 @@ HWTEST_F(ThreadDumpInfoTest, ThreadDumpInfoTest006, TestSize.Level2)
std::shared_ptr keyThreadDumpInfo = std::make_shared();
OtherThreadDumpInfo dumpInfo;
dumpInfo.SetDumpInfo(keyThreadDumpInfo);
- EXPECT_GT(dumpInfo.UnwindStack(process, unwinder), threadCount);
+ EXPECT_GT(dumpInfo.UnwindStack(process, request, unwinder), threadCount);
dumpInfo.Symbolize(process, unwinder);
dumpInfo.Print(process, request, unwinder);
std::vector keyWords = {
diff --git a/tools/process_dump/decorative_dump_info.h b/tools/process_dump/decorative_dump_info.h
index 7698320864dc994136e0334d509f5b6da1fb4fe5..fd7737acc65577317af9a8ddc1f93fe473a8ba58 100644
--- a/tools/process_dump/decorative_dump_info.h
+++ b/tools/process_dump/decorative_dump_info.h
@@ -50,10 +50,10 @@ public:
}
}
- int UnwindStack(DfxProcess& process, Unwinder& unwinder) override
+ int UnwindStack(DfxProcess& process, const ProcessDumpRequest& request, Unwinder& unwinder) override
{
if (dumpInfo_ != nullptr) {
- return dumpInfo_->UnwindStack(process, unwinder);
+ return dumpInfo_->UnwindStack(process, request, unwinder);
}
return 0;
}
@@ -113,7 +113,7 @@ private:
class OtherThreadDumpInfo : public DecorativeDumpInfo {
public:
- int UnwindStack(DfxProcess& process, Unwinder& unwinder) override;
+ int UnwindStack(DfxProcess& process, const ProcessDumpRequest& request, Unwinder& unwinder) override;
void Print(DfxProcess& process, const ProcessDumpRequest& request, Unwinder& unwinder) override;
void Symbolize(DfxProcess& process, Unwinder& unwinder) override;
static std::shared_ptr CreateInstance() { return std::make_shared(); }
diff --git a/tools/process_dump/dump_info.h b/tools/process_dump/dump_info.h
index cee0b044f03aad2454c2a5f04832d694934d9bb0..28935c9c14cd80e393fe06b349fc6c6d168c66a3 100644
--- a/tools/process_dump/dump_info.h
+++ b/tools/process_dump/dump_info.h
@@ -31,7 +31,7 @@ public:
virtual ~DumpInfo() {}
virtual void SetDumpInfo(const std::shared_ptr& dumpInfo) {}
virtual void Print(DfxProcess& process, const ProcessDumpRequest& request, Unwinder& unwinder) = 0;
- virtual int UnwindStack(DfxProcess& process, Unwinder& unwinder) = 0;
+ virtual int UnwindStack(DfxProcess& process, const ProcessDumpRequest& request, Unwinder& unwinder) = 0;
virtual void Symbolize(DfxProcess& process, Unwinder& unwinder) = 0;
virtual void GetMemoryValues(std::set& memoryValues) {};
};
diff --git a/tools/process_dump/dump_info_json_formatter.cpp b/tools/process_dump/dump_info_json_formatter.cpp
index cdc130ac7e28d804e6a9366f4f1f813c9cdcdaf4..c59e7f9e2325775e086627a6cadfb2b6e24766aa 100644
--- a/tools/process_dump/dump_info_json_formatter.cpp
+++ b/tools/process_dump/dump_info_json_formatter.cpp
@@ -59,6 +59,7 @@ void DumpInfoJsonFormatter::GetCrashJsonFormatInfo(const ProcessDumpRequest& req
jsonInfo["time"] = request.timeStamp;
jsonInfo["uuid"] = "";
jsonInfo["crash_type"] = "NativeCrash";
+ jsonInfo["process_name"] = process.GetProcessInfo().processName;
jsonInfo["pid"] = process.GetProcessInfo().pid;
jsonInfo["uid"] = process.GetProcessInfo().uid;
jsonInfo["app_running_unique_id"] = request.appRunningId;
diff --git a/tools/process_dump/key_thread_dump_info.cpp b/tools/process_dump/key_thread_dump_info.cpp
index 82b5df759a0669146679f204c63bc950b3727bc4..a76a339a4a1c89f72fa28e762fc0888ad0779b88 100644
--- a/tools/process_dump/key_thread_dump_info.cpp
+++ b/tools/process_dump/key_thread_dump_info.cpp
@@ -107,7 +107,7 @@ void KeyThreadDumpInfo::Print(DfxProcess& process, const ProcessDumpRequest& req
DfxBufferWriter::GetInstance().AppendBriefDumpInfo(dumpInfo);
}
-int KeyThreadDumpInfo::UnwindStack(DfxProcess& process, Unwinder& unwinder)
+int KeyThreadDumpInfo::UnwindStack(DfxProcess& process, const ProcessDumpRequest& request, Unwinder& unwinder)
{
DFXLOGI("unwind key thread dump start");
int result = 0;
@@ -119,7 +119,7 @@ int KeyThreadDumpInfo::UnwindStack(DfxProcess& process, Unwinder& unwinder)
DFXLOGW("vm pid is null, can not unwind key thread!");
return result;
}
-
+ unwinder.SetIsJitCrashFlag(request.type == ProcessDumpType::DUMP_TYPE_CPP_CRASH);
if (process.GetKeyThread()->GetThreadRegs() != nullptr) {
result = GetKeyThreadStack(process, unwinder) ? 1 : 0;
} else {
diff --git a/tools/process_dump/key_thread_dump_info.h b/tools/process_dump/key_thread_dump_info.h
index 4dd716a1cb2e433d5b4df0a46893f5ef98adf3ec..f2ef6f9c988eab4ca1f03e19aecee4494596519d 100644
--- a/tools/process_dump/key_thread_dump_info.h
+++ b/tools/process_dump/key_thread_dump_info.h
@@ -28,7 +28,7 @@ namespace HiviewDFX {
class KeyThreadDumpInfo : public DumpInfo {
public:
void Print(DfxProcess& process, const ProcessDumpRequest& request, Unwinder& unwinder) override;
- int UnwindStack(DfxProcess& process, Unwinder& unwinder) override;
+ int UnwindStack(DfxProcess& process, const ProcessDumpRequest& request, Unwinder& unwinder) override;
void Symbolize(DfxProcess& process, Unwinder& unwinder) override;
static std::shared_ptr CreateInstance() { return std::make_shared(); }
private:
diff --git a/tools/process_dump/lperf/lperf_events.cpp b/tools/process_dump/lperf/lperf_events.cpp
index d10cf989b56f9bc59e542f319f7b9d4ec0741e7f..ea85e4b103f59231e28a6be6295df25132162841 100644
--- a/tools/process_dump/lperf/lperf_events.cpp
+++ b/tools/process_dump/lperf/lperf_events.cpp
@@ -178,7 +178,7 @@ void LperfEvents::GetRecordFieldFromMmap(MmapFd& mmap, void* dest, size_t destSi
if (memcpy_s(dest, destSize, mmap.buf + pos, copySize) != 0) {
DFXLOGE("memcpy_s failed. size %{public}zd", copySize);
}
- if (copySize < size) {
+ if (copySize < size && destSize > copySize) {
size -= copySize;
if (memcpy_s(static_cast(dest) + copySize, destSize - copySize, mmap.buf, size) != 0) {
DFXLOGE("memcpy_s mmap.buf to dest failed. size %{public}zd", size);
diff --git a/tools/process_dump/other_thread_dump_info.cpp b/tools/process_dump/other_thread_dump_info.cpp
index 1bb1802290e5d7fa458505f742d2a008829fb655..1acd9396a3164a63ba6d87abfca536269839de35 100644
--- a/tools/process_dump/other_thread_dump_info.cpp
+++ b/tools/process_dump/other_thread_dump_info.cpp
@@ -23,9 +23,9 @@ namespace OHOS {
namespace HiviewDFX {
REGISTER_DUMP_INFO_CLASS(OtherThreadDumpInfo);
-int OtherThreadDumpInfo::UnwindStack(DfxProcess& process, Unwinder& unwinder)
+int OtherThreadDumpInfo::UnwindStack(DfxProcess& process, const ProcessDumpRequest& request, Unwinder& unwinder)
{
- int unwindSuccessCnt = DecorativeDumpInfo::UnwindStack(process, unwinder);
+ int unwindSuccessCnt = DecorativeDumpInfo::UnwindStack(process, request, unwinder);
DFXLOGI("unwind other thread dump start");
auto pid = process.GetVmPid();
if (pid == 0) {
diff --git a/tools/process_dump/process_dumper.cpp b/tools/process_dump/process_dumper.cpp
index f22eb02cbd3d60492bd8c54246c5b295a53ec392..ab6fdaea172eaccc2eeec62b731935bcaa25b506 100644
--- a/tools/process_dump/process_dumper.cpp
+++ b/tools/process_dump/process_dumper.cpp
@@ -437,7 +437,7 @@ void ProcessDumper::PrintDumpInfo(int& dumpRes)
prevDumpInfo = dumpInfo;
}
if (threadDumpInfo != nullptr) {
- int unwindSuccessCnt = threadDumpInfo->UnwindStack(*process_, *unwinder_);
+ int unwindSuccessCnt = threadDumpInfo->UnwindStack(*process_, request_, *unwinder_);
DFXLOGI("unwind success thread count(%{public}d)", unwindSuccessCnt);
if (unwindSuccessCnt > 0) {
dumpRes = ParseSymbols(threadDumpInfo);