From 5bdcd089b0b57c00cd4b2feef294a3f3b90a2808 Mon Sep 17 00:00:00 2001 From: xlgitee Date: Fri, 1 Aug 2025 09:30:58 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dfork=E5=9C=BA=E6=99=AF?= =?UTF-8?q?=E4=B8=8B=EF=BC=8C=E5=8D=95=E4=BE=8B=E5=AF=BC=E8=87=B4=E5=BD=93?= =?UTF-8?q?=E5=89=8D=E5=AD=90=E8=BF=9B=E7=A8=8B=E6=A0=88=E8=8C=83=E5=9B=B4?= =?UTF-8?q?=E4=B8=8D=E6=9B=B4=E6=96=B0=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: xlgitee Change-Id: Iab447f343e5dd39ce599f2701357fd232cbe69fc --- common/dfxutil/stack_utils.cpp | 38 ++++++++++++++++++++------- common/dfxutil/stack_utils.h | 18 ++++++++++--- test/unittest/unwind/memory_test.cpp | 39 +++++++++++++++++++++++++++- 3 files changed, 81 insertions(+), 14 deletions(-) diff --git a/common/dfxutil/stack_utils.cpp b/common/dfxutil/stack_utils.cpp index ae344333b..ccf2ff6ea 100644 --- a/common/dfxutil/stack_utils.cpp +++ b/common/dfxutil/stack_utils.cpp @@ -18,25 +18,45 @@ #include #include #include +#include + #include "dfx_define.h" #include "stack_utils.h" namespace OHOS { namespace HiviewDFX { -StackUtils::StackUtils() -{ - ParseSelfMaps(); -} - StackUtils& StackUtils::Instance() { static StackUtils inst; return inst; } -bool StackUtils::GetMainStackRange(uintptr_t& stackBottom, uintptr_t& stackTop) const +bool StackUtils::InitStackRange() +{ + const pid_t selfPid = getpid(); + if (pid_.load(std::memory_order_acquire) == selfPid) { + return mainStack_.IsValid(); + } + + std::lock_guard lock(initMutex_); + + if (pid_.load(std::memory_order_relaxed) == selfPid) { + return mainStack_.IsValid(); + } + mainStack_.Clear(); + arkCode_.Clear(); + ParseSelfMaps(); + + if (mainStack_.IsValid()) { + pid_.store(selfPid, std::memory_order_release); + return true; + } + return false; +} + +bool StackUtils::GetMainStackRange(uintptr_t& stackBottom, uintptr_t& stackTop) { - if (!mainStack_.IsValid()) { + if (!InitStackRange()) { return false; } stackBottom = mainStack_.start; @@ -44,9 +64,9 @@ bool StackUtils::GetMainStackRange(uintptr_t& stackBottom, uintptr_t& stackTop) return true; } -bool StackUtils::GetArkStackRange(uintptr_t& start, uintptr_t& end) const +bool StackUtils::GetArkStackRange(uintptr_t& start, uintptr_t& end) { - if (!arkCode_.IsValid()) { + if (!InitStackRange() || !arkCode_.IsValid()) { return false; } start = arkCode_.start; diff --git a/common/dfxutil/stack_utils.h b/common/dfxutil/stack_utils.h index 2b47b4517..07209f84e 100644 --- a/common/dfxutil/stack_utils.h +++ b/common/dfxutil/stack_utils.h @@ -15,10 +15,12 @@ #ifndef STACK_UTILS_H #define STACK_UTILS_H +#include #include #include #include #include +#include namespace OHOS { namespace HiviewDFX { @@ -30,22 +32,30 @@ public: StackUtils(const StackUtils&) = delete; StackUtils& operator=(const StackUtils&) = delete; - bool GetMainStackRange(uintptr_t& stackBottom, uintptr_t& stackTop) const; - bool GetArkStackRange(uintptr_t& start, uintptr_t& end) const; + bool GetMainStackRange(uintptr_t& stackBottom, uintptr_t& stackTop); + bool GetArkStackRange(uintptr_t& start, uintptr_t& end); static bool GetSelfStackRange(uintptr_t& stackBottom, uintptr_t& stackTop); private: + StackUtils() = default; + void ParseSelfMaps(); + bool InitStackRange(); struct MapRange { bool IsValid() const { return start != 0 && start < end; } + void Clear() + { + start = 0; + end = 0; + } uintptr_t start{0}; uintptr_t end{0}; }; - StackUtils(); - void ParseSelfMaps(); MapRange mainStack_; MapRange arkCode_; + std::atomic pid_{0}; + std::mutex initMutex_; }; } // namespace HiviewDFX } // namespace OHOS diff --git a/test/unittest/unwind/memory_test.cpp b/test/unittest/unwind/memory_test.cpp index 2c2ba7739..89d48c95e 100644 --- a/test/unittest/unwind/memory_test.cpp +++ b/test/unittest/unwind/memory_test.cpp @@ -549,7 +549,7 @@ HWTEST_F(DfxMemoryTest, DfxMemoryTest015, TestSize.Level2) /** * @tc.name: DfxMemoryTest016 - * @tc.desc: test GetArkStackRange FUNC + * @tc.desc: test GetMainStackRange FUNC * @tc.type: FUNC */ HWTEST_F(DfxMemoryTest, DfxMemoryTest016, TestSize.Level2) @@ -613,6 +613,43 @@ HWTEST_F(DfxMemoryTest, DfxMemoryTest018, TestSize.Level2) ASSERT_EQ(ret, -1); GTEST_LOG_(INFO) << "DfxMemoryTest018: end."; } + +/** + * @tc.name: DfxMemoryTest019 + * @tc.desc: test GetMainStackRange FUNC + * @tc.type: FUNC + */ +HWTEST_F(DfxMemoryTest, DfxMemoryTest019, TestSize.Level2) +{ + GTEST_LOG_(INFO) << "DfxMemoryTest019: start."; + uintptr_t stackBottom {0}; + uintptr_t stackTop {0}; + auto &stackUtils = StackUtils::Instance(); + stackUtils.GetMainStackRange(stackBottom, stackTop); + pid_t pid = fork(); + if (pid == 0) { + uintptr_t childStackBottom {0}; + uintptr_t childStackTop {0}; + stackUtils.GetMainStackRange(childStackBottom, childStackTop); + EXPECT_EQ(stackUtils.pid_, getpid()); + EXPECT_NE(childStackBottom, 0); + EXPECT_NE(childStackTop, 0); + if (stackBottom == childStackBottom && stackTop == childStackTop) { + GTEST_LOG_(INFO) << "DfxMemoryTest019: stack range is same, exit."; + exit(0); + } + exit(1); + } else { + int status; + pid_t waitPid = wait(&status); + if (waitPid == -1) { + GTEST_LOG_(ERROR) << "DfxMemoryTest019: wait failed, exit."; + } + + EXPECT_EQ(WEXITSTATUS(status), 0); + GTEST_LOG_(INFO) << "DfxMemoryTest019: end."; + } +} } } // namespace HiviewDFX } // namespace OHOS -- Gitee