From 04ee6a05837ab6dffb820776cb072509955e8f29 Mon Sep 17 00:00:00 2001 From: yuhailong Date: Sun, 5 Jan 2025 17:26:49 +0800 Subject: [PATCH 01/12] feature: Code optimization, remove common duplicate code. Signed-off-by: yuhailong Change-Id: I846b2da16f4b7f1e41b97957bb35e41749f7944a --- common/cutil/BUILD.gn | 8 + common/cutil/dfx_cutil.c | 54 +++---- common/cutil/dfx_cutil.h | 2 - common/cutil/musl_cutil.h | 145 ------------------ interfaces/innerkits/signal_handler/BUILD.gn | 1 + .../signal_handler/dfx_dumprequest.c | 27 ++-- .../signal_handler/dfx_signal_handler.c | 19 ++- .../signal_handler/include/dfx_dumprequest.h | 2 - 8 files changed, 56 insertions(+), 202 deletions(-) delete mode 100644 common/cutil/musl_cutil.h diff --git a/common/cutil/BUILD.gn b/common/cutil/BUILD.gn index c80d81d56..ec79aac91 100644 --- a/common/cutil/BUILD.gn +++ b/common/cutil/BUILD.gn @@ -39,4 +39,12 @@ if (defined(ohos_lite)) { part_name = "faultloggerd" subsystem_name = "hiviewdfx" } + + ohos_source_set("dfx_cutil_musl") { + sources = [ "dfx_cutil.c" ] + cflags = [ "-DENABLE_MUSL_CUTIL" ] + public_configs = [ ":dfx_cutil_config" ] + part_name = "faultloggerd" + subsystem_name = "hiviewdfx" + } } diff --git a/common/cutil/dfx_cutil.c b/common/cutil/dfx_cutil.c index f89fd75b9..1c70fe9b6 100644 --- a/common/cutil/dfx_cutil.c +++ b/common/cutil/dfx_cutil.c @@ -15,56 +15,44 @@ #include "dfx_cutil.h" +#include #include #include #include #include #include #include +#ifndef ENABLE_MUSL_CUTIL #include +#endif #include #include #include "dfx_define.h" -static const char PID_STR_NAME[] = "Pid:"; +static const char * const PID_STR_NAME = "Pid:"; static bool ReadStringFromFile(const char* path, char* dst, size_t dstSz) { if ((dst == NULL) || (path == NULL) || (dstSz == 0)) { return false; } - char name[NAME_BUF_LEN]; - char nameFilter[NAME_BUF_LEN]; - (void)memset_s(name, sizeof(name), '\0', sizeof(name)); - (void)memset_s(nameFilter, sizeof(nameFilter), '\0', sizeof(nameFilter)); - - int fd = -1; - fd = OHOS_TEMP_FAILURE_RETRY(open(path, O_RDONLY)); + int fd = OHOS_TEMP_FAILURE_RETRY(open(path, O_RDONLY)); if (fd < 0) { return false; } + char name[NAME_BUF_LEN] = {0}; ssize_t nRead = OHOS_TEMP_FAILURE_RETRY(read(fd, name, NAME_BUF_LEN - 1)); if (nRead <= 0) { syscall(SYS_close, fd); return false; } - char* p = name; - int i = 0; - while (*p != '\0') { - if ((*p == '\n') || (i == NAME_BUF_LEN)) { - break; - } - nameFilter[i] = *p; - p++, i++; - } - nameFilter[NAME_BUF_LEN - 1] = '\0'; - - if (memcpy_s(dst, dstSz, nameFilter, strlen(nameFilter) + 1) != 0) { - syscall(SYS_close, fd); - return false; + size_t i = 0; + for (; i < dstSz - 1 && name[i] != '\n' && name[i] != '\0'; i++) { + dst[i] = name[i]; } + dst[i] = '\0'; syscall(SYS_close, fd); return true; @@ -78,7 +66,11 @@ bool GetThreadName(char* buffer, size_t bufferSz) bool GetThreadNameByTid(int32_t tid, char* buffer, size_t bufferSz) { char threadNamePath[NAME_BUF_LEN] = { 0 }; +#ifdef ENABLE_MUSL_CUTIL + if (snprintf(threadNamePath, sizeof(threadNamePath), "/proc/%d/comm", tid) <= 0) { +#else if (snprintf_s(threadNamePath, sizeof(threadNamePath), sizeof(threadNamePath) - 1, "/proc/%d/comm", tid) <= 0) { +#endif return false; } return ReadStringFromFile(threadNamePath, buffer, bufferSz); @@ -97,10 +89,10 @@ pid_t GetRealPid(void) return pid; } - char buf[LINE_BUF_SIZE]; - int i = 0; - char b; - while (1) { + char buf[LINE_BUF_SIZE] = {0}; + int i = 0; + while (true) { + char b = '\0'; ssize_t nRead = OHOS_TEMP_FAILURE_RETRY(read(fd, &b, sizeof(char))); if (nRead <= 0 || b == '\0') { break; @@ -108,11 +100,19 @@ pid_t GetRealPid(void) if (b == '\n' || i == LINE_BUF_SIZE) { if (strncmp(buf, PID_STR_NAME, strlen(PID_STR_NAME)) == 0) { +#ifdef ENABLE_MUSL_CUTIL + (void)sscanf(buf, "%*[^0-9]%d", &pid); +#else (void)sscanf_s(buf, "%*[^0-9]%d", &pid); +#endif break; } - i = 0; +#ifdef ENABLE_MUSL_CUTIL + (void)memset(buf, '\0', sizeof(buf)); +#else (void)memset_s(buf, sizeof(buf), '\0', sizeof(buf)); +#endif + i = 0; continue; } buf[i] = b; diff --git a/common/cutil/dfx_cutil.h b/common/cutil/dfx_cutil.h index 730a05d09..61dcb4fdf 100644 --- a/common/cutil/dfx_cutil.h +++ b/common/cutil/dfx_cutil.h @@ -16,8 +16,6 @@ #define DFX_COMMON_CUTIL_H #include -#include -#include #include #include #include "dfx_define.h" diff --git a/common/cutil/musl_cutil.h b/common/cutil/musl_cutil.h deleted file mode 100644 index 1cc9d07f2..000000000 --- a/common/cutil/musl_cutil.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2022-2023 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 DFX_MUSL_CUTIL_H -#define DFX_MUSL_CUTIL_H - -#include -#include -#include -#include -#include -#include -#include "dfx_define.h" -#include "musl_log.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef ENABLE_MUSL_CUTIL -static const char PID_STR_NAME[] = "Pid:"; - -static bool ReadStringFromFile(const char* path, char* dst, size_t dstSz) -{ - char name[NAME_BUF_LEN]; - char nameFilter[NAME_BUF_LEN]; - memset(name, 0, sizeof(name)); - memset(nameFilter, 0, sizeof(nameFilter)); - - int fd = -1; - fd = OHOS_TEMP_FAILURE_RETRY(open(path, O_RDONLY)); - if (fd < 0) { - return false; - } - - int nRead = OHOS_TEMP_FAILURE_RETRY(read(fd, name, NAME_BUF_LEN -1)); - if (nRead == -1) { - close(fd); - return false; - } - - char* p = name; - int i = 0; - while (*p != '\0') { - if ((*p == '\n') || (i == NAME_BUF_LEN)) { - break; - } - nameFilter[i] = *p; - p++, i++; - } - nameFilter[NAME_BUF_LEN - 1] = '\0'; - - size_t cpyLen = strlen(nameFilter) + 1; - if (cpyLen > dstSz) { - cpyLen = dstSz; - } - memcpy(dst, nameFilter, cpyLen); - close(fd); - return true; -} - -bool GetThreadName(char* buffer, size_t bufferSz) -{ - return ReadStringFromFile(PROC_SELF_COMM_PATH, buffer, bufferSz); -} - -bool GetThreadNameByTid(int32_t tid, char* buffer, size_t bufferSz) -{ - char threadNamePath[NAME_BUF_LEN] = { 0 }; - if (snprintf(threadNamePath, sizeof(threadNamePath), "/proc/%d/comm", tid) <= 0) { - return false; - } - return ReadStringFromFile(threadNamePath, buffer, bufferSz); -} - -bool GetProcessName(char* buffer, size_t bufferSz) -{ - return ReadStringFromFile(PROC_SELF_CMDLINE_PATH, buffer, bufferSz); -} - -pid_t GetRealPid(void) -{ - pid_t pid = syscall(SYS_getpid); - int fd = OHOS_TEMP_FAILURE_RETRY(open(PROC_SELF_STATUS_PATH, O_RDONLY)); - if (fd < 0) { - DFXLOGE("GetRealPid:: open failed! pid:(%{public}ld), errno:(%{public}d).", pid, errno); - return pid; - } - - char buf[LINE_BUF_SIZE] = {0}; - int i = 0; - char b; - ssize_t nRead = 0; - while (1) { - nRead = OHOS_TEMP_FAILURE_RETRY(read(fd, &b, sizeof(char))); - if (nRead <= 0 || b == '\0') { - DFXLOGE("GetRealPid:: read failed! pid:(%{public}ld), errno:(%{public}d), " \ - "nRead(%{public}zd), readchar(%{public}02X).", - pid, errno, nRead, b); - break; - } - - if (b == '\n' || i == LINE_BUF_SIZE) { - if (strncmp(buf, PID_STR_NAME, strlen(PID_STR_NAME)) != 0) { - i = 0; - (void)memset(buf, '\0', sizeof(buf)); - continue; - } - if (sscanf(buf, "%*[^0-9]%d", &pid) < 0) { - DFXLOGE("GetRealPid:: sscanf failed! pid:(%{public}ld), errno:(%{public}d), buf(%{public}s).", - pid, errno, buf); - } - break; - } - buf[i] = b; - i++; - } - close(fd); - return pid; -} - -uint64_t GetTimeMilliseconds(void) -{ - struct timespec ts; - (void)clock_gettime(CLOCK_REALTIME, &ts); - return ((uint64_t)ts.tv_sec * NUMBER_ONE_THOUSAND) + // 1000 : second to millisecond convert ratio - (((uint64_t)ts.tv_nsec) / NUMBER_ONE_MILLION); // 1000000 : nanosecond to millisecond convert ratio -} - -#endif -#ifdef __cplusplus -} -#endif -#endif \ No newline at end of file diff --git a/interfaces/innerkits/signal_handler/BUILD.gn b/interfaces/innerkits/signal_handler/BUILD.gn index cd287677e..a3c243942 100644 --- a/interfaces/innerkits/signal_handler/BUILD.gn +++ b/interfaces/innerkits/signal_handler/BUILD.gn @@ -37,6 +37,7 @@ template("lib_dfxsignalhandler_template") { "dfx_signalhandler_exception.c", "musl_log.c", ] + deps = [ "$faultloggerd_path/common/cutil:dfx_cutil_musl" ] configs -= __inherited_configs configs += __static_sighandler_config configs += [ "//build/config/compiler:compiler" ] diff --git a/interfaces/innerkits/signal_handler/dfx_dumprequest.c b/interfaces/innerkits/signal_handler/dfx_dumprequest.c index 06068ba6b..a4a3bbb8c 100644 --- a/interfaces/innerkits/signal_handler/dfx_dumprequest.c +++ b/interfaces/innerkits/signal_handler/dfx_dumprequest.c @@ -18,14 +18,20 @@ #include "dfx_dumprequest.h" +#include #include #include #include #include +#include #include #include +#include #include #include +#include +#include +#include #include #include #include @@ -34,25 +40,14 @@ #include #include #include -#include -#include +#include +#include + +#include "dfx_cutil.h" #include "dfx_define.h" #include "dfx_dump_request.h" -#include "dfx_signalhandler_exception.h" -#include "errno.h" -#include "linux/capability.h" -#include "stdbool.h" -#include "string.h" -#ifndef DFX_SIGNAL_LIBC -#include -#include "dfx_cutil.h" #include "dfx_log.h" -#else -#include "musl_cutil.h" -#include "musl_log.h" -#endif - -#include "info/fatal_message.h" +#include "dfx_signalhandler_exception.h" #ifdef LOG_DOMAIN #undef LOG_DOMAIN diff --git a/interfaces/innerkits/signal_handler/dfx_signal_handler.c b/interfaces/innerkits/signal_handler/dfx_signal_handler.c index 66c4cdd22..f352907ef 100644 --- a/interfaces/innerkits/signal_handler/dfx_signal_handler.c +++ b/interfaces/innerkits/signal_handler/dfx_signal_handler.c @@ -18,14 +18,19 @@ #define _GNU_SOURCE 1 #endif +#include #include #include #include #include #include #include +#include #include #include +#include +#include +#include #include #include #include @@ -34,29 +39,23 @@ #include #include #include -#include -#include +#include +#include + +#include "dfx_cutil.h" #include "dfx_define.h" #include "dfx_dump_request.h" #include "dfx_signalhandler_exception.h" -#include "errno.h" -#include "linux/capability.h" -#include "stdbool.h" -#include "string.h" #ifndef DFX_SIGNAL_LIBC #include -#include "dfx_cutil.h" #include "dfx_log.h" #else -#include "musl_cutil.h" #include "musl_log.h" #endif - #ifdef is_ohos_lite #include "dfx_dumprequest.h" #endif -#include "info/fatal_message.h" #ifdef LOG_DOMAIN #undef LOG_DOMAIN diff --git a/interfaces/innerkits/signal_handler/include/dfx_dumprequest.h b/interfaces/innerkits/signal_handler/include/dfx_dumprequest.h index a6fe61947..2b1fe5323 100644 --- a/interfaces/innerkits/signal_handler/include/dfx_dumprequest.h +++ b/interfaces/innerkits/signal_handler/include/dfx_dumprequest.h @@ -15,8 +15,6 @@ #ifndef DFX_DUMPREQUEST_H #define DFX_DUMPREQUEST_H -#include - #include "dfx_dump_request.h" #ifdef __cplusplus -- Gitee From 4ec9dcd44ade95784b47b155f063712b58da2570 Mon Sep 17 00:00:00 2001 From: yuhailong Date: Sun, 5 Jan 2025 19:39:51 +0800 Subject: [PATCH 02/12] feat:del unusing string_view Signed-off-by: yuhailong Change-Id: Iade8560aaf2b5c0301b5493de8acc2acacfd1b54 --- common/dfxlog/dfx_log.h | 3 +- common/dfxutil/dfx_util.cpp | 28 +++---- common/dfxutil/dfx_util.h | 2 +- common/dfxutil/elapsed_time.h | 6 +- common/dfxutil/file_util.h | 1 + common/dfxutil/string_view_util.h | 84 ------------------- .../localhandler/dfx_signal_local_handler.cpp | 16 ++-- interfaces/common/cpp_define.h | 26 ------ .../innerkits/unwinder/include/dfx_symbol.h | 38 ++++----- 9 files changed, 46 insertions(+), 158 deletions(-) delete mode 100644 common/dfxutil/string_view_util.h delete mode 100644 interfaces/common/cpp_define.h diff --git a/common/dfxlog/dfx_log.h b/common/dfxlog/dfx_log.h index af58c5d88..3fea0fa2f 100644 --- a/common/dfxlog/dfx_log.h +++ b/common/dfxlog/dfx_log.h @@ -32,7 +32,6 @@ extern "C" { #ifndef DFX_NO_PRINT_LOG #ifdef DFX_LOG_HILOG_BASE -// replace the old interface, and delete the old interface after the replacement is complete #ifdef DFX_LOG_UNWIND #define DFXLOGD(fmt, ...) HILOG_BASE_DEBUG(LOG_CORE, fmt, ##__VA_ARGS__) #else @@ -58,7 +57,7 @@ extern "C" { #endif #else -// replace the old interface, and delete the old interface after the replacement is complete + #define DFXLOGD(fmt, ...) HILOG_DEBUG(LOG_CORE, fmt, ##__VA_ARGS__) #define DFXLOGI(fmt, ...) HILOG_INFO(LOG_CORE, fmt, ##__VA_ARGS__) #define DFXLOGW(fmt, ...) HILOG_WARN(LOG_CORE, fmt, ##__VA_ARGS__) diff --git a/common/dfxutil/dfx_util.cpp b/common/dfxutil/dfx_util.cpp index 7349a029d..4ce13a610 100644 --- a/common/dfxutil/dfx_util.cpp +++ b/common/dfxutil/dfx_util.cpp @@ -124,7 +124,7 @@ std::string GetCurrentTimeStr(uint64_t current) if (ret <= 0) { return "invalid timestamp\n"; } - return std::string(millBuf, strlen(millBuf)); + return millBuf; } bool ReadDirFiles(const std::string& path, std::vector& files) @@ -143,16 +143,16 @@ bool ReadDirFiles(const std::string& path, std::vector& files) files.emplace_back(std::string(ent->d_name)); } (void)closedir(dir); - return (files.size() > 0); + return !files.empty(); } bool VerifyFilePath(const std::string& filePath, const std::vector& validPaths) { - if (validPaths.size() == 0) { + if (validPaths.empty()) { return true; } - for (auto validPath : validPaths) { + for (const auto &validPath : validPaths) { if (filePath.find(validPath) == 0) { return true; } @@ -173,16 +173,16 @@ void ParseSiValue(siginfo_t& si, uint64_t& endTime, int& tid) } #endif -off_t GetFileSize(const int& fd) +off_t GetFileSize(int fd) { - off_t fileSize = 0; - if (fd >= 0) { - struct stat fileStat; - if (fstat(fd, &fileStat) == 0) { - fileSize = fileStat.st_size; - } + if (fd < 0) { + return 0; + } + struct stat fileStat; + if (fstat(fd, &fileStat) == 0) { + return fileStat.st_size; } - return fileSize; + return 0; } bool ReadFdToString(int fd, std::string& content) @@ -193,9 +193,9 @@ bool ReadFdToString(int fd, std::string& content) content.reserve(sb.st_size); } - char buf[BUFSIZ] __attribute__((__uninitialized__)); + char buf[BUFSIZ] = {0}; ssize_t n; - while ((n = OHOS_TEMP_FAILURE_RETRY(read(fd, &buf[0], sizeof(buf)))) > 0) { + while ((n = OHOS_TEMP_FAILURE_RETRY(read(fd, &buf, sizeof(buf)))) > 0) { content.append(buf, n); } return (n == 0); diff --git a/common/dfxutil/dfx_util.h b/common/dfxutil/dfx_util.h index cc466b052..5fbd4270f 100644 --- a/common/dfxutil/dfx_util.h +++ b/common/dfxutil/dfx_util.h @@ -37,7 +37,7 @@ AT_SYMBOL_HIDDEN bool ReadDirFiles(const std::string& path, std::vector& validPaths); AT_SYMBOL_HIDDEN void ParseSiValue(siginfo_t& si, uint64_t& endTime, int& tid); #endif -AT_SYMBOL_HIDDEN off_t GetFileSize(const int& fd); +AT_SYMBOL_HIDDEN off_t GetFileSize(int fd); AT_SYMBOL_HIDDEN bool ReadFdToString(int fd, std::string& content); AT_SYMBOL_HIDDEN void CloseFd(int& fd); AT_SYMBOL_HIDDEN uintptr_t StripPac(uintptr_t inAddr, uintptr_t pacMask); diff --git a/common/dfxutil/elapsed_time.h b/common/dfxutil/elapsed_time.h index 6b683582d..c0b0da161 100644 --- a/common/dfxutil/elapsed_time.h +++ b/common/dfxutil/elapsed_time.h @@ -25,7 +25,7 @@ public: ElapsedTime() { begin_ = std::chrono::high_resolution_clock::now(); - }; + } ElapsedTime(std::string printContent, time_t limitCostMilliseconds) : limitCostMilliseconds_(limitCostMilliseconds), printContent_(std::move(printContent)) @@ -46,13 +46,13 @@ public: void Reset() { begin_ = std::chrono::high_resolution_clock::now(); - }; + } template time_t Elapsed() const { return std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - begin_).count(); - }; + } private: std::chrono::time_point begin_; diff --git a/common/dfxutil/file_util.h b/common/dfxutil/file_util.h index f07c4ffdf..b3c29b761 100644 --- a/common/dfxutil/file_util.h +++ b/common/dfxutil/file_util.h @@ -40,6 +40,7 @@ static bool LoadStringFromFile(const std::string& filePath, std::string& content } content.clear(); + content.reserve(fileLength); file.seekg(0, std::ios::beg); std::copy(std::istreambuf_iterator(file), std::istreambuf_iterator(), std::back_inserter(content)); return true; diff --git a/common/dfxutil/string_view_util.h b/common/dfxutil/string_view_util.h deleted file mode 100644 index b44a59ea7..000000000 --- a/common/dfxutil/string_view_util.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2023 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 STRING_VIEW_UTIL_H -#define STRING_VIEW_UTIL_H - -#include -#include -#include -#include -#include -#include "cpp_define.h" - -namespace OHOS { -namespace HiviewDFX { -class StringViewHold { -public: - static StringViewHold &Get() - { - static StringViewHold instance; - return instance; - } - - const char* Hold(STRING_VIEW view) - { - pthread_spin_lock(&spin_lock_); - if (view.size() == 0) { - pthread_spin_unlock(&spin_lock_); - return ""; - } - - char *p = new (std::nothrow) char[view.size() + 1]; - if (p == nullptr) { - pthread_spin_unlock(&spin_lock_); - return ""; - } - if (memset_s(p, view.size() + 1, '\0', view.size() + 1) != 0) { - pthread_spin_unlock(&spin_lock_); - return ""; - } - std::copy(view.data(), view.data() + view.size(), p); - views_.emplace_back(p); - pthread_spin_unlock(&spin_lock_); - return p; - } - - // only use in UT - void Clean() - { - pthread_spin_lock(&spin_lock_); - for (auto &p : views_) { - delete[] p; - } - views_.clear(); - pthread_spin_unlock(&spin_lock_); - } -private: - StringViewHold() - { - pthread_spin_init(&spin_lock_, PTHREAD_PROCESS_PRIVATE); - } - ~StringViewHold() - { - Clean(); - pthread_spin_destroy(&spin_lock_); - } - - std::vector views_; - pthread_spinlock_t spin_lock_; -}; -} // namespace HiviewDFX -} // namespace OHOS -#endif \ No newline at end of file diff --git a/frameworks/localhandler/dfx_signal_local_handler.cpp b/frameworks/localhandler/dfx_signal_local_handler.cpp index eb8312a2c..d10f35bb6 100644 --- a/frameworks/localhandler/dfx_signal_local_handler.cpp +++ b/frameworks/localhandler/dfx_signal_local_handler.cpp @@ -43,18 +43,21 @@ #define LOG_TAG "DfxSignalLocalHandler" #endif -#define LOCAL_HANDLER_STACK_SIZE (128 * 1024) // 128K +constexpr uint32_t LOCAL_HANDLER_STACK_SIZE = 128 * 1024; // 128K constexpr uint32_t FAULTLOGGERD_UID = 1202; static CrashFdFunc g_crashFdFn = nullptr; +#if !defined(__aarch64__) && !defined(__loongarch_lp64) static void *g_reservedChildStack = nullptr; +#endif static struct ProcessDumpRequest g_request; static pthread_mutex_t g_signalHandlerMutex = PTHREAD_MUTEX_INITIALIZER; -static int g_platformSignals[] = { +static constexpr int CATCHER_STACK_SIGNALS[] = { SIGABRT, SIGBUS, SIGILL, SIGSEGV, }; +#if !defined(__aarch64__) && !defined(__loongarch_lp64) static void ReserveChildThreadSignalStack(void) { // reserve stack for fork @@ -67,6 +70,7 @@ static void ReserveChildThreadSignalStack(void) g_reservedChildStack = static_cast(static_cast(g_reservedChildStack) + LOCAL_HANDLER_STACK_SIZE - 1); } +#endif AT_UNUSED static void FutexWait(volatile void* ftx, int value) { @@ -115,7 +119,7 @@ void DFX_SignalLocalHandler(int sig, siginfo_t *si, void *context) if (ret < 0) { DFXLOGE("memcpy_s context fail, ret=%{public}d", ret); } -#if defined(__aarch64__) || defined(__loongarch_lp64) +#if defined(__aarch64__) || defined(__loongarch_lp64) DoCrashHandler(NULL); #else int pseudothreadTid = -1; @@ -143,7 +147,9 @@ void DFX_GetCrashFdFunc(CrashFdFunc fn) void DFX_InstallLocalSignalHandler(void) { +#if !defined(__aarch64__) && !defined(__loongarch_lp64) ReserveChildThreadSignalStack(); +#endif sigset_t set; sigemptyset(&set); @@ -153,10 +159,8 @@ void DFX_InstallLocalSignalHandler(void) action.sa_sigaction = DFX_SignalLocalHandler; action.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK; - for (size_t i = 0; i < sizeof(g_platformSignals) / sizeof(g_platformSignals[0]); i++) { - int32_t sig = g_platformSignals[i]; + for (auto sig : CATCHER_STACK_SIGNALS) { remove_all_special_handler(sig); - sigaddset(&set, sig); if (sigaction(sig, &action, nullptr) != 0) { DFXLOGE("Failed to register signal(%{public}d)", sig); diff --git a/interfaces/common/cpp_define.h b/interfaces/common/cpp_define.h deleted file mode 100644 index 8bb4ea529..000000000 --- a/interfaces/common/cpp_define.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2021-2024 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 CPP_DEFINE_H -#define CPP_DEFINE_H - -#ifndef is_ohos_lite -#define STRING_VIEW std::string_view -#else -#include -#define STRING_VIEW std::string -#endif - -#endif diff --git a/interfaces/innerkits/unwinder/include/dfx_symbol.h b/interfaces/innerkits/unwinder/include/dfx_symbol.h index 5b724c235..293e656c1 100644 --- a/interfaces/innerkits/unwinder/include/dfx_symbol.h +++ b/interfaces/innerkits/unwinder/include/dfx_symbol.h @@ -20,7 +20,6 @@ #include #include #include -#include "string_view_util.h" namespace OHOS { namespace HiviewDFX { @@ -35,39 +34,34 @@ struct DfxSymbol { int32_t symbolFileIndex_ = -1; // symbols file index, used to report protobuf file int32_t index_ = -1; uint32_t symbolId_ = 0; // for frame map id - STRING_VIEW name_ = ""; - STRING_VIEW demangle_ = ""; // demangle string - STRING_VIEW module_ = ""; // maybe empty - STRING_VIEW comm_ = ""; // we need a comm name like comm@0x1234 - STRING_VIEW symbolName_ = ""; - mutable STRING_VIEW unknow_ = ""; + std::string name_ = ""; + std::string demangle_ = ""; // demangle string + std::string module_ = ""; // maybe empty + std::string comm_ = ""; // we need a comm name like comm@0x1234 + std::string symbolName_ = ""; + mutable std::string unknow_ = ""; uint64_t offset_ = 0; mutable bool matched_ = false; // if some callstack match this int32_t hit_ = 0; // elf use this - DfxSymbol(uint64_t vaddr, uint64_t size, const std::string &name, const std::string &demangle, - const std::string module) + DfxSymbol(uint64_t vaddr, uint64_t size, std::string name, std::string demangle, std::string module) : funcVaddr_(vaddr), fileVaddr_(vaddr), size_(size), - name_(StringViewHold::Get().Hold(name)), - demangle_(StringViewHold::Get().Hold(demangle)), - module_(StringViewHold::Get().Hold(module)) {} - DfxSymbol(uint64_t vaddr, uint64_t size, const std::string &name, const std::string &module) + name_(std::move(name)), + demangle_(std::move(demangle)), + module_(std::move(module)) {} + DfxSymbol(uint64_t vaddr, uint64_t size, std::string name, std::string module) : DfxSymbol(vaddr, size, name, name, module) {} // kernel use this - DfxSymbol(uint64_t vaddr, const std::string &name, const std::string &module) + DfxSymbol(uint64_t vaddr, std::string name, std::string module) : DfxSymbol(vaddr, 0, name, name, module) {} // Symbolic use this - DfxSymbol(uint64_t taskVaddr = 0, const std::string &comm = "") - : taskVaddr_(taskVaddr), comm_(comm) {} - - DfxSymbol(const DfxSymbol &other) = default; - - DfxSymbol& operator=(const DfxSymbol& other) = default; + DfxSymbol(uint64_t taskVaddr = 0, std::string comm = "") + : taskVaddr_(taskVaddr), comm_(std::move(comm)) {} inline bool Equal(const DfxSymbol &b) const { @@ -104,7 +98,7 @@ struct DfxSymbol { offset_ = fileVaddr_ - funcVaddr_; } - STRING_VIEW GetName() const + const std::string& GetName() const { if (!demangle_.empty()) { return demangle_; @@ -119,7 +113,7 @@ struct DfxSymbol { } else { ss << comm_ << "@0x" << std::hex << taskVaddr_; } - unknow_ = StringViewHold::Get().Hold(ss.str()); + unknow_ = ss.str(); } return unknow_; } -- Gitee From e725ab1249484d8e9aeacb9236abb00f57b54fe1 Mon Sep 17 00:00:00 2001 From: yuhailong Date: Sun, 5 Jan 2025 20:54:40 +0800 Subject: [PATCH 03/12] feat:del dup code Signed-off-by: yuhailong Change-Id: I04e738a768f454bf4c9082a70daad69d2cf98e1c Signed-off-by: yuhailong --- interfaces/common/dfx_define.h | 14 ++-- interfaces/common/dfx_dump_res.h | 55 ++++++++------- interfaces/common/dfx_errors.h | 32 ++++----- interfaces/common/dfx_exception.h | 68 +++++++++++-------- .../crash_exception/crash_exception.cpp | 12 ---- .../signal_handler/dfx_dumprequest.c | 12 ---- .../signal_handler/dfx_signal_handler.c | 12 ---- interfaces/innerkits/unwinder/BUILD.gn | 2 - .../innerkits/unwinder/include/arm_exidx.h | 4 +- .../unwinder/include/dwarf_section.h | 4 +- test/benchmarktest/unwinder/BUILD.gn | 1 - test/unittest/unwind/BUILD.gn | 1 - 12 files changed, 91 insertions(+), 126 deletions(-) diff --git a/interfaces/common/dfx_define.h b/interfaces/common/dfx_define.h index 7fe022a61..0bd1746d2 100644 --- a/interfaces/common/dfx_define.h +++ b/interfaces/common/dfx_define.h @@ -86,13 +86,13 @@ static const char* const PROC_SELF_EXE_PATH = "/proc/self/exe"; #define FALLTHROUGH_INTENDED [[clang::fallthrough]] // NOLINT #endif -#define OHOS_TEMP_FAILURE_RETRY(exp) \ - ({ \ - long int _rc; \ - do { \ - _rc = (long int)(exp); \ - } while ((_rc == -1) && (errno == EINTR)); \ - _rc; \ +#define OHOS_TEMP_FAILURE_RETRY(exp) \ + ({ \ + long int _rc; \ + do { \ + _rc = (long int)(exp); \ + } while ((_rc == -1) && (errno == EINTR)); \ + _rc; \ }) #if defined(__LP64__) diff --git a/interfaces/common/dfx_dump_res.h b/interfaces/common/dfx_dump_res.h index 6eb750222..b265c0788 100644 --- a/interfaces/common/dfx_dump_res.h +++ b/interfaces/common/dfx_dump_res.h @@ -62,36 +62,41 @@ enum DumpErrorCode : int32_t { class DfxDumpRes { public: - inline static std::string ToString(const int32_t& res) + inline static std::string ToString(int32_t res) { - std::string ss = std::to_string(res) + " ( " + GetResStr(res) + " )"; - return ss; + return std::to_string(res) + " ( " + GetResStr(res) + " )"; } private: - inline static const char* GetResStr(const int32_t& res) + struct DumpErrInfo { + int32_t errCode; + const char *info; + }; + inline static const char* GetResStr(int32_t res) { - const char *cp; - switch (res) { - case DUMP_ESUCCESS: cp = "no error"; break; - case DUMP_EREADREQUEST: cp = "read dump request error"; break; - case DUMP_EGETPPID: cp = "ppid is crashed before unwind"; break; - case DUMP_EATTACH: cp = "ptrace attach thread failed"; break; - case DUMP_EGETFD: cp = "get fd error"; break; - case DUMP_ENOMEM: cp = "out of memory"; break; - case DUMP_EBADREG: cp = "bad register number"; break; - case DUMP_EREADONLYREG: cp = "attempt to write read-only register"; break; - case DUMP_ESTOPUNWIND: cp = "stop unwinding"; break; - case DUMP_EINVALIDIP: cp = "invalid IP"; break; - case DUMP_EBADFRAME: cp = "bad frame"; break; - case DUMP_EINVAL: cp = "unsupported operation or bad value"; break; - case DUMP_EBADVERSION: cp = "unwind info has unsupported version"; break; - case DUMP_ENOINFO: cp = "no unwind info found"; break; - case DUMP_ENOMAP: cp = "mapinfo is not exist"; break; - case DUMP_EREADPID: cp = "fail to read real pid"; break; - default: cp = "invalid error code"; break; - } - return cp; + const DumpErrInfo errInfos[] = { + { DUMP_ESUCCESS, "no error" }, + { DUMP_EREADREQUEST, "read dump request error" }, + { DUMP_EGETPPID, "ppid is crashed before unwind" }, + { DUMP_EATTACH, "ptrace attach thread failed" }, + { DUMP_EGETFD, "get fd error" }, + { DUMP_ENOMEM, "out of memory" }, + { DUMP_EBADREG, "bad register number" }, + { DUMP_EREADONLYREG, "attempt to write read-only register" }, + { DUMP_ESTOPUNWIND, "stop unwinding" }, + { DUMP_EINVALIDIP, "invalid IP" }, + { DUMP_EBADFRAME, "bad frame" }, + { DUMP_EINVAL, "unsupported operation or bad value" }, + { DUMP_EBADVERSION, "unwind info has unsupported version" }, + { DUMP_ENOINFO, "no unwind info found" }, + { DUMP_ENOMAP, "mapinfo is not exist" }, + { DUMP_EREADPID, "fail to read real pid" }, + }; + + auto iter = std::find_if(std::begin(errInfos), std::end(errInfos), [res](const auto &ele) { + return ele.errCode == res; + }); + return iter != std::end(errInfos) ? iter->info : "invalid error code"; } }; } // namespace HiviewDFX diff --git a/interfaces/common/dfx_errors.h b/interfaces/common/dfx_errors.h index 758f33042..8c386d2d7 100644 --- a/interfaces/common/dfx_errors.h +++ b/interfaces/common/dfx_errors.h @@ -88,37 +88,29 @@ enum UnwindErrorCode : uint16_t { /** * @brief Unwind error data */ -struct UnwindErrorData { - inline const uint16_t& GetCode() { return code_; } - inline const uint64_t& GetAddr() { return addr_; } +class UnwindErrorData { +public: + inline uint16_t GetCode() { return code_; } + inline uint64_t GetAddr() { return addr_; } - template - inline void SetAddrAndCode([[maybe_unused]] T1 addr, [[maybe_unused]] T2 code) + inline void SetAddrAndCode(uintptr_t addr, uint16_t code) { -#ifdef DFX_UNWIND_ERROR - addr_ = static_cast(addr); - code_ = static_cast(code); -#endif + addr_ = addr; + code_ = code; } - template - inline void SetCode([[maybe_unused]] T code) + inline void SetCode(uint16_t code) { -#ifdef DFX_UNWIND_ERROR - code_ = static_cast(code); -#endif + code_ = code; } - template - inline void SetAddr([[maybe_unused]] T addr) + inline void SetAddr(uintptr_t addr) { -#ifdef DFX_UNWIND_ERROR - addr_ = static_cast(addr); -#endif + addr_ = addr; } private: uint16_t code_ = 0; - uint64_t addr_ = 0; + uintptr_t addr_ = 0; }; } // namespace HiviewDFX } // namespace OHOS diff --git a/interfaces/common/dfx_exception.h b/interfaces/common/dfx_exception.h index 4ca27bfcc..61b161bd7 100644 --- a/interfaces/common/dfx_exception.h +++ b/interfaces/common/dfx_exception.h @@ -69,36 +69,44 @@ struct ErrCodeToStr { const char* str; }; -static struct ErrCodeToStr g_crashExceptionMap[] = { - {CRASH_SIGNAL_EMASKED, "Signal has been masked." }, - {CRASH_SIGNAL_EFORK, "Failed to fork child process." }, - {CRASH_SIGNAL_ECLONE, "Failed to clone thread of recycle dump process." }, - {CRASH_SIGNAL_ESETSTATE, "Failed to set dump state." }, - {CRASH_SIGNAL_EINHERITCAP, "Failed to inherit capabilities." }, - {CRASH_SIGNAL_EEXECL, "Failed to execl processdump." }, - {CRASH_SIGNAL_EWAITEXIT, "Failed to wait vm process exit." }, - {CRASH_SIGNAL_EREADPIPE, "Failed to read pipe due to timeout."}, - {CRASH_SIGNAL_ECREATEPIPE, "Failed to init create pipe."}, - {CRASH_SIGNAL_EDUMPREQUEST, "Failed to find symbol to dump request."}, - {CRASH_DUMP_EREADREQ, "Failed to read dump request." }, - {CRASH_DUMP_EPARENTPID, "Failed to check parent pid." }, - {CRASH_DUMP_EATTACH, "Failed to attach target process." }, - {CRASH_DUMP_EWRITEFD, "Failed to request writen fd." }, - {CRASH_DUMP_EKILLED, "Tagert process has been killed." }, - {CRASH_DUMP_EREADPID, "Failed to read real pid."}, - {CRASH_UNWIND_ECONTEXT, "Unwind context illegal." }, - {CRASH_UNWIND_EFRAME, "Failed to step ark js frame." }, - {CRASH_UNWIND_ESTACK, "Stack corruption." }, - {CRASH_LOG_ESTACKLOS, "Crash thread stack not found." }, - {CRASH_LOG_ECHILDSTACK, "Child thread stack not found." }, - {CRASH_LOG_EREGLOS, "Registers not found." }, - {CRASH_LOG_EMEMLOS, "Memory not found." }, - {CRASH_LOG_ESTACKMEMLOS, "Fault stack not found." }, - {CRASH_LOG_EMAPLOS, "Maps not found." }, - {CRASH_LOG_EHILOGLOS, "Hilog not found." }, - {CRASH_LOG_ESUMMARYLOS, "Fault Summary not found."}, - {CRASH_UNKNOWN, "Unknown reason." }, -}; +static inline const char* GetCrashDescription(int32_t errCode) +{ + const struct ErrCodeToStr crashExceptions[] = { + {CRASH_SIGNAL_EMASKED, "Signal has been masked." }, + {CRASH_SIGNAL_EFORK, "Failed to fork child process." }, + {CRASH_SIGNAL_ECLONE, "Failed to clone thread of recycle dump process." }, + {CRASH_SIGNAL_ESETSTATE, "Failed to set dump state." }, + {CRASH_SIGNAL_EINHERITCAP, "Failed to inherit capabilities." }, + {CRASH_SIGNAL_EEXECL, "Failed to execl processdump." }, + {CRASH_SIGNAL_EWAITEXIT, "Failed to wait vm process exit." }, + {CRASH_SIGNAL_EREADPIPE, "Failed to read pipe due to timeout."}, + {CRASH_SIGNAL_ECREATEPIPE, "Failed to init create pipe."}, + {CRASH_SIGNAL_EDUMPREQUEST, "Failed to find symbol to dump request."}, + {CRASH_DUMP_EREADREQ, "Failed to read dump request." }, + {CRASH_DUMP_EPARENTPID, "Failed to check parent pid." }, + {CRASH_DUMP_EATTACH, "Failed to attach target process." }, + {CRASH_DUMP_EWRITEFD, "Failed to request writen fd." }, + {CRASH_DUMP_EKILLED, "Tagert process has been killed." }, + {CRASH_DUMP_EREADPID, "Failed to read real pid."}, + {CRASH_UNWIND_ECONTEXT, "Unwind context illegal." }, + {CRASH_UNWIND_EFRAME, "Failed to step ark js frame." }, + {CRASH_UNWIND_ESTACK, "Stack corruption." }, + {CRASH_LOG_ESTACKLOS, "Crash thread stack not found." }, + {CRASH_LOG_ECHILDSTACK, "Child thread stack not found." }, + {CRASH_LOG_EREGLOS, "Registers not found." }, + {CRASH_LOG_EMEMLOS, "Memory not found." }, + {CRASH_LOG_ESTACKMEMLOS, "Fault stack not found." }, + {CRASH_LOG_EMAPLOS, "Maps not found." }, + {CRASH_LOG_EHILOGLOS, "Hilog not found." }, + {CRASH_LOG_ESUMMARYLOS, "Fault Summary not found."}, + }; + for (int i = 0; i < sizeof(crashExceptions) / sizeof(crashExceptions[0]); i++) { + if (errCode == crashExceptions[i].errCode) { + return crashExceptions[i].str; + } + } + return "Unknown reason."; +} /** * @brief Process crash dump exception description diff --git a/interfaces/innerkits/crash_exception/crash_exception.cpp b/interfaces/innerkits/crash_exception/crash_exception.cpp index ab563aec7..61f2a98e1 100644 --- a/interfaces/innerkits/crash_exception/crash_exception.cpp +++ b/interfaces/innerkits/crash_exception/crash_exception.cpp @@ -50,18 +50,6 @@ void SetCrashProcInfo(std::string& name, int32_t pid, int32_t uid) g_crashProcessUid = uid; } -static const char* GetCrashDescription(const int32_t errCode) -{ - size_t i; - - for (i = 0; i < sizeof(g_crashExceptionMap) / sizeof(g_crashExceptionMap[0]); i++) { - if (errCode == g_crashExceptionMap[i].errCode) { - return g_crashExceptionMap[i].str; - } - } - return g_crashExceptionMap[i - 1].str; /* the end of map is "unknown reason" */ -} - void ReportCrashException(const char* pName, int32_t pid, int32_t uid, int32_t errCode) { if (pName == nullptr || strnlen(pName, NAME_BUF_LEN) == NAME_BUF_LEN) { diff --git a/interfaces/innerkits/signal_handler/dfx_dumprequest.c b/interfaces/innerkits/signal_handler/dfx_dumprequest.c index a4a3bbb8c..4678c9db1 100644 --- a/interfaces/innerkits/signal_handler/dfx_dumprequest.c +++ b/interfaces/innerkits/signal_handler/dfx_dumprequest.c @@ -112,18 +112,6 @@ static bool IsDumpSignal(int signo) return signo == SIGDUMP || signo == SIGLEAK_STACK; } -static const char* GetCrashDescription(const int32_t errCode) -{ - size_t i; - - for (i = 0; i < sizeof(g_crashExceptionMap) / sizeof(g_crashExceptionMap[0]); i++) { - if (errCode == g_crashExceptionMap[i].errCode) { - return g_crashExceptionMap[i].str; - } - } - return g_crashExceptionMap[i - 1].str; /* the end of map is "unknown reason" */ -} - static void FillCrashExceptionAndReport(const int err) { struct CrashDumpException exception; diff --git a/interfaces/innerkits/signal_handler/dfx_signal_handler.c b/interfaces/innerkits/signal_handler/dfx_signal_handler.c index f352907ef..815b009ad 100644 --- a/interfaces/innerkits/signal_handler/dfx_signal_handler.c +++ b/interfaces/innerkits/signal_handler/dfx_signal_handler.c @@ -223,18 +223,6 @@ static bool FillDebugMessageLocked(int32_t sig, siginfo_t *si) return true; } -static const char* GetCrashDescription(const int32_t errCode) -{ - size_t i; - - for (i = 0; i < sizeof(g_crashExceptionMap) / sizeof(g_crashExceptionMap[0]); i++) { - if (errCode == g_crashExceptionMap[i].errCode) { - return g_crashExceptionMap[i].str; - } - } - return g_crashExceptionMap[i - 1].str; /* the end of map is "unknown reason" */ -} - static void FillCrashExceptionAndReport(const int err) { struct CrashDumpException exception; diff --git a/interfaces/innerkits/unwinder/BUILD.gn b/interfaces/innerkits/unwinder/BUILD.gn index 42f298e3f..255725b84 100644 --- a/interfaces/innerkits/unwinder/BUILD.gn +++ b/interfaces/innerkits/unwinder/BUILD.gn @@ -165,7 +165,6 @@ if (defined(ohos_lite)) { "$faultloggerd_common_path/build:coverage_flags", ] defines = [ - "DFX_UNWIND_ERROR", "DFX_ENABLE_TRACE", ] if (target_cpu == "arm64") { @@ -283,7 +282,6 @@ if (defined(ohos_lite)) { ] defines = [ "DFX_LOG_UNWIND", - "DFX_UNWIND_ERROR", "INSTR_STATISTIC_ENABLE", ] diff --git a/interfaces/innerkits/unwinder/include/arm_exidx.h b/interfaces/innerkits/unwinder/include/arm_exidx.h index 762db1a74..8d3900a9c 100644 --- a/interfaces/innerkits/unwinder/include/arm_exidx.h +++ b/interfaces/innerkits/unwinder/include/arm_exidx.h @@ -46,8 +46,8 @@ public: bool SearchEntry(uintptr_t pc, struct UnwindTableInfo uti, struct UnwindEntryInfo& uei); bool Step(uintptr_t entryOffset, std::shared_ptr rs); - const uint16_t& GetLastErrorCode() { return lastErrorData_.GetCode(); } - const uint64_t& GetLastErrorAddr() { return lastErrorData_.GetAddr(); } + uint16_t GetLastErrorCode() { return lastErrorData_.GetCode(); } + uint64_t GetLastErrorAddr() { return lastErrorData_.GetAddr(); } private: struct DecodeTable { diff --git a/interfaces/innerkits/unwinder/include/dwarf_section.h b/interfaces/innerkits/unwinder/include/dwarf_section.h index 253390780..08c674d63 100644 --- a/interfaces/innerkits/unwinder/include/dwarf_section.h +++ b/interfaces/innerkits/unwinder/include/dwarf_section.h @@ -35,8 +35,8 @@ public: bool SearchEntry(uintptr_t pc, struct UnwindTableInfo uti, struct UnwindEntryInfo& uei); bool Step(uintptr_t pc, uintptr_t fdeAddr, std::shared_ptr rs); - const uint16_t& GetLastErrorCode() { return lastErrorData_.GetCode(); } - const uint64_t& GetLastErrorAddr() { return lastErrorData_.GetAddr(); } + uint16_t GetLastErrorCode() { return lastErrorData_.GetCode(); } + uint64_t GetLastErrorAddr() { return lastErrorData_.GetAddr(); } protected: bool GetCieOrFde(uintptr_t& addr, FrameDescEntry& fdeInfo); diff --git a/test/benchmarktest/unwinder/BUILD.gn b/test/benchmarktest/unwinder/BUILD.gn index 49646cc6f..945d960e0 100644 --- a/test/benchmarktest/unwinder/BUILD.gn +++ b/test/benchmarktest/unwinder/BUILD.gn @@ -37,7 +37,6 @@ if (!defined(ohos_lite)) { if (libunwinder_debug) { defines += [ "DFX_LOG_UNWIND", - "DFX_UNWIND_ERROR", ] } sources = [ diff --git a/test/unittest/unwind/BUILD.gn b/test/unittest/unwind/BUILD.gn index c4ba6ff20..bba69e804 100644 --- a/test/unittest/unwind/BUILD.gn +++ b/test/unittest/unwind/BUILD.gn @@ -115,7 +115,6 @@ ohos_unittest("test_exidx") { configs = [ "$faultloggerd_common_path/build:coverage_flags" ] defines = [ "DFX_LOG_UNWIND", - "DFX_UNWIND_ERROR", "is_ohos=${is_ohos}", "TEST_ARM_EXIDX", ] -- Gitee From d0b982a478baedd3a7da93cc12a02174fe73ebb2 Mon Sep 17 00:00:00 2001 From: yuhailong Date: Sun, 5 Jan 2025 21:34:36 +0800 Subject: [PATCH 04/12] feat:param+fpunwinder Signed-off-by: yuhailong Change-Id: I7ab5fae27e0c6727266f3b739bacff838a9e279e --- interfaces/common/dfx_exception.h | 2 +- interfaces/common/dfx_param.h | 39 ++++++------------- .../innerkits/async_stack/fp_unwinder.cpp | 17 ++++---- .../innerkits/async_stack/fp_unwinder.h | 2 +- interfaces/innerkits/unwinder/unwinder.cpp | 2 +- test/unittest/common/param_test.cpp | 2 +- 6 files changed, 24 insertions(+), 40 deletions(-) diff --git a/interfaces/common/dfx_exception.h b/interfaces/common/dfx_exception.h index 61b161bd7..6ab21e71a 100644 --- a/interfaces/common/dfx_exception.h +++ b/interfaces/common/dfx_exception.h @@ -100,7 +100,7 @@ static inline const char* GetCrashDescription(int32_t errCode) {CRASH_LOG_EHILOGLOS, "Hilog not found." }, {CRASH_LOG_ESUMMARYLOS, "Fault Summary not found."}, }; - for (int i = 0; i < sizeof(crashExceptions) / sizeof(crashExceptions[0]); i++) { + for (uint32_t i = 0; i < sizeof(crashExceptions) / sizeof(crashExceptions[0]); i++) { if (errCode == crashExceptions[i].errCode) { return crashExceptions[i].str; } diff --git a/interfaces/common/dfx_param.h b/interfaces/common/dfx_param.h index 52c55c0c0..029cdfa99 100644 --- a/interfaces/common/dfx_param.h +++ b/interfaces/common/dfx_param.h @@ -17,43 +17,26 @@ #include #if defined(ENABLE_PARAMETER) -#include #include "parameter.h" #include "parameters.h" #endif namespace OHOS { namespace HiviewDFX { -namespace { -[[maybe_unused]] constexpr char MIXSTACK_ENABLED_KEY[] = "faultloggerd.priv.mixstack.enabled"; -} - -#if defined(ENABLE_PARAMETER) -#define GEN_ENABLE_PARAM_FUNC(FuncName, EnableKey, DefValue, ExpValue) \ - __attribute__((noinline)) static bool FuncName() \ - { \ - static bool ret = true; \ - static std::once_flag flag; \ - std::call_once(flag, [&] { \ - if (OHOS::system::GetParameter(EnableKey, DefValue) == ExpValue) { \ - ret = true; \ - } else { \ - ret = false; \ - } \ - }); \ - return ret; \ - } -#else -#define GEN_ENABLE_PARAM_FUNC(FuncName, EnableKey, DefValue, ExpValue) \ - __attribute__((noinline)) static bool FuncName() \ - { \ - return false; \ - } -#endif class DfxParam { public: - GEN_ENABLE_PARAM_FUNC(EnableMixstack, MIXSTACK_ENABLED_KEY, "true", "true"); + static bool IsEnableMixstack() + { +#if defined(ENABLE_PARAMETER) + static bool isEnable = [] { + return OHOS::system::GetParameter("faultloggerd.priv.mixstack.enabled", "true") == "true"; + }(); + return isEnable; +#else + return false; +#endif + } }; } // namespace HiviewDFX } // namespace OHOS diff --git a/interfaces/innerkits/async_stack/fp_unwinder.cpp b/interfaces/innerkits/async_stack/fp_unwinder.cpp index 76ffce302..e3384d23e 100644 --- a/interfaces/innerkits/async_stack/fp_unwinder.cpp +++ b/interfaces/innerkits/async_stack/fp_unwinder.cpp @@ -29,7 +29,7 @@ namespace OHOS { namespace HiviewDFX { -static int32_t g_validPipe[PIPE_NUM_SZ] = {-1, -1}; + constexpr uintptr_t MAX_UNWIND_ADDR_RANGE = 16 * 1024; int32_t FpUnwinder::Unwind(uintptr_t* pcs, int32_t sz, int32_t skipFrameNum) { @@ -72,7 +72,8 @@ int32_t FpUnwinder::Unwind(uintptr_t* pcs, int32_t sz, int32_t skipFrameNum) int32_t FpUnwinder::UnwindFallback(uintptr_t* pcs, int32_t sz, int32_t skipFrameNum) { - if (pipe2(g_validPipe, O_CLOEXEC | O_NONBLOCK) != 0) { + int32_t validPipe[PIPE_NUM_SZ] = {-1, -1}; + if (pipe2(validPipe, O_CLOEXEC | O_NONBLOCK) != 0) { DFXLOGE("Failed to init pipe, errno(%{public}d)", errno); return 0; } @@ -82,7 +83,7 @@ int32_t FpUnwinder::UnwindFallback(uintptr_t* pcs, int32_t sz, int32_t skipFrame int32_t realSz = 0; while ((index < sz - 1) && (fp - firstFp < MAX_UNWIND_ADDR_RANGE)) { uintptr_t addr = fp + sizeof(uintptr_t); - if (!ReadUintptrSafe(addr, pcs[++index])) { + if (!ReadUintptrSafe(validPipe[PIPE_WRITE], addr, pcs[++index])) { break; } if ((++index) >= skipFrameNum) { @@ -90,21 +91,21 @@ int32_t FpUnwinder::UnwindFallback(uintptr_t* pcs, int32_t sz, int32_t skipFrame realSz = index - skipFrameNum + 1; } uintptr_t prevFp = fp; - if (!ReadUintptrSafe(prevFp, fp)) { + if (!ReadUintptrSafe(validPipe[PIPE_WRITE], prevFp, fp)) { break; } if (fp <= prevFp) { break; } } - close(g_validPipe[PIPE_WRITE]); - close(g_validPipe[PIPE_READ]); + close(validPipe[PIPE_WRITE]); + close(validPipe[PIPE_READ]); return realSz; } -NO_SANITIZE bool FpUnwinder::ReadUintptrSafe(uintptr_t addr, uintptr_t& value) +NO_SANITIZE bool FpUnwinder::ReadUintptrSafe(int pipeWrite, uintptr_t addr, uintptr_t& value) { - if (OHOS_TEMP_FAILURE_RETRY(syscall(SYS_write, g_validPipe[PIPE_WRITE], addr, sizeof(uintptr_t))) == -1) { + if (OHOS_TEMP_FAILURE_RETRY(syscall(SYS_write, pipeWrite, addr, sizeof(uintptr_t))) == -1) { DFXLOGE("Failed to write addr to pipe, it is a invalid addr"); return false; } diff --git a/interfaces/innerkits/async_stack/fp_unwinder.h b/interfaces/innerkits/async_stack/fp_unwinder.h index c881ef17b..cb425a2bc 100644 --- a/interfaces/innerkits/async_stack/fp_unwinder.h +++ b/interfaces/innerkits/async_stack/fp_unwinder.h @@ -37,7 +37,7 @@ public: static int32_t Unwind(uintptr_t* pcs, int32_t sz, int32_t skipFrameNum); private: static int32_t UnwindFallback(uintptr_t* pcs, int32_t sz, int32_t skipFrameNum); - static bool ReadUintptrSafe(uintptr_t addr, uintptr_t& value); + static bool ReadUintptrSafe(int pipeWrite, uintptr_t addr, uintptr_t& value); }; } } // namespace OHOS diff --git a/interfaces/innerkits/unwinder/unwinder.cpp b/interfaces/innerkits/unwinder/unwinder.cpp index dcc8eb133..fae46d20a 100644 --- a/interfaces/innerkits/unwinder/unwinder.cpp +++ b/interfaces/innerkits/unwinder/unwinder.cpp @@ -227,7 +227,7 @@ private: void InitParam() { #if defined(ENABLE_MIXSTACK) - enableMixstack_ = DfxParam::EnableMixstack(); + enableMixstack_ = DfxParam::IsEnableMixstack(); #endif } bool GetMainStackRangeInner(uintptr_t& stackBottom, uintptr_t& stackTop); diff --git a/test/unittest/common/param_test.cpp b/test/unittest/common/param_test.cpp index 356476431..9dd4174c9 100644 --- a/test/unittest/common/param_test.cpp +++ b/test/unittest/common/param_test.cpp @@ -41,7 +41,7 @@ public: HWTEST_F(ParamTest, DfxParamTest001, TestSize.Level2) { GTEST_LOG_(INFO) << "DfxParamTest001: start."; - ASSERT_EQ(DfxParam::EnableMixstack(), true); + ASSERT_EQ(DfxParam::IsEnableMixstack(), true); GTEST_LOG_(INFO) << "DfxParamTest001: end."; } -- Gitee From b130b1127dfc465950a3353190f338041f0493b7 Mon Sep 17 00:00:00 2001 From: yuhailong Date: Sun, 5 Jan 2025 23:02:48 +0800 Subject: [PATCH 05/12] feat:stack_util opt Signed-off-by: yuhailong Change-Id: Ic80983cbc99b1c54d4906813bfb470a126521f49 --- common/dfxutil/stack_util.h | 188 ++++++++++-------- .../innerkits/async_stack/fp_unwinder.cpp | 6 +- .../innerkits/unwinder/include/fp_unwinder.h | 4 +- .../innerkits/unwinder/thread_context.cpp | 4 +- interfaces/innerkits/unwinder/unwinder.cpp | 6 +- test/unittest/unwind/memory_test.cpp | 8 +- 6 files changed, 119 insertions(+), 97 deletions(-) diff --git a/common/dfxutil/stack_util.h b/common/dfxutil/stack_util.h index a3fde0e25..90202a69d 100644 --- a/common/dfxutil/stack_util.h +++ b/common/dfxutil/stack_util.h @@ -18,112 +18,134 @@ #include #include #include +#include #include #include #include "dfx_define.h" namespace OHOS { namespace HiviewDFX { -namespace { -static uintptr_t g_stackMapStart = 0; -static uintptr_t g_stackMapEnd = 0; -static uintptr_t g_arkMapStart = 0; -static uintptr_t g_arkMapEnd = 0; -static bool ParseSelfMaps() -{ - FILE *fp = fopen(PROC_SELF_MAPS_PATH, "r"); - if (fp == NULL) { - return false; +class StackUtils { +public: + static StackUtils& Instance() + { + static StackUtils inst; + return inst; } - bool ret = false; - char mapInfo[256] = {0}; // 256: map info size - int pos = 0; - uint64_t begin = 0; - uint64_t end = 0; - uint64_t offset = 0; - char perms[5] = {0}; // 5:rwxp - while (fgets(mapInfo, sizeof(mapInfo), fp) != NULL) { - if (strstr(mapInfo, "[stack]") != NULL) { - if (sscanf_s(mapInfo, "%" SCNxPTR "-%" SCNxPTR " %4s %" SCNxPTR " %*x:%*x %*d%n", &begin, &end, - &perms, sizeof(perms), &offset, &pos) != 4) { // 4:scan size - continue; - } - g_stackMapStart = static_cast(begin); - g_stackMapEnd = static_cast(end); - ret = true; - } - if (strstr(mapInfo, "stub.an") != NULL) { - if (sscanf_s(mapInfo, "%" SCNxPTR "-%" SCNxPTR " %4s %" SCNxPTR " %*x:%*x %*d%n", &begin, &end, - &perms, sizeof(perms), &offset, &pos) != 4) { // 4:scan size - continue; - } - if (strcmp(perms, "r-xp") != 0) { - continue; - } + StackUtils(const StackUtils&) = delete; + StackUtils& operator=(const StackUtils&) = delete; - g_arkMapStart = static_cast(begin); - g_arkMapEnd = static_cast(end); - ret = true; + bool GetMainStackRange(uintptr_t& stackBottom, uintptr_t& stackTop) const + { + if (!mainStack_.Valid()) { + return false; } + stackBottom = mainStack_.start; + stackTop = mainStack_.end; + return true; } - (void)fclose(fp); - return ret; -}; -} - -AT_UNUSED inline bool GetArkStackRange(uintptr_t& start, uintptr_t& end) -{ - if (g_arkMapStart == 0 || g_arkMapEnd == 0) { - ParseSelfMaps(); - } - start = g_arkMapStart; - end = g_arkMapEnd; - return (g_arkMapStart != 0 && g_arkMapEnd != 0); -} -AT_UNUSED inline bool GetMainStackRange(uintptr_t& stackBottom, uintptr_t& stackTop) -{ - if (g_stackMapStart == 0 || g_stackMapEnd == 0) { - ParseSelfMaps(); + bool GetArkStackRange(uintptr_t& start, uintptr_t& end) const + { + if (!arkCode_.Valid()) { + return false; + } + start = arkCode_.start; + end = arkCode_.end; + return true; } - stackBottom = g_stackMapStart; - stackTop = g_stackMapEnd; - return (g_stackMapStart != 0 && g_stackMapEnd != 0); -} -AT_UNUSED static bool GetSelfStackRange(uintptr_t& stackBottom, uintptr_t& stackTop) -{ - bool ret = false; - pthread_attr_t tattr; - void *base = nullptr; - size_t size = 0; - if (pthread_getattr_np(pthread_self(), &tattr) != 0) { + static bool GetSelfStackRange(uintptr_t& stackBottom, uintptr_t& stackTop) + { + pthread_attr_t tattr; + if (pthread_getattr_np(pthread_self(), &tattr) != 0) { + return false; + } + void *base = nullptr; + size_t size = 0; + bool ret = false; + if (pthread_attr_getstack(&tattr, &base, &size) == 0) { + stackBottom = reinterpret_cast(base); + stackTop = reinterpret_cast(base) + size; + ret = true; + } + pthread_attr_destroy(&tattr); return ret; } - if (pthread_attr_getstack(&tattr, &base, &size) == 0) { - stackBottom = reinterpret_cast(base); - stackTop = reinterpret_cast(base) + size; - ret = true; - } - pthread_attr_destroy(&tattr); - return ret; -} -AT_UNUSED static bool GetSigAltStackRange(uintptr_t& stackBottom, uintptr_t& stackTop) -{ - bool ret = false; - stack_t altStack; - if (sigaltstack(nullptr, &altStack) != -1) { + static bool GetSigAltStackRange(uintptr_t& stackBottom, uintptr_t& stackTop) + { + stack_t altStack; + if (sigaltstack(nullptr, &altStack) == -1) { + return false; + } if ((static_cast(altStack.ss_flags) & SS_ONSTACK) != 0) { stackBottom = reinterpret_cast(altStack.ss_sp); stackTop = reinterpret_cast(altStack.ss_sp) + altStack.ss_size; - ret = true; + return true; + } + return false; + } +private: + struct MapRange { + uintptr_t start{0}; + uintptr_t end{0}; + bool Valid() const + { + return start != 0 && start < end; } + }; + StackUtils() + { + ParseSelfMaps(); } - return ret; -} + void ParseSelfMaps() + { + std::unique_ptr fp(fopen(PROC_SELF_MAPS_PATH, "r"), [](FILE* fp) { + if (fp != nullptr) { + fclose(fp); + } + }); + if (fp == nullptr) { + return; + } + auto parser = [] (auto mapInfo, bool checkExec, MapRange &range) { + uint64_t begin = 0; + uint64_t end = 0; + uint64_t offset = 0; + char perms[5] = {0}; // 5:rwxp + int pos = 0; + if (sscanf_s(mapInfo, "%" SCNxPTR "-%" SCNxPTR " %4s %" SCNxPTR " %*x:%*x %*d%n", &begin, &end, + &perms, sizeof(perms), &offset, &pos) != 4) { // 4:scan size + return; + } + if (checkExec && strcmp(perms, "r-xp") != 0) { + return; + } + range = {begin, end}; + }; + + char mapInfo[256] = {0}; // 256: map info size + while (fgets(mapInfo, sizeof(mapInfo), fp.get()) != nullptr) { + if (mainStack_.Valid() && arkCode_.Valid()) { + return; + } + if (!mainStack_.Valid() && strstr(mapInfo, "[stack]") != nullptr) { + parser(mapInfo, false, mainStack_); + continue; + } + + if (!arkCode_.Valid() && strstr(mapInfo, "stub.an") != nullptr) { + parser(mapInfo, true, arkCode_); + } + } + } + MapRange mainStack_; + MapRange arkCode_; +}; + } // namespace HiviewDFX } // namespace OHOS #endif diff --git a/interfaces/innerkits/async_stack/fp_unwinder.cpp b/interfaces/innerkits/async_stack/fp_unwinder.cpp index e3384d23e..5b69dc4b5 100644 --- a/interfaces/innerkits/async_stack/fp_unwinder.cpp +++ b/interfaces/innerkits/async_stack/fp_unwinder.cpp @@ -42,11 +42,11 @@ int32_t FpUnwinder::Unwind(uintptr_t* pcs, int32_t sz, int32_t skipFrameNum) uintptr_t stackTop = 0; uint32_t realSz = 0; if (getpid() == gettid()) { - GetMainStackRange(stackBottom, stackTop); + StackUtils::Instance().GetMainStackRange(stackBottom, stackTop); } else { - GetSelfStackRange(stackBottom, stackTop); + StackUtils::GetSelfStackRange(stackBottom, stackTop); if (!(stackPtr >= stackBottom && stackPtr < stackTop)) { - GetSigAltStackRange(stackBottom, stackTop); + StackUtils::GetSigAltStackRange(stackBottom, stackTop); if (stackPtr < stackBottom || stackPtr >= stackTop) { return realSz; } diff --git a/interfaces/innerkits/unwinder/include/fp_unwinder.h b/interfaces/innerkits/unwinder/include/fp_unwinder.h index f08157925..c7286474d 100644 --- a/interfaces/innerkits/unwinder/include/fp_unwinder.h +++ b/interfaces/innerkits/unwinder/include/fp_unwinder.h @@ -53,11 +53,11 @@ public: return 0; } if (gettid() == getpid()) { - if (!GetMainStackRange(stackBottom_, stackTop_)) { + if (!StackUtils::Instance().GetMainStackRange(stackBottom_, stackTop_)) { return 0; } } else { - if (!GetSelfStackRange(stackBottom_, stackTop_)) { + if (!StackUtils::GetSelfStackRange(stackBottom_, stackTop_)) { return 0; } } diff --git a/interfaces/innerkits/unwinder/thread_context.cpp b/interfaces/innerkits/unwinder/thread_context.cpp index 3387d5d34..7b880682d 100644 --- a/interfaces/innerkits/unwinder/thread_context.cpp +++ b/interfaces/innerkits/unwinder/thread_context.cpp @@ -174,7 +174,7 @@ NO_SANITIZE void CopyContextAndWaitTimeout(int sig, siginfo_t *si, void *context } if (tid != getpid()) { - if (!GetSelfStackRange(ctxPtr->stackBottom, ctxPtr->stackTop)) { + if (!StackUtils::GetSelfStackRange(ctxPtr->stackBottom, ctxPtr->stackTop)) { DFXLOGW("Failed to get stack range with tid(%{public}d)", tid); } } @@ -362,7 +362,7 @@ NO_SANITIZE bool LocalThreadContextMix::CheckStatusValidate(int status, int32_t NO_SANITIZE bool LocalThreadContextMix::GetSelfStackRangeInSignal() { std::unique_lock lock(mtx_); - return GetSelfStackRange(stackBottom_, stackTop_); + return StackUtils::GetSelfStackRange(stackBottom_, stackTop_); } NO_SANITIZE void LocalThreadContextMix::CopyRegister(void *context) diff --git a/interfaces/innerkits/unwinder/unwinder.cpp b/interfaces/innerkits/unwinder/unwinder.cpp index fae46d20a..1cdfa336a 100644 --- a/interfaces/innerkits/unwinder/unwinder.cpp +++ b/interfaces/innerkits/unwinder/unwinder.cpp @@ -515,7 +515,7 @@ bool Unwinder::Impl::GetMainStackRangeInner(uintptr_t& stackBottom, uintptr_t& s { if (maps_ != nullptr && !maps_->GetStackRange(stackBottom, stackTop)) { return false; - } else if (maps_ == nullptr && !GetMainStackRange(stackBottom, stackTop)) { + } else if (maps_ == nullptr && !StackUtils::Instance().GetMainStackRange(stackBottom, stackTop)) { return false; } return true; @@ -525,7 +525,7 @@ bool Unwinder::Impl::GetArkStackRangeInner(uintptr_t& arkMapStart, uintptr_t& ar { if (maps_ != nullptr && !maps_->GetArkStackRange(arkMapStart, arkMapEnd)) { return false; - } else if (maps_ == nullptr && !GetArkStackRange(arkMapStart, arkMapEnd)) { + } else if (maps_ == nullptr && !StackUtils::Instance().GetArkStackRange(arkMapStart, arkMapEnd)) { return false; } return true; @@ -536,7 +536,7 @@ bool Unwinder::Impl::GetStackRange(uintptr_t& stackBottom, uintptr_t& stackTop) if (gettid() == getpid()) { return GetMainStackRangeInner(stackBottom, stackTop); } - return GetSelfStackRange(stackBottom, stackTop); + return StackUtils::GetSelfStackRange(stackBottom, stackTop); } bool Unwinder::Impl::UnwindLocalWithTid(const pid_t tid, size_t maxFrameNum, size_t skipFrameNum) diff --git a/test/unittest/unwind/memory_test.cpp b/test/unittest/unwind/memory_test.cpp index ad2866cbd..9d6a4a344 100644 --- a/test/unittest/unwind/memory_test.cpp +++ b/test/unittest/unwind/memory_test.cpp @@ -111,7 +111,7 @@ HWTEST_F(DfxMemoryTest, DfxMemoryTest003, TestSize.Level2) uint8_t values[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8}; UnwindContext ctx; auto acc = std::make_shared(); - ASSERT_TRUE(GetSelfStackRange(ctx.stackBottom, ctx.stackTop)); + ASSERT_TRUE(StackUtils::GetSelfStackRange(ctx.stackBottom, ctx.stackTop)); auto memory = std::make_shared(acc); memory->SetCtx(&ctx); uintptr_t addr = reinterpret_cast(&values[0]); @@ -150,7 +150,7 @@ HWTEST_F(DfxMemoryTest, DfxMemoryTest004, TestSize.Level2) uint8_t values[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8}; UnwindContext ctx; auto acc = std::make_shared(); - ASSERT_TRUE(GetSelfStackRange(ctx.stackBottom, ctx.stackTop)); + ASSERT_TRUE(StackUtils::GetSelfStackRange(ctx.stackBottom, ctx.stackTop)); auto memory = std::make_shared(acc); memory->SetCtx(&ctx); uintptr_t addr = reinterpret_cast(&values[0]); @@ -180,7 +180,7 @@ HWTEST_F(DfxMemoryTest, DfxMemoryTest005, TestSize.Level2) uint8_t values[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8}; UnwindContext ctx; auto acc = std::make_shared(); - ASSERT_TRUE(GetSelfStackRange(ctx.stackBottom, ctx.stackTop)); + ASSERT_TRUE(StackUtils::GetSelfStackRange(ctx.stackBottom, ctx.stackTop)); auto memory = std::make_shared(acc); memory->SetCtx(&ctx); uintptr_t addr = reinterpret_cast(&values[0]); @@ -207,7 +207,7 @@ HWTEST_F(DfxMemoryTest, DfxMemoryTest006, TestSize.Level2) GTEST_LOG_(INFO) << "DfxMemoryTest006: start."; UnwindContext ctx; auto acc = std::make_shared(); - ASSERT_TRUE(GetSelfStackRange(ctx.stackBottom, ctx.stackTop)); + ASSERT_TRUE(StackUtils::GetSelfStackRange(ctx.stackBottom, ctx.stackTop)); auto memory = std::make_shared(acc); memory->SetCtx(&ctx); ASSERT_EQ(memory->GetEncodedSize(DW_EH_PE_absptr), sizeof(uintptr_t)); -- Gitee From 8e8e51a28f5b1b2e4bd7e2153c46441b390c9584 Mon Sep 17 00:00:00 2001 From: yuhailong Date: Mon, 6 Jan 2025 00:05:14 +0800 Subject: [PATCH 06/12] feat:add faultlogger sieze checker Signed-off-by: yuhailong Change-Id: I986cd23240a55c64461430d0df8a8c4f344ed7a8 --- .../innerkits/async_stack/include/unique_stack_table.h | 6 ++---- tools/process_dump/faultlogger_client_msg.h | 2 ++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/interfaces/innerkits/async_stack/include/unique_stack_table.h b/interfaces/innerkits/async_stack/include/unique_stack_table.h index 725b65fa3..04b8a3396 100644 --- a/interfaces/innerkits/async_stack/include/unique_stack_table.h +++ b/interfaces/innerkits/async_stack/include/unique_stack_table.h @@ -79,9 +79,7 @@ public: bool Init(); static UniqueStackTable* Instance(); - UniqueStackTable() - { - } + UniqueStackTable() = default; explicit UniqueStackTable(pid_t pid) : pid_(pid) { @@ -92,7 +90,7 @@ public: } UniqueStackTable(void* buf, uint32_t size, bool releaseBuffer = true) - :tableBufMMap_(buf), tableSize_(size), releaseBuffer_(releaseBuffer) + : tableBufMMap_(buf), tableSize_(size), releaseBuffer_(releaseBuffer) { totalNodes_ = ((tableSize_ / sizeof(Node)) >> 1) << 1; } diff --git a/tools/process_dump/faultlogger_client_msg.h b/tools/process_dump/faultlogger_client_msg.h index 818831533..4476d292a 100644 --- a/tools/process_dump/faultlogger_client_msg.h +++ b/tools/process_dump/faultlogger_client_msg.h @@ -38,4 +38,6 @@ struct FaultDFXLOGIInner { std::map sectionMaps; }; +static_assert(sizeof(FaultDFXLOGIInner) == 96, "faultlogger plugin must be modify together!!!"); + #endif //FAULTLOGGER_CLIENT_MSG_H_ -- Gitee From f2e0b4ef828fbbbaa98af17d9e621fd062a28bec Mon Sep 17 00:00:00 2001 From: yuhailong Date: Mon, 6 Jan 2025 15:29:45 +0800 Subject: [PATCH 07/12] fix:format code Signed-off-by: yuhailong Change-Id: Ibfec3fff770ca190a873dae2dec18f1ffdb876e5 --- common/cutil/dfx_cutil.c | 2 +- interfaces/common/dfx_param.h | 2 +- interfaces/innerkits/unwinder/BUILD.gn | 4 +--- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/common/cutil/dfx_cutil.c b/common/cutil/dfx_cutil.c index 1c70fe9b6..c80d34190 100644 --- a/common/cutil/dfx_cutil.c +++ b/common/cutil/dfx_cutil.c @@ -90,7 +90,7 @@ pid_t GetRealPid(void) } char buf[LINE_BUF_SIZE] = {0}; - int i = 0; + int i = 0; while (true) { char b = '\0'; ssize_t nRead = OHOS_TEMP_FAILURE_RETRY(read(fd, &b, sizeof(char))); diff --git a/interfaces/common/dfx_param.h b/interfaces/common/dfx_param.h index 029cdfa99..f8b13e4c8 100644 --- a/interfaces/common/dfx_param.h +++ b/interfaces/common/dfx_param.h @@ -33,7 +33,7 @@ public: return OHOS::system::GetParameter("faultloggerd.priv.mixstack.enabled", "true") == "true"; }(); return isEnable; -#else +#else return false; #endif } diff --git a/interfaces/innerkits/unwinder/BUILD.gn b/interfaces/innerkits/unwinder/BUILD.gn index 255725b84..2bbf897d0 100644 --- a/interfaces/innerkits/unwinder/BUILD.gn +++ b/interfaces/innerkits/unwinder/BUILD.gn @@ -164,9 +164,7 @@ if (defined(ohos_lite)) { ":mixstack_config", "$faultloggerd_common_path/build:coverage_flags", ] - defines = [ - "DFX_ENABLE_TRACE", - ] + defines = [ "DFX_ENABLE_TRACE" ] if (target_cpu == "arm64") { defines += [ "ENABLE_PARAMETER" ] } -- Gitee From 8324f1c22d454f6c63c98c1ab6a7f5ae504f249d Mon Sep 17 00:00:00 2001 From: yuhailong Date: Mon, 6 Jan 2025 17:37:53 +0800 Subject: [PATCH 08/12] feat:dumpcatch pimpl Signed-off-by: yuhailong Change-Id: Id2049ada9450c0f9bb0cd0283bda8b917251479a --- common/cutil/dfx_cutil.c | 40 +----- .../dump_catcher/dfx_dump_catcher.cpp | 127 ++++++++++++++---- .../dump_catcher/include/dfx_dump_catcher.h | 52 ++----- .../include/dfx_dump_catcher_errno.h | 1 - interfaces/innerkits/signal_handler/BUILD.gn | 1 - 5 files changed, 110 insertions(+), 111 deletions(-) diff --git a/common/cutil/dfx_cutil.c b/common/cutil/dfx_cutil.c index c80d34190..5b9a634d1 100644 --- a/common/cutil/dfx_cutil.c +++ b/common/cutil/dfx_cutil.c @@ -29,8 +29,6 @@ #include #include "dfx_define.h" -static const char * const PID_STR_NAME = "Pid:"; - static bool ReadStringFromFile(const char* path, char* dst, size_t dstSz) { if ((dst == NULL) || (path == NULL) || (dstSz == 0)) { @@ -83,43 +81,7 @@ bool GetProcessName(char* buffer, size_t bufferSz) pid_t GetRealPid(void) { - pid_t pid = syscall(SYS_getpid); - int fd = OHOS_TEMP_FAILURE_RETRY(open(PROC_SELF_STATUS_PATH, O_RDONLY)); - if (fd < 0) { - return pid; - } - - char buf[LINE_BUF_SIZE] = {0}; - int i = 0; - while (true) { - char b = '\0'; - ssize_t nRead = OHOS_TEMP_FAILURE_RETRY(read(fd, &b, sizeof(char))); - if (nRead <= 0 || b == '\0') { - break; - } - - if (b == '\n' || i == LINE_BUF_SIZE) { - if (strncmp(buf, PID_STR_NAME, strlen(PID_STR_NAME)) == 0) { -#ifdef ENABLE_MUSL_CUTIL - (void)sscanf(buf, "%*[^0-9]%d", &pid); -#else - (void)sscanf_s(buf, "%*[^0-9]%d", &pid); -#endif - break; - } -#ifdef ENABLE_MUSL_CUTIL - (void)memset(buf, '\0', sizeof(buf)); -#else - (void)memset_s(buf, sizeof(buf), '\0', sizeof(buf)); -#endif - i = 0; - continue; - } - buf[i] = b; - i++; - } - syscall(SYS_close, fd); - return pid; + return syscall(SYS_getpid); } uint64_t GetTimeMilliseconds(void) diff --git a/interfaces/innerkits/dump_catcher/dfx_dump_catcher.cpp b/interfaces/innerkits/dump_catcher/dfx_dump_catcher.cpp index 61691b6da..190dc8da1 100644 --- a/interfaces/innerkits/dump_catcher/dfx_dump_catcher.cpp +++ b/interfaces/innerkits/dump_catcher/dfx_dump_catcher.cpp @@ -17,27 +17,29 @@ #include #include -#include +#include +#include #include #include #include #include +#include +#include #include #include -#include -#include #include "backtrace_local.h" #include "dfx_define.h" +#include "dfx_dump_catcher_errno.h" #include "dfx_dump_res.h" #include "dfx_kernel_stack.h" #include "dfx_log.h" +#include "dfx_socket_request.h" #include "dfx_trace_dlsym.h" #include "dfx_util.h" #include "elapsed_time.h" #include "faultloggerd_client.h" -#include "dfx_socket_request.h" #include "file_ex.h" #include "procinfo.h" @@ -104,7 +106,78 @@ static void InitKernelStackInfo() g_kernelStackPid = 0; } -bool DfxDumpCatcher::DoDumpCurrTid(const size_t skipFrameNum, std::string& msg, size_t maxFrameNums) +class DfxDumpCatcher::Impl { +public: + bool DumpCatch(int pid, int tid, std::string& msg, size_t maxFrameNums, bool isJson); + bool DumpCatchFd(int pid, int tid, std::string& msg, int fd, size_t maxFrameNums); + bool DumpCatchMultiPid(const std::vector &pidV, std::string& msg); + int DumpCatchProcess(int pid, std::string& msg, size_t maxFrameNums, bool isJson); + std::pair DumpCatchWithTimeout(int pid, std::string& msg, int timeout, int tid, bool isJson); +private: + bool DoDumpCurrTid(const size_t skipFrameNum, std::string& msg, size_t maxFrameNums); + bool DoDumpLocalTid(const int tid, std::string& msg, size_t maxFrameNums); + bool DoDumpLocalPid(int pid, std::string& msg, size_t maxFrameNums); + bool DoDumpLocalLocked(int pid, int tid, std::string& msg, size_t maxFrameNums); + int32_t DoDumpRemoteLocked(int pid, int tid, std::string& msg, bool isJson = false, + int timeout = DUMPCATCHER_REMOTE_TIMEOUT); + int32_t DoDumpCatchRemote(int pid, int tid, std::string& msg, bool isJson = false, + int timeout = DUMPCATCHER_REMOTE_TIMEOUT); + int DoDumpRemotePid(int pid, std::string& msg, int (&pipeReadFd)[2], + bool isJson = false, int32_t timeout = DUMPCATCHER_REMOTE_TIMEOUT); + bool HandlePollError(const uint64_t endTime, int& remainTime, + bool& collectAllTidStack, std::string& resMsg, int& ret); + bool HandlePollTimeout(const int timeout, int& remainTime, + bool& collectAllTidStack, std::string& resMsg, int& ret); + bool HandlePollEvents(std::pair& bufState, std::pair& resState, + const struct pollfd (&readFds)[2], bool& bPipeConnect, bool& res); + std::pair DumpRemotePoll(const int timeout, std::pair& bufState, + std::pair& resState); + int DoDumpRemotePoll(int timeout, std::string& msg, const int (&pipeReadFd)[2], bool isJson = false); + bool DoReadBuf(int fd, std::string& msg); + bool DoReadRes(int fd, bool& ret, std::string& msg); + static void CollectKernelStack(pid_t pid, int waitMilliSeconds = 0); + void AsyncGetAllTidKernelStack(pid_t pid, int waitMilliSeconds = 0); + void DealWithPollRet(int pollRet, int pid, int32_t& ret, std::string& msg); + void DealWithSdkDumpRet(int sdkdumpRet, int pid, int32_t& ret, std::string& msg); + + static const int DUMPCATCHER_REMOTE_P90_TIMEOUT = 1000; + static const int DUMPCATCHER_REMOTE_TIMEOUT = 10000; + std::mutex mutex_; + int32_t pid_ = -1; + std::string halfProcStatus_ = ""; + std::string halfProcWchan_ = ""; +}; + +DfxDumpCatcher::DfxDumpCatcher() : impl_(std::make_shared()) +{} + +bool DfxDumpCatcher::DumpCatch(int pid, int tid, std::string& msg, size_t maxFrameNums, bool isJson) +{ + return impl_->DumpCatch(pid, tid, msg, maxFrameNums, isJson); +} + +bool DfxDumpCatcher::DumpCatchFd(int pid, int tid, std::string& msg, int fd, size_t maxFrameNums) +{ + return impl_->DumpCatchFd(pid, tid, msg, fd, maxFrameNums); +} + +bool DfxDumpCatcher::DumpCatchMultiPid(const std::vector &pidV, std::string& msg) +{ + return impl_->DumpCatchMultiPid(pidV, msg); +} + +int DfxDumpCatcher::DumpCatchProcess(int pid, std::string& msg, size_t maxFrameNums, bool isJson) +{ + return impl_->DumpCatchProcess(pid, msg, maxFrameNums, isJson); +} + +std::pair DfxDumpCatcher::DumpCatchWithTimeout(int pid, std::string& msg, + int timeout, int tid, bool isJson) +{ + return impl_->DumpCatchWithTimeout(pid, msg, timeout, tid, isJson); +} + +bool DfxDumpCatcher::Impl::DoDumpCurrTid(const size_t skipFrameNum, std::string& msg, size_t maxFrameNums) { bool ret = false; @@ -117,7 +190,7 @@ bool DfxDumpCatcher::DoDumpCurrTid(const size_t skipFrameNum, std::string& msg, return ret; } -bool DfxDumpCatcher::DoDumpLocalTid(const int tid, std::string& msg, size_t maxFrameNums) +bool DfxDumpCatcher::Impl::DoDumpLocalTid(const int tid, std::string& msg, size_t maxFrameNums) { bool ret = false; if (tid <= 0) { @@ -132,7 +205,7 @@ bool DfxDumpCatcher::DoDumpLocalTid(const int tid, std::string& msg, size_t maxF return ret; } -bool DfxDumpCatcher::DoDumpLocalPid(int pid, std::string& msg, size_t maxFrameNums) +bool DfxDumpCatcher::Impl::DoDumpLocalPid(int pid, std::string& msg, size_t maxFrameNums) { bool ret = false; if (pid <= 0) { @@ -161,12 +234,12 @@ bool DfxDumpCatcher::DoDumpLocalPid(int pid, std::string& msg, size_t maxFrameNu return ret; } -int32_t DfxDumpCatcher::DoDumpRemoteLocked(int pid, int tid, std::string& msg, bool isJson, int timeout) +int32_t DfxDumpCatcher::Impl::DoDumpRemoteLocked(int pid, int tid, std::string& msg, bool isJson, int timeout) { return DoDumpCatchRemote(pid, tid, msg, isJson, timeout); } -bool DfxDumpCatcher::DoDumpLocalLocked(int pid, int tid, std::string& msg, size_t maxFrameNums) +bool DfxDumpCatcher::Impl::DoDumpLocalLocked(int pid, int tid, std::string& msg, size_t maxFrameNums) { bool ret = false; if (tid == gettid()) { @@ -324,7 +397,7 @@ static void AnalyzeTimeoutReason(int pid, int32_t& ret) ret = DUMPCATCH_TIMEOUT_DUMP_SLOW; } -void DfxDumpCatcher::DealWithPollRet(int pollRet, int pid, int32_t& ret, std::string& msg) +void DfxDumpCatcher::Impl::DealWithPollRet(int pollRet, int pid, int32_t& ret, std::string& msg) { if (pollRet == DUMP_POLL_OK) { ret = DUMPCATCH_ESUCCESS; @@ -362,7 +435,7 @@ void DfxDumpCatcher::DealWithPollRet(int pollRet, int pid, int32_t& ret, std::st } } -void DfxDumpCatcher::DealWithSdkDumpRet(int sdkdumpRet, int pid, int32_t& ret, std::string& msg) +void DfxDumpCatcher::Impl::DealWithSdkDumpRet(int sdkdumpRet, int pid, int32_t& ret, std::string& msg) { uint32_t uid = getuid(); if (sdkdumpRet == ResponseCode::SDK_DUMP_REPEAT) { @@ -427,7 +500,7 @@ static std::pair DealWithDumpCatchRet(int pid, int32_t& ret, s return std::make_pair(result, reason); } -std::pair DfxDumpCatcher::DumpCatchWithTimeout(int pid, std::string& msg, int timeout, +std::pair DfxDumpCatcher::Impl::DumpCatchWithTimeout(int pid, std::string& msg, int timeout, int tid, bool isJson) { DfxEnableTraceDlsym(true); @@ -476,7 +549,7 @@ std::pair DfxDumpCatcher::DumpCatchWithTimeout(int pid, std::s return result; } -int DfxDumpCatcher::DumpCatchProcess(int pid, std::string& msg, size_t maxFrameNums, bool isJson) +int DfxDumpCatcher::Impl::DumpCatchProcess(int pid, std::string& msg, size_t maxFrameNums, bool isJson) { if (DumpCatch(pid, 0, msg, maxFrameNums, isJson)) { return 0; @@ -490,7 +563,7 @@ int DfxDumpCatcher::DumpCatchProcess(int pid, std::string& msg, size_t maxFrameN return -1; } -bool DfxDumpCatcher::DumpCatch(int pid, int tid, std::string& msg, size_t maxFrameNums, bool isJson) +bool DfxDumpCatcher::Impl::DumpCatch(int pid, int tid, std::string& msg, size_t maxFrameNums, bool isJson) { bool ret = false; if (pid <= 0 || tid < 0) { @@ -536,7 +609,7 @@ bool DfxDumpCatcher::DumpCatch(int pid, int tid, std::string& msg, size_t maxFra return ret; } -bool DfxDumpCatcher::DumpCatchFd(int pid, int tid, std::string& msg, int fd, size_t maxFrameNums) +bool DfxDumpCatcher::Impl::DumpCatchFd(int pid, int tid, std::string& msg, int fd, size_t maxFrameNums) { bool ret = false; ret = DumpCatch(pid, tid, msg, maxFrameNums); @@ -546,7 +619,7 @@ bool DfxDumpCatcher::DumpCatchFd(int pid, int tid, std::string& msg, int fd, siz return ret; } -int32_t DfxDumpCatcher::DoDumpCatchRemote(int pid, int tid, std::string& msg, bool isJson, int timeout) +int32_t DfxDumpCatcher::Impl::DoDumpCatchRemote(int pid, int tid, std::string& msg, bool isJson, int timeout) { DFX_TRACE_SCOPED_DLSYM("DoDumpCatchRemote"); int32_t ret = DUMPCATCH_UNKNOWN; @@ -572,7 +645,7 @@ int32_t DfxDumpCatcher::DoDumpCatchRemote(int pid, int tid, std::string& msg, bo return ret; } -int DfxDumpCatcher::DoDumpRemotePid(int pid, std::string& msg, int (&pipeReadFd)[2], bool isJson, int32_t timeout) +int DfxDumpCatcher::Impl::DoDumpRemotePid(int pid, std::string& msg, int (&pipeReadFd)[2], bool isJson, int32_t timeout) { DFX_TRACE_SCOPED_DLSYM("DoDumpRemotePid"); if (timeout <= 0) { @@ -610,7 +683,7 @@ static int32_t KernelRet2DumpcatchRet(int32_t ret) } } -void DfxDumpCatcher::CollectKernelStack(pid_t pid, int waitMilliSeconds) +void DfxDumpCatcher::Impl::CollectKernelStack(pid_t pid, int waitMilliSeconds) { ElapsedTime timer; std::string kernelStackInfo; @@ -661,7 +734,7 @@ void DfxDumpCatcher::CollectKernelStack(pid_t pid, int waitMilliSeconds) timer.Elapsed()); } -void DfxDumpCatcher::AsyncGetAllTidKernelStack(pid_t pid, int waitMilliSeconds) +void DfxDumpCatcher::Impl::AsyncGetAllTidKernelStack(pid_t pid, int waitMilliSeconds) { ReadProcessStatus(halfProcStatus_, pid); ReadProcessWchan(halfProcWchan_, pid, false, true); @@ -686,7 +759,7 @@ void DfxDumpCatcher::AsyncGetAllTidKernelStack(pid_t pid, int waitMilliSeconds) } } -bool DfxDumpCatcher::HandlePollError(const uint64_t endTime, int& remainTime, +bool DfxDumpCatcher::Impl::HandlePollError(const uint64_t endTime, int& remainTime, bool& collectAllTidStack, std::string& resMsg, int& ret) { if (errno == EINTR) { @@ -708,7 +781,7 @@ bool DfxDumpCatcher::HandlePollError(const uint64_t endTime, int& remainTime, return false; } -bool DfxDumpCatcher::HandlePollTimeout(const int timeout, int& remainTime, +bool DfxDumpCatcher::Impl::HandlePollTimeout(const int timeout, int& remainTime, bool& collectAllTidStack, std::string& resMsg, int& ret) { if (!collectAllTidStack && (remainTime == DUMPCATCHER_REMOTE_P90_TIMEOUT)) { @@ -722,7 +795,7 @@ bool DfxDumpCatcher::HandlePollTimeout(const int timeout, int& remainTime, return false; } -bool DfxDumpCatcher::HandlePollEvents(std::pair& bufState, std::pair& resState, +bool DfxDumpCatcher::Impl::HandlePollEvents(std::pair& bufState, std::pair& resState, const struct pollfd (&readFds)[2], bool& bPipeConnect, bool& res) { bool bufRet = true; @@ -759,7 +832,7 @@ bool DfxDumpCatcher::HandlePollEvents(std::pair& bufState, std return true; } -std::pair DfxDumpCatcher::DumpRemotePoll(const int timeout, +std::pair DfxDumpCatcher::Impl::DumpRemotePoll(const int timeout, std::pair& bufState, std::pair& resState) { int ret = DUMP_POLL_INIT; @@ -801,7 +874,7 @@ std::pair DfxDumpCatcher::DumpRemotePoll(const int timeout, return std::make_pair(res, ret); } -int DfxDumpCatcher::DoDumpRemotePoll(int timeout, std::string& msg, const int (&pipeReadFd)[2], bool isJson) +int DfxDumpCatcher::Impl::DoDumpRemotePoll(int timeout, std::string& msg, const int (&pipeReadFd)[2], bool isJson) { DFX_TRACE_SCOPED_DLSYM("DoDumpRemotePoll"); if (pipeReadFd[PIPE_BUF_INDEX] < 0 || pipeReadFd[PIPE_RES_INDEX] < 0) { @@ -820,7 +893,7 @@ int DfxDumpCatcher::DoDumpRemotePoll(int timeout, std::string& msg, const int (& return result.first ? DUMP_POLL_OK : result.second; } -bool DfxDumpCatcher::DoReadBuf(int fd, std::string& msg) +bool DfxDumpCatcher::Impl::DoReadBuf(int fd, std::string& msg) { bool ret = false; char *buffer = new char[MAX_PIPE_SIZE]; @@ -838,7 +911,7 @@ bool DfxDumpCatcher::DoReadBuf(int fd, std::string& msg) return ret; } -bool DfxDumpCatcher::DoReadRes(int fd, bool& ret, std::string& msg) +bool DfxDumpCatcher::Impl::DoReadRes(int fd, bool& ret, std::string& msg) { int32_t res = DumpErrorCode::DUMP_ESUCCESS; ssize_t nread = OHOS_TEMP_FAILURE_RETRY(read(fd, &res, sizeof(res))); @@ -853,7 +926,7 @@ bool DfxDumpCatcher::DoReadRes(int fd, bool& ret, std::string& msg) return true; } -bool DfxDumpCatcher::DumpCatchMultiPid(const std::vector pidV, std::string& msg) +bool DfxDumpCatcher::Impl::DumpCatchMultiPid(const std::vector &pidV, std::string& msg) { bool ret = false; int pidSize = (int)pidV.size(); diff --git a/interfaces/innerkits/dump_catcher/include/dfx_dump_catcher.h b/interfaces/innerkits/dump_catcher/include/dfx_dump_catcher.h index 98fab1f3f..43fb7ed25 100644 --- a/interfaces/innerkits/dump_catcher/include/dfx_dump_catcher.h +++ b/interfaces/innerkits/dump_catcher/include/dfx_dump_catcher.h @@ -17,21 +17,19 @@ #define DFX_DUMPCATCH_H #include -#include -#include #include -#include -#include #include -#include #include - -#include "dfx_dump_catcher_errno.h" - namespace OHOS { namespace HiviewDFX { class DfxDumpCatcher { public: + static constexpr size_t DEFAULT_MAX_FRAME_NUM = 256; + + DfxDumpCatcher(); + DfxDumpCatcher(const DfxDumpCatcher&) = delete; + DfxDumpCatcher& operator=(const DfxDumpCatcher&) = delete; + /** * @brief Dump native stack by specify pid and tid * @@ -65,7 +63,7 @@ public: * @param msg message of native stack * @return if succeed return true, otherwise return false */ - bool DumpCatchMultiPid(const std::vector pidV, std::string& msg); + bool DumpCatchMultiPid(const std::vector &pidV, std::string& msg); /** * @brief Dump stack of process * @@ -93,40 +91,8 @@ public: std::pair DumpCatchWithTimeout(int pid, std::string& msg, int timeout = 3000, int tid = 0, bool isJson = false); private: - static constexpr size_t DEFAULT_MAX_FRAME_NUM = 256; - bool DoDumpCurrTid(const size_t skipFrameNum, std::string& msg, size_t maxFrameNums); - bool DoDumpLocalTid(const int tid, std::string& msg, size_t maxFrameNums); - bool DoDumpLocalPid(int pid, std::string& msg, size_t maxFrameNums); - bool DoDumpLocalLocked(int pid, int tid, std::string& msg, size_t maxFrameNums); - int32_t DoDumpRemoteLocked(int pid, int tid, std::string& msg, bool isJson = false, - int timeout = DUMPCATCHER_REMOTE_TIMEOUT); - int32_t DoDumpCatchRemote(int pid, int tid, std::string& msg, bool isJson = false, - int timeout = DUMPCATCHER_REMOTE_TIMEOUT); - int DoDumpRemotePid(int pid, std::string& msg, int (&pipeReadFd)[2], - bool isJson = false, int32_t timeout = DUMPCATCHER_REMOTE_TIMEOUT); - bool HandlePollError(const uint64_t endTime, int& remainTime, - bool& collectAllTidStack, std::string& resMsg, int& ret); - bool HandlePollTimeout(const int timeout, int& remainTime, - bool& collectAllTidStack, std::string& resMsg, int& ret); - bool HandlePollEvents(std::pair& bufState, std::pair& resState, - const struct pollfd (&readFds)[2], bool& bPipeConnect, bool& res); - std::pair DumpRemotePoll(const int timeout, std::pair& bufState, - std::pair& resState); - int DoDumpRemotePoll(int timeout, std::string& msg, const int (&pipeReadFd)[2], bool isJson = false); - bool DoReadBuf(int fd, std::string& msg); - bool DoReadRes(int fd, bool& ret, std::string& msg); - static void CollectKernelStack(pid_t pid, int waitMilliSeconds = 0); - void AsyncGetAllTidKernelStack(pid_t pid, int waitMilliSeconds = 0); - void DealWithPollRet(int pollRet, int pid, int32_t& ret, std::string& msg); - void DealWithSdkDumpRet(int sdkdumpRet, int pid, int32_t& ret, std::string& msg); - -private: - static const int DUMPCATCHER_REMOTE_P90_TIMEOUT = 1000; - static const int DUMPCATCHER_REMOTE_TIMEOUT = 10000; - std::mutex mutex_; - int32_t pid_ = -1; - std::string halfProcStatus_ = ""; - std::string halfProcWchan_ = ""; + class Impl; + std::shared_ptr impl_; }; } // namespace HiviewDFX } // namespace OHOS diff --git a/interfaces/innerkits/dump_catcher/include/dfx_dump_catcher_errno.h b/interfaces/innerkits/dump_catcher/include/dfx_dump_catcher_errno.h index 3260a8459..fe4abdede 100644 --- a/interfaces/innerkits/dump_catcher/include/dfx_dump_catcher_errno.h +++ b/interfaces/innerkits/dump_catcher/include/dfx_dump_catcher_errno.h @@ -18,7 +18,6 @@ #include #include -#include namespace OHOS { namespace HiviewDFX { diff --git a/interfaces/innerkits/signal_handler/BUILD.gn b/interfaces/innerkits/signal_handler/BUILD.gn index a3c243942..a968fb213 100644 --- a/interfaces/innerkits/signal_handler/BUILD.gn +++ b/interfaces/innerkits/signal_handler/BUILD.gn @@ -130,7 +130,6 @@ if (defined(ohos_lite)) { "_LIBCPP_HAS_MUSL_LIBC", "__BUILD_LINUX_WITH_CLANG", "ENABLE_SIGHAND_MUSL_LOG", - "ENABLE_MUSL_CUTIL", ] ldflags = [ "-nostdlib" ] -- Gitee From c9f18f2f36041a563767372e8b4f7f9ea4cdbe55 Mon Sep 17 00:00:00 2001 From: yuhailong Date: Mon, 6 Jan 2025 19:51:25 +0800 Subject: [PATCH 09/12] fix:restore string_view_util.h for perf Signed-off-by: yuhailong Change-Id: I8d3d3088d448cdc724d948ea1e0d329797bdea26 --- common/dfxutil/string_view_util.h | 84 +++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 common/dfxutil/string_view_util.h diff --git a/common/dfxutil/string_view_util.h b/common/dfxutil/string_view_util.h new file mode 100644 index 000000000..b44a59ea7 --- /dev/null +++ b/common/dfxutil/string_view_util.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2023 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 STRING_VIEW_UTIL_H +#define STRING_VIEW_UTIL_H + +#include +#include +#include +#include +#include +#include "cpp_define.h" + +namespace OHOS { +namespace HiviewDFX { +class StringViewHold { +public: + static StringViewHold &Get() + { + static StringViewHold instance; + return instance; + } + + const char* Hold(STRING_VIEW view) + { + pthread_spin_lock(&spin_lock_); + if (view.size() == 0) { + pthread_spin_unlock(&spin_lock_); + return ""; + } + + char *p = new (std::nothrow) char[view.size() + 1]; + if (p == nullptr) { + pthread_spin_unlock(&spin_lock_); + return ""; + } + if (memset_s(p, view.size() + 1, '\0', view.size() + 1) != 0) { + pthread_spin_unlock(&spin_lock_); + return ""; + } + std::copy(view.data(), view.data() + view.size(), p); + views_.emplace_back(p); + pthread_spin_unlock(&spin_lock_); + return p; + } + + // only use in UT + void Clean() + { + pthread_spin_lock(&spin_lock_); + for (auto &p : views_) { + delete[] p; + } + views_.clear(); + pthread_spin_unlock(&spin_lock_); + } +private: + StringViewHold() + { + pthread_spin_init(&spin_lock_, PTHREAD_PROCESS_PRIVATE); + } + ~StringViewHold() + { + Clean(); + pthread_spin_destroy(&spin_lock_); + } + + std::vector views_; + pthread_spinlock_t spin_lock_; +}; +} // namespace HiviewDFX +} // namespace OHOS +#endif \ No newline at end of file -- Gitee From b800b3200be66e06c66a63852ce202fdbadf77ff Mon Sep 17 00:00:00 2001 From: yuhailong Date: Mon, 6 Jan 2025 20:58:57 +0800 Subject: [PATCH 10/12] fix: dumpcatch compile error Signed-off-by: yuhailong Change-Id: Icd35fd46e23b10d6dc9158b4b4398c967ef91333 --- .../dump_catcher/dfx_dump_catcher.cpp | 6 ++-- .../dump_catcher/dfx_dump_catcher_errno.cpp | 1 + .../dump_catcher/libdfx_dumpcatcher.map | 5 ++-- .../formatter/dfx_json_formatter.cpp | 8 ++--- .../formatter/include/dfx_json_formatter.h | 2 +- interfaces/innerkits/procinfo/procinfo.cpp | 6 ++-- .../dump_catcher/dumpcatcher_command_test.cpp | 30 ++++++++++++------- 7 files changed, 33 insertions(+), 25 deletions(-) diff --git a/interfaces/innerkits/dump_catcher/dfx_dump_catcher.cpp b/interfaces/innerkits/dump_catcher/dfx_dump_catcher.cpp index 190dc8da1..9767f19c8 100644 --- a/interfaces/innerkits/dump_catcher/dfx_dump_catcher.cpp +++ b/interfaces/innerkits/dump_catcher/dfx_dump_catcher.cpp @@ -612,7 +612,7 @@ bool DfxDumpCatcher::Impl::DumpCatch(int pid, int tid, std::string& msg, size_t bool DfxDumpCatcher::Impl::DumpCatchFd(int pid, int tid, std::string& msg, int fd, size_t maxFrameNums) { bool ret = false; - ret = DumpCatch(pid, tid, msg, maxFrameNums); + ret = DumpCatch(pid, tid, msg, fd, maxFrameNums); if (fd > 0) { ret = OHOS_TEMP_FAILURE_RETRY(write(fd, msg.c_str(), msg.length())); } @@ -795,8 +795,8 @@ bool DfxDumpCatcher::Impl::HandlePollTimeout(const int timeout, int& remainTime, return false; } -bool DfxDumpCatcher::Impl::HandlePollEvents(std::pair& bufState, std::pair& resState, - const struct pollfd (&readFds)[2], bool& bPipeConnect, bool& res) +bool DfxDumpCatcher::Impl::HandlePollEvents(std::pair& bufState, + std::pair& resState, const struct pollfd (&readFds)[2], bool& bPipeConnect, bool& res) { bool bufRet = true; bool resRet = false; diff --git a/interfaces/innerkits/dump_catcher/dfx_dump_catcher_errno.cpp b/interfaces/innerkits/dump_catcher/dfx_dump_catcher_errno.cpp index 4c5cb65bd..cf31a09f6 100644 --- a/interfaces/innerkits/dump_catcher/dfx_dump_catcher_errno.cpp +++ b/interfaces/innerkits/dump_catcher/dfx_dump_catcher_errno.cpp @@ -14,6 +14,7 @@ */ #include "dfx_dump_catcher_errno.h" +#include namespace OHOS { namespace HiviewDFX { diff --git a/interfaces/innerkits/dump_catcher/libdfx_dumpcatcher.map b/interfaces/innerkits/dump_catcher/libdfx_dumpcatcher.map index 9c49c9ad0..18b3a75e8 100644 --- a/interfaces/innerkits/dump_catcher/libdfx_dumpcatcher.map +++ b/interfaces/innerkits/dump_catcher/libdfx_dumpcatcher.map @@ -1,9 +1,8 @@ { global: extern "C++" { - OHOS::HiviewDFX::DfxDumpCatcher::Dump*; - OHOS::HiviewDFX::DfxDumpCatcher::Do*; - OHOS::HiviewDFX::DfxDumpCatchError::ToString*; + OHOS::HiviewDFX::DfxDumpCatcher::DfxDumpCatcher*; + OHOS::HiviewDFX::DfxDumpCatcher::DumpCatch*; }; local: *; diff --git a/interfaces/innerkits/formatter/dfx_json_formatter.cpp b/interfaces/innerkits/formatter/dfx_json_formatter.cpp index f54b0ec73..ac349891b 100644 --- a/interfaces/innerkits/formatter/dfx_json_formatter.cpp +++ b/interfaces/innerkits/formatter/dfx_json_formatter.cpp @@ -35,7 +35,7 @@ static bool FormatJsFrame(const Json::Value& frames, const uint32_t& frameIdx, s if (snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, idxFmt, frameIdx) <= 0) { return false; } - outStr = std::string(buf, strlen(buf)); + outStr = std::string(buf); std::string symbol = frames[frameIdx]["symbol"].asString(); if (!symbol.empty()) { outStr.append(" " + symbol); @@ -66,7 +66,7 @@ static bool FormatNativeFrame(const Json::Value& frames, const uint32_t& frameId file.empty() ? "Unknown" : file.c_str()) <= 0) { return false; } - outStr = std::string(buf, strlen(buf)); + outStr = std::string(buf); if (!symbol.empty()) { outStr.append("(" + symbol + "+" + offset + ")"); } @@ -77,7 +77,7 @@ static bool FormatNativeFrame(const Json::Value& frames, const uint32_t& frameId } } -bool DfxJsonFormatter::FormatJsonStack(std::string jsonStack, std::string& outStackStr) +bool DfxJsonFormatter::FormatJsonStack(const std::string& jsonStack, std::string& outStackStr) { Json::Reader reader; Json::Value threads; @@ -157,7 +157,7 @@ static bool FormatKernelStackJson(std::vector processStack, std: if (snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, format, frame.relPc) <= 0) { continue; } - frameJson["pc"] = std::string(buf, strlen(buf)); + frameJson["pc"] = std::string(buf); frameJson["symbol"] = ""; frameJson["offset"] = 0; frameJson["file"] = frame.mapName.empty() ? "Unknown" : frame.mapName; diff --git a/interfaces/innerkits/formatter/include/dfx_json_formatter.h b/interfaces/innerkits/formatter/include/dfx_json_formatter.h index 965ecb646..0c5b5f8ce 100644 --- a/interfaces/innerkits/formatter/include/dfx_json_formatter.h +++ b/interfaces/innerkits/formatter/include/dfx_json_formatter.h @@ -33,7 +33,7 @@ public: * @param outStackStr output the stack string * @return bool */ - static bool FormatJsonStack(std::string jsonStack, std::string& outStackStr); + static bool FormatJsonStack(const std::string& jsonStack, std::string& outStackStr); /** * @brief Format kernel stack diff --git a/interfaces/innerkits/procinfo/procinfo.cpp b/interfaces/innerkits/procinfo/procinfo.cpp index 499f40a8b..c2fd46a4d 100644 --- a/interfaces/innerkits/procinfo/procinfo.cpp +++ b/interfaces/innerkits/procinfo/procinfo.cpp @@ -32,9 +32,9 @@ namespace OHOS { namespace HiviewDFX { namespace { -const char PID_STR_NAME[] = "Pid:"; -const char PPID_STR_NAME[] = "PPid:"; -const char NSPID_STR_NAME[] = "NSpid:"; +const char * const PID_STR_NAME = "Pid:"; +const char * const PPID_STR_NAME = "PPid:"; +const char * const NSPID_STR_NAME = "NSpid:"; const int ARGS_COUNT_ONE = 1; const int ARGS_COUNT_TWO = 2; const int STATUS_LINE_SIZE = 1024; diff --git a/test/unittest/dump_catcher/dumpcatcher_command_test.cpp b/test/unittest/dump_catcher/dumpcatcher_command_test.cpp index 989d1c008..a242d0789 100644 --- a/test/unittest/dump_catcher/dumpcatcher_command_test.cpp +++ b/test/unittest/dump_catcher/dumpcatcher_command_test.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include "dfx_define.h" @@ -249,23 +250,30 @@ HWTEST_F(DumpCatcherCommandTest, DumpCatcherCommandTest014, TestSize.Level2) /** * @tc.name: DumpCatcherCommandTest015 - * @tc.desc: test dumpcatcher abnormal scenario + * @tc.desc: test dumpcatcher self scenario * @tc.type: FUNC */ HWTEST_F(DumpCatcherCommandTest, DumpCatcherCommandTest015, TestSize.Level2) { GTEST_LOG_(INFO) << "DumpCatcherCommandTest015: start."; - std::shared_ptr dump = make_shared(); - std::string msg = ""; - bool ret = dump->DoDumpCurrTid(0, msg, 0); - ASSERT_EQ(ret, false); - ret = dump->DoDumpLocalTid(-1, msg, 0); - ASSERT_EQ(ret, false); - ret = dump->DoDumpLocalPid(-1, msg, 0); - ASSERT_EQ(ret, false); + auto sleep = [] { + std::this_thread::sleep_for(std::chrono::seconds(10)); + }; + for (int i = 0; i < 10; i++) { + std::thread t(sleep); + t.detach(); + } + DfxDumpCatcher dump; + std::string stack; + bool result = dump.DumpCatch(getpid(), 0, stack); + ASSERT_EQ(result, true); + + result = dump.DumpCatch(getpid(), getpid(), stack); + ASSERT_EQ(result, true); + std::vector pidV; - ret = dump->DumpCatchMultiPid(pidV, msg); - ASSERT_EQ(ret, false); + result = dump.DumpCatchMultiPid(pidV, stack); + ASSERT_EQ(result, false); GTEST_LOG_(INFO) << "DumpCatcherCommandTest015: end."; } -- Gitee From 241ec51715c121d8eb2f1f1bfaa5fa90c33caa55 Mon Sep 17 00:00:00 2001 From: yuhailong Date: Mon, 6 Jan 2025 21:31:22 +0800 Subject: [PATCH 11/12] feat:DfxDumpCatchError opt Signed-off-by: yuhailong Change-Id: I875b488523435b18d9497e99f65c5820923d7fba --- .../dump_catcher/dfx_dump_catcher_errno.cpp | 64 ++++++++++--------- test/benchmarktest/unwinder/BUILD.gn | 4 +- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/interfaces/innerkits/dump_catcher/dfx_dump_catcher_errno.cpp b/interfaces/innerkits/dump_catcher/dfx_dump_catcher_errno.cpp index cf31a09f6..92f6d6d6b 100644 --- a/interfaces/innerkits/dump_catcher/dfx_dump_catcher_errno.cpp +++ b/interfaces/innerkits/dump_catcher/dfx_dump_catcher_errno.cpp @@ -14,43 +14,45 @@ */ #include "dfx_dump_catcher_errno.h" -#include - +#include namespace OHOS { namespace HiviewDFX { +struct DumpCatchErrInfo { + int32_t code; + const char *info; +}; -const std::map ERROR_CODE_MAP = { - { DUMPCATCH_ESUCCESS, std::string("success") }, - { DUMPCATCH_EPARAM, std::string("param error") }, - { DUMPCATCH_NO_PROCESS, std::string("process has exited") }, - { DUMPCATCH_IS_DUMPING, std::string("process is dumping") }, - { DUMPCATCH_EPERMISSION, std::string("check permission error") }, - { DUMPCATCH_HAS_CRASHED, std::string("process has been crashed") }, - { DUMPCATCH_ECONNECT, std::string("failed to connect to faultloggerd") }, - { DUMPCATCH_EWRITE, std::string("failed to write data to faultloggerd") }, - { DUMPCATCH_EFD, std::string("buf or res fd error") }, - { DUMPCATCH_EPOLL, std::string("poll error") }, - { DUMPCATCH_DUMP_EPTRACE, std::string("failed to ptrace thread") }, - { DUMPCATCH_DUMP_EUNWIND, std::string("failed to unwind") }, - { DUMPCATCH_DUMP_EMAP, std::string("failed to find map") }, - { DUMPCATCH_TIMEOUT_SIGNAL_BLOCK, std::string("signal has been block by target process") }, - { DUMPCATCH_TIMEOUT_KERNEL_FROZEN, std::string("target process has been frozen in kernel") }, - { DUMPCATCH_TIMEOUT_PROCESS_KILLED, std::string("target process has been killed during dumping") }, - { DUMPCATCH_TIMEOUT_DUMP_SLOW, std::string("failed to fully dump due to timeout") }, - { DUMPCATCH_KERNELSTACK_ECREATE, std::string("kernelstack fail due to create hstackval fail") }, - { DUMPCATCH_KERNELSTACK_EOPEN, std::string("kernelstack fail due to open bbox fail") }, - { DUMPCATCH_KERNELSTACK_EIOCTL, std::string("kernelstack fail due to ioctl fail") }, - { DUMPCATCH_KERNELSTACK_NONEED, std::string("no need to dump kernelstack") }, - { DUMPCATCH_UNKNOWN, std::string("unknown reason") } +const DumpCatchErrInfo ERROR_CODE_MAPS[] = { + { DUMPCATCH_ESUCCESS, "success" }, + { DUMPCATCH_EPARAM, "param error" }, + { DUMPCATCH_NO_PROCESS, "process has exited" }, + { DUMPCATCH_IS_DUMPING, "process is dumping" }, + { DUMPCATCH_EPERMISSION, "check permission error" }, + { DUMPCATCH_HAS_CRASHED, "process has been crashed" }, + { DUMPCATCH_ECONNECT, "failed to connect to faultloggerd" }, + { DUMPCATCH_EWRITE, "failed to write data to faultloggerd" }, + { DUMPCATCH_EFD, "buf or res fd error" }, + { DUMPCATCH_EPOLL, "poll error" }, + { DUMPCATCH_DUMP_EPTRACE, "failed to ptrace thread" }, + { DUMPCATCH_DUMP_EUNWIND, "failed to unwind" }, + { DUMPCATCH_DUMP_EMAP, "failed to find map" }, + { DUMPCATCH_TIMEOUT_SIGNAL_BLOCK, "signal has been block by target process" }, + { DUMPCATCH_TIMEOUT_KERNEL_FROZEN, "target process has been frozen in kernel" }, + { DUMPCATCH_TIMEOUT_PROCESS_KILLED, "target process has been killed during dumping" }, + { DUMPCATCH_TIMEOUT_DUMP_SLOW, "failed to fully dump due to timeout" }, + { DUMPCATCH_KERNELSTACK_ECREATE, "kernelstack fail due to create hstackval fail" }, + { DUMPCATCH_KERNELSTACK_EOPEN, "kernelstack fail due to open bbox fail" }, + { DUMPCATCH_KERNELSTACK_EIOCTL, "kernelstack fail due to ioctl fail" }, + { DUMPCATCH_KERNELSTACK_NONEED, "no need to dump kernelstack" }, + { DUMPCATCH_UNKNOWN, "unknown reason" } }; -std::string DfxDumpCatchError::ToString(const int32_t res) +std::string DfxDumpCatchError::ToString(int32_t res) { - auto it = ERROR_CODE_MAP.find(res); - if (it != ERROR_CODE_MAP.end()) { - return it->second; - } - return std::string("invalid error code"); + auto iter = std::find_if(std::begin(ERROR_CODE_MAPS), std::end(ERROR_CODE_MAPS), [res](const auto &ele) { + return ele.code == res; + }); + return iter != std::end(ERROR_CODE_MAPS) ? iter->info : "invalid error code"; } } // namespace HiviewDFX } // namespace OHOS \ No newline at end of file diff --git a/test/benchmarktest/unwinder/BUILD.gn b/test/benchmarktest/unwinder/BUILD.gn index 945d960e0..3b60a0287 100644 --- a/test/benchmarktest/unwinder/BUILD.gn +++ b/test/benchmarktest/unwinder/BUILD.gn @@ -35,9 +35,7 @@ if (!defined(ohos_lite)) { ldflags = [ "-rdynamic" ] defines = [ "LOCK_TO_CPU" ] if (libunwinder_debug) { - defines += [ - "DFX_LOG_UNWIND", - ] + defines += [ "DFX_LOG_UNWIND" ] } sources = [ "$faultloggerd_test_path/benchmarktest/main/main_benchmark.cpp", -- Gitee From 3eabc67b90c9695738922bef0899746899c592a9 Mon Sep 17 00:00:00 2001 From: yuhailong Date: Tue, 7 Jan 2025 09:37:21 +0800 Subject: [PATCH 12/12] fix:arm64 complie Signed-off-by: yuhailong Change-Id: I15fe72959ce6fdd0b65744f1c53cba167fbe064b --- frameworks/localhandler/dfx_signal_local_handler.cpp | 2 +- interfaces/innerkits/signal_handler/encaps.json | 7 ++++++- tools/process_dump/faultlogger_client_msg.h | 4 ++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/frameworks/localhandler/dfx_signal_local_handler.cpp b/frameworks/localhandler/dfx_signal_local_handler.cpp index d10f35bb6..bb317fd5e 100644 --- a/frameworks/localhandler/dfx_signal_local_handler.cpp +++ b/frameworks/localhandler/dfx_signal_local_handler.cpp @@ -43,11 +43,11 @@ #define LOG_TAG "DfxSignalLocalHandler" #endif -constexpr uint32_t LOCAL_HANDLER_STACK_SIZE = 128 * 1024; // 128K constexpr uint32_t FAULTLOGGERD_UID = 1202; static CrashFdFunc g_crashFdFn = nullptr; #if !defined(__aarch64__) && !defined(__loongarch_lp64) +constexpr uint32_t LOCAL_HANDLER_STACK_SIZE = 128 * 1024; // 128K static void *g_reservedChildStack = nullptr; #endif static struct ProcessDumpRequest g_request; diff --git a/interfaces/innerkits/signal_handler/encaps.json b/interfaces/innerkits/signal_handler/encaps.json index 6d5f4ebad..a859cec83 100644 --- a/interfaces/innerkits/signal_handler/encaps.json +++ b/interfaces/innerkits/signal_handler/encaps.json @@ -1 +1,6 @@ -{"encaps":{"ohos.encaps.count":1,"ohos.encaps.fork.source":2}} \ No newline at end of file +{ + "encaps": { + "ohos.encaps.count": 1, + "ohos.encaps.fork.source": 2 + } +} \ No newline at end of file diff --git a/tools/process_dump/faultlogger_client_msg.h b/tools/process_dump/faultlogger_client_msg.h index 4476d292a..a10278d90 100644 --- a/tools/process_dump/faultlogger_client_msg.h +++ b/tools/process_dump/faultlogger_client_msg.h @@ -38,6 +38,10 @@ struct FaultDFXLOGIInner { std::map sectionMaps; }; +#if defined(__arm__) static_assert(sizeof(FaultDFXLOGIInner) == 96, "faultlogger plugin must be modify together!!!"); +#elif defined(__aarch64__) +static_assert(sizeof(FaultDFXLOGIInner) == 168, "faultlogger plugin must be modify together!!!"); +#endif #endif //FAULTLOGGER_CLIENT_MSG_H_ -- Gitee