From 0a0ebc696c70d81f3cf5efe52e466209de7a6975 Mon Sep 17 00:00:00 2001 From: cs1111 Date: Mon, 8 Sep 2025 20:09:00 +0800 Subject: [PATCH] feature:async stack open normally Signed-off-by: cs1111 Change-Id: I08739318813385e2e05555e04a3a76afe8508806 --- .../innerkits/async_stack/async_stack.cpp | 104 ++++++++++-------- .../async_stack/include/async_stack.h | 10 +- .../innerkits/async_stack/libasync_stack.map | 4 +- .../unittest/async_stack/async_stack_test.cpp | 26 +---- .../process_dump/submitter_stack_test.cpp | 4 +- tools/crasher_cpp/dfx_crasher.cpp | 29 ----- 6 files changed, 65 insertions(+), 112 deletions(-) diff --git a/interfaces/innerkits/async_stack/async_stack.cpp b/interfaces/innerkits/async_stack/async_stack.cpp index 995bca829..1d9e170cc 100644 --- a/interfaces/innerkits/async_stack/async_stack.cpp +++ b/interfaces/innerkits/async_stack/async_stack.cpp @@ -15,6 +15,7 @@ #include "async_stack.h" +#include #include #include #include @@ -27,43 +28,18 @@ #include "unwinder.h" using namespace OHOS::HiviewDFX; +static bool g_init = false; #if defined(__aarch64__) static pthread_key_t g_stackidKey; -static bool g_init = false; static OHOS::HiviewDFX::FpBacktrace* g_fpBacktrace = nullptr; +using SetStackIdFn = void(*)(uint64_t stackId); +using CollectAsyncStackFn = uint64_t(*)(); +using UvSetAsyncStackFn = void(*)(CollectAsyncStackFn collectAsyncStackFn, SetStackIdFn setStackIdFn); +using FFRTSetAsyncStackFn = void(*)(CollectAsyncStackFn collectAsyncStackFn, SetStackIdFn setStackIdFn); -static void InitAsyncStackInner(void) -{ - // init unique stack table - if (!OHOS::HiviewDFX::UniqueStackTable::Instance()->Init()) { - DFXLOGE("failed to init unique stack table?."); - return; - } - - if (pthread_key_create(&g_stackidKey, nullptr) == 0) { - g_init = true; - } else { - DFXLOGE("failed to create key for stackId."); - return; - } - - // set callback for DfxSignalHandler to read stackId - DFX_SetAsyncStackCallback(GetStackId); - g_fpBacktrace = OHOS::HiviewDFX::FpBacktrace::CreateInstance(); -} - -static bool InitAsyncStack(void) -{ - static once_flag onceFlag = ONCE_FLAG_INIT; - call_once(&onceFlag, InitAsyncStackInner); - return g_init; -} -#endif - -extern "C" uint64_t CollectAsyncStack(void) +extern "C" uint64_t DfxCollectAsyncStack(void) { -#if defined(__aarch64__) - if (!InitAsyncStack()) { + if (!g_init) { return 0; } const uint32_t maxSize = 16; @@ -77,33 +53,69 @@ extern "C" uint64_t CollectAsyncStack(void) uintptr_t* pcs = reinterpret_cast(pcArray); OHOS::HiviewDFX::UniqueStackTable::Instance()->PutPcsInTable(stackIdPtr, pcs, size); return stackId; -#else - return 0; -#endif } -extern "C" void SetStackId(uint64_t stackId) +extern "C" void DfxSetStackId(uint64_t stackId) { -#if defined(__aarch64__) - if (!InitAsyncStack()) { + if (!g_init) { return; } pthread_setspecific(g_stackidKey, reinterpret_cast(stackId)); -#else - return; -#endif } -extern "C" uint64_t GetStackId() +extern "C" uint64_t DfxGetStackId() { -#if defined(__aarch64__) - if (!InitAsyncStack()) { + if (!g_init) { return 0; } return reinterpret_cast(pthread_getspecific(g_stackidKey)); -#else - return 0; +} + +void DfxSetAsyncStackCallback(void) +{ + // set callback for DfxSignalHandler to read stackId + DFX_SetAsyncStackCallback(DfxGetStackId); + const char* uvSetAsyncStackFnName = "LibuvSetAsyncStackFunc"; + auto uvSetAsyncStackFn = reinterpret_cast(dlsym(RTLD_DEFAULT, uvSetAsyncStackFnName)); + if (uvSetAsyncStackFn != nullptr) { + uvSetAsyncStackFn(DfxCollectAsyncStack, DfxSetStackId); + } + static const char* debuggableEnv = getenv("HAP_DEBUGGABLE"); + if ((debuggableEnv != NULL && strcmp(debuggableEnv, "true") == 0)) { + const char* ffrtSetAsyncStackFnName = "FFRTSetAsyncStackFunc"; + auto ffrtSetAsyncStackFn = reinterpret_cast(dlsym(RTLD_DEFAULT, ffrtSetAsyncStackFnName)); + if (ffrtSetAsyncStackFn != nullptr) { + ffrtSetAsyncStackFn(DfxCollectAsyncStack, DfxSetStackId); + } + } +} + +void DfxInitAsyncStackInner(void) +{ + // init unique stack table + if (!OHOS::HiviewDFX::UniqueStackTable::Instance()->Init()) { + DFXLOGE("failed to init unique stack table?."); + return; + } + + if (pthread_key_create(&g_stackidKey, nullptr) != 0) { + DFXLOGE("failed to create key for stackId."); + return; + } + g_fpBacktrace = OHOS::HiviewDFX::FpBacktrace::CreateInstance(); + DfxSetAsyncStackCallback(); + g_init = true; +} #endif + +bool DfxInitAsyncStack() +{ +#if defined(__aarch64__) + static once_flag onceFlag = ONCE_FLAG_INIT; + call_once(&onceFlag, DfxInitAsyncStackInner); +#endif + return g_init; + } extern "C" int DfxGetSubmitterStackLocal(char* stackTraceBuf, size_t bufferSize) diff --git a/interfaces/innerkits/async_stack/include/async_stack.h b/interfaces/innerkits/async_stack/include/async_stack.h index ca128aa06..a1856f970 100644 --- a/interfaces/innerkits/async_stack/include/async_stack.h +++ b/interfaces/innerkits/async_stack/include/async_stack.h @@ -22,15 +22,7 @@ extern "C" { #endif -// return stackId -uint64_t CollectAsyncStack(void); - -// set stack id to TLS -void SetStackId(uint64_t stackId); - -// get stack id from TLS -uint64_t GetStackId(void); - +bool DfxInitAsyncStack(); /** * @brief get submitter stack in local case * diff --git a/interfaces/innerkits/async_stack/libasync_stack.map b/interfaces/innerkits/async_stack/libasync_stack.map index 27aaddf2a..7a8a3c3ec 100644 --- a/interfaces/innerkits/async_stack/libasync_stack.map +++ b/interfaces/innerkits/async_stack/libasync_stack.map @@ -4,9 +4,7 @@ OHOS::HiviewDFX::UniqueStackTable*; }; extern "C" { - CollectAsyncStack; - SetStackId; - GetStackId; + DfxInitAsyncStack; DfxGetSubmitterStackLocal; }; local: diff --git a/test/unittest/async_stack/async_stack_test.cpp b/test/unittest/async_stack/async_stack_test.cpp index a1be0fd3e..cec30d802 100644 --- a/test/unittest/async_stack/async_stack_test.cpp +++ b/test/unittest/async_stack/async_stack_test.cpp @@ -115,39 +115,21 @@ HWTEST_F(AsyncStackTest, AsyncStackTest001, TestSize.Level2) /** * @tc.name: AsyncStackTest002 - * @tc.desc: test GetStackId() + * @tc.desc: test DfxInitAsyncStack() * @tc.type: FUNC */ HWTEST_F(AsyncStackTest, AsyncStackTest002, TestSize.Level2) { GTEST_LOG_(INFO) << "AsyncStackTest002: start."; - SetStackId(1); - auto res = GetStackId(); + bool res = DfxInitAsyncStack(); GTEST_LOG_(INFO) << "res: " << res; #if defined(__arm__) - ASSERT_EQ(0, res); + ASSERT_FALSE(res); #elif defined(__aarch64__) - ASSERT_NE(0, res); + ASSERT_TRUE(res); #endif GTEST_LOG_(INFO) << "AsyncStackTest002: end."; } - -/** - * @tc.name: AsyncStackTest003 - * @tc.desc: test CollectAsyncStack() - * @tc.type: FUNC - */ -HWTEST_F(AsyncStackTest, AsyncStackTest003, TestSize.Level0) -{ - GTEST_LOG_(INFO) << "AsyncStackTest003: start."; - auto ret = CollectAsyncStack(); -#if defined(__aarch64__) - ASSERT_NE(0, ret); -#else - ASSERT_EQ(0, ret); -#endif - GTEST_LOG_(INFO) << "AsyncStackTest003: end."; -} } // namespace HiviewDFX } // namepsace OHOS diff --git a/test/unittest/process_dump/submitter_stack_test.cpp b/test/unittest/process_dump/submitter_stack_test.cpp index 61fde80bd..9a96ecca9 100644 --- a/test/unittest/process_dump/submitter_stack_test.cpp +++ b/test/unittest/process_dump/submitter_stack_test.cpp @@ -71,8 +71,6 @@ namespace { HWTEST_F(SubmitterStackTest, SubmitterStackTest001, TestSize.Level2) { GTEST_LOG_(INFO) << "SubmitterStackTest001: start."; - uint64_t stackId = CollectAsyncStack(); - SetStackId(stackId); pid_t pid = fork(); if (pid < 0) { GTEST_LOG_(ERROR) << "Failed to fork new test process."; @@ -87,7 +85,7 @@ HWTEST_F(SubmitterStackTest, SubmitterStackTest001, TestSize.Level2) .tid = tid, .pid = pid, .nsPid = pid, - .stackId = GetStackId(), + .stackId = 0, }; DfxProcess process; process.InitProcessInfo(pid, nsPid, getuid(), ""); diff --git a/tools/crasher_cpp/dfx_crasher.cpp b/tools/crasher_cpp/dfx_crasher.cpp index 6a4a1e950..0baad5e76 100644 --- a/tools/crasher_cpp/dfx_crasher.cpp +++ b/tools/crasher_cpp/dfx_crasher.cpp @@ -143,10 +143,6 @@ constexpr static CrasherCommandLine CMDLINE_TABLE[] = { &DfxCrasher::TestGetCrashObj}, {"TestGetCrashObjMemory", "Test get memory info when crash", &DfxCrasher::TestGetCrashObjMemory}, -#ifndef is_ohos_lite - {"AsyncStack", "Test async stacktrace in nomal thread crash case", - &DfxCrasher::AsyncStacktrace}, -#endif {"Deadlock", "Test deadlock and parse lock owner", &DfxCrasher::TestDeadlock}, }; @@ -563,31 +559,6 @@ NOINLINE int DfxCrasher::TestGetCrashObjMemory() } #ifndef is_ohos_lite -static void* CrashInSubThread(void* stackIdPtr) -{ - uint64_t value = *reinterpret_cast(stackIdPtr); - SetStackId(value); - printf("CrashInSubThread stackId:%p value:%p.\n", stackIdPtr, reinterpret_cast(value)); - raise(SIGSEGV); - return nullptr; -} - -NOINLINE int DfxCrasher::AsyncStacktrace() -{ -#ifdef __aarch64__ - uint64_t stackId = CollectAsyncStack(); - printf("Current stackId:%p.\n", (void*)stackId); - pthread_t thread; - pthread_create(&thread, NULL, CrashInSubThread, (void*)&stackId); - void *result = nullptr; - pthread_join(thread, &result); - return reinterpret_cast(result); -#else - printf("Unsupported arch.\n"); - return 0; -#endif -} - NOINLINE static int FFRTTaskSubmit1(int i) { int inner = i + 1; -- Gitee