diff --git a/interfaces/innerkits/unwinder/include/unwind_context.h b/interfaces/innerkits/unwinder/include/unwind_context.h index c1422a01f73764340ced85d24aeed127fc7507dc..b425cd16b63672f1fe7f63d89d4199a4448e6a37 100644 --- a/interfaces/innerkits/unwinder/include/unwind_context.h +++ b/interfaces/innerkits/unwinder/include/unwind_context.h @@ -65,7 +65,7 @@ struct UnwindContext { bool stackCheck = false; uintptr_t stackBottom = 0; uintptr_t stackTop = 0; - int pid; + int pid = 0; std::shared_ptr regs = nullptr; std::shared_ptr maps = nullptr; std::shared_ptr map = nullptr; diff --git a/interfaces/innerkits/unwinder/src/jsvm/dfx_jsvm.cpp b/interfaces/innerkits/unwinder/src/jsvm/dfx_jsvm.cpp index 7bacd17804c84e21f40ebf098fea2c9a5011d8b7..07f5707a2b2bf39775ffd3ce9b805c53456a18a3 100644 --- a/interfaces/innerkits/unwinder/src/jsvm/dfx_jsvm.cpp +++ b/interfaces/innerkits/unwinder/src/jsvm/dfx_jsvm.cpp @@ -106,14 +106,14 @@ int DfxJsvm::JsvmDestroyJsSymbolExtractor(uintptr_t extractorPtr) int DfxJsvm::ParseJsvmFrameInfo(uintptr_t pc, uintptr_t extractorPtr, JsvmFunction *jsvmFunction) { - if (parseJsvmFrameInfoFn_ != nullptr) { + if (parseJsvmFrameInfoFn_ != nullptr && jsvmFunction != nullptr) { return parseJsvmFrameInfoFn_(pc, extractorPtr, jsvmFunction); } const char* jsvmFuncName = "jsvm_parse_js_frame_info"; DlsymJsvmFunc(jsvmFuncName, parseJsvmFrameInfoFn_); - if (parseJsvmFrameInfoFn_ != nullptr) { + if (parseJsvmFrameInfoFn_ != nullptr && jsvmFunction != nullptr) { return parseJsvmFrameInfoFn_(pc, extractorPtr, jsvmFunction); } return -1; @@ -121,6 +121,10 @@ int DfxJsvm::ParseJsvmFrameInfo(uintptr_t pc, uintptr_t extractorPtr, JsvmFuncti int DfxJsvm::StepJsvmFrame(void *obj, ReadMemFunc readMemFn, JsvmStepParam* jsvmParam) { + if (obj == nullptr || readMemFn == nullptr || jsvmParam == nullptr) { + DFXLOGE("param is nullptr."); + return -1; + } if (stepJsvmFn_ != nullptr) { return stepJsvmFn_(obj, readMemFn, jsvmParam); } diff --git a/test/unittest/unwind/BUILD.gn b/test/unittest/unwind/BUILD.gn index 9b07401bf5478f7aa261a9a0251f2064c58f84dd..6d526a55c9ec2b33769c959b2e96e1b8ee0bc2f5 100644 --- a/test/unittest/unwind/BUILD.gn +++ b/test/unittest/unwind/BUILD.gn @@ -37,6 +37,7 @@ ohos_unittest("test_unwind") { "elf_test.cpp", "fp_unwinder_test.cpp", "instr_statistic_test.cpp", + "jsvm_test.cpp", "maps_test.cpp", "memory_test.cpp", "regs_test.cpp", diff --git a/test/unittest/unwind/jsvm_test.cpp b/test/unittest/unwind/jsvm_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a12a5170c24a0b52ca4ed827aff6075d7311ee8b --- /dev/null +++ b/test/unittest/unwind/jsvm_test.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +#include +#include +#include +#include + +#include "dfx_jsvm.h" +#include "dfx_log.h" + +using namespace testing; +using namespace testing::ext; +using namespace std; + +namespace OHOS { +namespace HiviewDFX { +bool g_jsvmEnable = false; + +class JsvmTest : public testing::Test { +public: + static void SetUpTestCase() {} + static void TearDownTestCase() {} + void SetUp() + { + std::string filePath; +#if defined(__arm__) + filePath = "/system/lib/ndk/libjsvm.so"; +#elif defined(__aarch64__) + filePath = "/system/lib64/ndk/libjsvm.so"; +#endif + g_jsvmEnable = filesystem::exists(filePath); + } + void TearDown() {} +}; + +/** + * @tc.name: JsvmTest001 + * @tc.desc: test JsvmCreateJsSymbolExtractor function + * @tc.type: FUNC + */ +HWTEST_F(JsvmTest, JsvmTest001, TestSize.Level2) +{ + GTEST_LOG_(INFO) << "JsvmTest001: start."; + uintptr_t extractorPtr = 0; + if (g_jsvmEnable) { + DfxJsvm::Instance().JsvmCreateJsSymbolExtractor(&extractorPtr, getpid()); + ASSERT_NE(DfxJsvm::Instance().jsvmCreateJsSymbolExtractorFn_, nullptr); + DfxJsvm::Instance().JsvmCreateJsSymbolExtractor(&extractorPtr, getpid()); + ASSERT_NE(DfxJsvm::Instance().jsvmCreateJsSymbolExtractorFn_, nullptr); + DfxJsvm::Instance().JsvmDestroyJsSymbolExtractor(extractorPtr); + ASSERT_NE(DfxJsvm::Instance().jsvmDestroyJsSymbolExtractorFn_, nullptr); + DfxJsvm::Instance().JsvmDestroyJsSymbolExtractor(extractorPtr); + ASSERT_NE(DfxJsvm::Instance().jsvmDestroyJsSymbolExtractorFn_, nullptr); + } else { + DfxJsvm::Instance().JsvmCreateJsSymbolExtractor(&extractorPtr, getpid()); + ASSERT_EQ(DfxJsvm::Instance().jsvmCreateJsSymbolExtractorFn_, nullptr); + DfxJsvm::Instance().JsvmDestroyJsSymbolExtractor(extractorPtr); + ASSERT_EQ(DfxJsvm::Instance().jsvmDestroyJsSymbolExtractorFn_, nullptr); + } + + GTEST_LOG_(INFO) << "JsvmTest001: end."; +} + +/** + * @tc.name: JsvmTest002 + * @tc.desc: test ParseJsvmFrameInfo function + * @tc.type: FUNC + */ +HWTEST_F(JsvmTest, JsvmTest002, TestSize.Level2) +{ + GTEST_LOG_(INFO) << "JsvmTest002: start."; + uintptr_t pc = 0; + uintptr_t extractorPtr = 0; + JsvmFunction *jsFunction = nullptr; + if (g_jsvmEnable) { + DfxJsvm::Instance().ParseJsvmFrameInfo(pc, extractorPtr, jsFunction); + ASSERT_NE(DfxJsvm::Instance().parseJsvmFrameInfoFn_, nullptr); + DfxJsvm::Instance().ParseJsvmFrameInfo(pc, extractorPtr, jsFunction); + ASSERT_NE(DfxJsvm::Instance().parseJsvmFrameInfoFn_, nullptr); + } else { + DfxJsvm::Instance().ParseJsvmFrameInfo(pc, extractorPtr, jsFunction); + ASSERT_EQ(DfxJsvm::Instance().parseJsvmFrameInfoFn_, nullptr); + } + + GTEST_LOG_(INFO) << "JsvmTest002: end."; +} + +/** + * @tc.name: JsvmTest003 + * @tc.desc: test StepJsvmFrame function + * @tc.type: FUNC + */ +HWTEST_F(JsvmTest, JsvmTest003, TestSize.Level2) +{ + GTEST_LOG_(INFO) << "JsvmTest003: start."; + void *obj = nullptr; + ReadMemFunc readMemFn = nullptr; + JsvmStepParam *jsvmParam = nullptr; + DfxJsvm::Instance().StepJsvmFrame(obj, readMemFn, jsvmParam); + ASSERT_EQ(DfxJsvm::Instance().stepJsvmFn_, nullptr); + GTEST_LOG_(INFO) << "JsvmTest003: end."; +} +} +} \ No newline at end of file