1 /* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #include <gtest/gtest.h> 16 17 #include <cstdio> 18 #include <dlfcn.h> 19 #include <cstdint> 20 21 #include "dfx_ark.h" 22 #include "dfx_log.h" 23 24 using namespace testing; 25 using namespace testing::ext; 26 using namespace std; 27 28 namespace OHOS { 29 namespace HiviewDFX { 30 namespace { 31 using RustDemangleFn = char*(*)(const char *); 32 RustDemangleFn g_rustDemangleFn = nullptr; 33 } // namespace 34 35 class ArkTest : public testing::Test { 36 public: SetUpTestCase()37 static void SetUpTestCase() {} TearDownTestCase()38 static void TearDownTestCase() {} SetUp()39 void SetUp() {} TearDown()40 void TearDown() {} 41 }; 42 43 /** 44 * @tc.name: ArkTest001 45 * @tc.desc: test ArkCreateJsSymbolExtractor functions 46 * @tc.type: FUNC 47 */ 48 HWTEST_F(ArkTest, ArkTest001, TestSize.Level2) 49 { 50 GTEST_LOG_(INFO) << "ArkTest001: start."; 51 uintptr_t zero = 0; 52 uintptr_t* extractorPtr = &zero; 53 DfxArk::Instance().ArkCreateJsSymbolExtractor(extractorPtr); 54 ASSERT_NE(DfxArk::Instance().arkCreateJsSymbolExtractorFn_, nullptr); 55 DfxArk::Instance().arkCreateJsSymbolExtractorFn_ = nullptr; 56 GTEST_LOG_(INFO) << "ArkTest001: end."; 57 } 58 59 /** 60 * @tc.name: ArkTest002 61 * @tc.desc: test ArkDestoryJsSymbolExtractor functions 62 * @tc.type: FUNC 63 */ 64 HWTEST_F(ArkTest, ArkTest002, TestSize.Level2) 65 { 66 GTEST_LOG_(INFO) << "ArkTest002: start."; 67 uintptr_t extractorPtr = 0; 68 DfxArk::Instance().ArkDestoryJsSymbolExtractor(extractorPtr); 69 ASSERT_NE(DfxArk::Instance().arkDestoryJsSymbolExtractorFn_, nullptr); 70 DfxArk::Instance().arkDestoryJsSymbolExtractorFn_ = nullptr; 71 GTEST_LOG_(INFO) << "ArkTest002: end."; 72 } 73 74 /** 75 * @tc.name: ArkTest003 76 * @tc.desc: test ParseArkFileInfo functions 77 * @tc.type: FUNC 78 */ 79 HWTEST_F(ArkTest, ArkTest003, TestSize.Level2) 80 { 81 GTEST_LOG_(INFO) << "ArkTest003: start."; 82 uintptr_t byteCodePc = 0; 83 uintptr_t mapBase = 0; 84 const char* name = nullptr; 85 uintptr_t extractorPtr = 0; 86 JsFunction *jsFunction = nullptr; 87 DfxArk::Instance().ParseArkFileInfo(byteCodePc, mapBase, name, extractorPtr, jsFunction); 88 ASSERT_NE(DfxArk::Instance().parseArkFileInfoFn_, nullptr); 89 DfxArk::Instance().parseArkFileInfoFn_ = nullptr; 90 GTEST_LOG_(INFO) << "ArkTest003: end."; 91 } 92 93 /** 94 * @tc.name: ArkTest004 95 * @tc.desc: test ParseArkFrameInfoLocal functions 96 * @tc.type: FUNC 97 */ 98 HWTEST_F(ArkTest, ArkTest004, TestSize.Level2) 99 { 100 GTEST_LOG_(INFO) << "ArkTest004: start."; 101 uintptr_t byteCodePc = 0; 102 uintptr_t mapBase = 0; 103 uintptr_t offset = 0; 104 JsFunction *jsFunction = nullptr; 105 DfxArk::Instance().ParseArkFrameInfoLocal(byteCodePc, mapBase, offset, jsFunction); 106 ASSERT_NE(DfxArk::Instance().parseArkFrameInfoLocalFn_, nullptr); 107 DfxArk::Instance().parseArkFrameInfoLocalFn_ = nullptr; 108 GTEST_LOG_(INFO) << "ArkTest004: end."; 109 } 110 111 /** 112 * @tc.name: ArkTest005 113 * @tc.desc: test ParseArkFrameInfo functions 114 * @tc.type: FUNC 115 */ 116 HWTEST_F(ArkTest, ArkTest005, TestSize.Level2) 117 { 118 GTEST_LOG_(INFO) << "ArkTest005: start."; 119 uintptr_t byteCodePc = 0; 120 uintptr_t mapBase = 0; 121 uintptr_t loadOffset = 0; 122 uint8_t *data = nullptr; 123 uint64_t dataSize = 0; 124 uintptr_t extractorPtr = 0; 125 JsFunction *jsFunction = nullptr; 126 DfxArk::Instance().ParseArkFrameInfo(byteCodePc, mapBase, loadOffset, data, dataSize, extractorPtr, jsFunction); 127 ASSERT_NE(DfxArk::Instance().parseArkFrameInfoFn_, nullptr); 128 DfxArk::Instance().parseArkFrameInfoFn_ = nullptr; 129 GTEST_LOG_(INFO) << "ArkTest005: end."; 130 } 131 132 /** 133 * @tc.name: ArkTest006 134 * @tc.desc: test StepArkFrame functions 135 * @tc.type: FUNC 136 */ 137 HWTEST_F(ArkTest, ArkTest006, TestSize.Level2) 138 { 139 GTEST_LOG_(INFO) << "ArkTest006: start."; 140 pid_t pid = fork(); 141 if (pid == 0) { 142 uintptr_t zero = 0; 143 void *obj = nullptr; 144 OHOS::HiviewDFX::ReadMemFunc readMemFn = nullptr; 145 uintptr_t *fp = &zero; 146 uintptr_t *sp = &zero; 147 uintptr_t *pc = &zero; 148 bool *isJsFrame = nullptr; 149 ArkStepParam arkParam(fp, sp, pc, isJsFrame); 150 DfxArk::Instance().StepArkFrame(obj, readMemFn, &arkParam); 151 ASSERT_NE(DfxArk::Instance().stepArkFn_, nullptr); 152 DfxArk::Instance().stepArkFn_ = nullptr; 153 ASSERT_NE(DfxArk::Instance().handle_, nullptr); 154 const char* arkCreateLocalFn = "ark_create_local"; 155 std::unique_lock<std::mutex> lock(DfxArk::Instance().arkMutex_); 156 *reinterpret_cast<void**>(&(DfxArk::Instance().arkCreateLocalFn_)) = dlsym(DfxArk::Instance().handle_, 157 arkCreateLocalFn); 158 ASSERT_NE(DfxArk::Instance().arkCreateLocalFn_, nullptr); 159 DfxArk::Instance().arkCreateLocalFn_(); 160 DfxArk::Instance().arkCreateLocalFn_ = nullptr; 161 const char* arkDestroyFuncName = "ark_destroy_local"; 162 *reinterpret_cast<void**>(&(DfxArk::Instance().arkDestroyLocalFn_)) = dlsym(DfxArk::Instance().handle_, 163 arkDestroyFuncName); 164 ASSERT_NE(DfxArk::Instance().arkDestroyLocalFn_, nullptr); 165 DfxArk::Instance().arkDestroyLocalFn_(); 166 DfxArk::Instance().arkDestroyLocalFn_ = nullptr; 167 exit(0); 168 } 169 int status; 170 bool isSuccess = waitpid(pid, &status, 0) != -1; 171 if (!isSuccess) { 172 ASSERT_FALSE(isSuccess); 173 } else { 174 int exitCode = -1; 175 if (WIFEXITED(status)) { 176 exitCode = WEXITSTATUS(status); 177 printf("Exit status was %d\n", exitCode); 178 } 179 ASSERT_EQ(exitCode, 0); 180 GTEST_LOG_(INFO) << "ArkTest006: end."; 181 } 182 } 183 184 /** 185 * @tc.name: ArkTest007 186 * @tc.desc: test StepArkFrameWithJit functions 187 * @tc.type: FUNC 188 */ 189 HWTEST_F(ArkTest, ArkTest007, TestSize.Level2) 190 { 191 GTEST_LOG_(INFO) << "ArkTest007: start."; 192 uintptr_t zero = 0; 193 void *ctx = &zero; 194 ReadMemFunc readMem = nullptr; 195 uintptr_t *fp = &zero; 196 uintptr_t *sp = &zero; 197 uintptr_t *pc = &zero; 198 uintptr_t *methodId = &zero; 199 bool *isJsFrame = nullptr; 200 std::vector<uintptr_t> vec; 201 std::vector<uintptr_t>& jitCache = vec; 202 OHOS::HiviewDFX::ArkUnwindParam ark(ctx, readMem, fp, sp, pc, methodId, isJsFrame, jitCache); 203 OHOS::HiviewDFX::ArkUnwindParam* arkPrama = &ark; 204 DfxArk::Instance().StepArkFrameWithJit(arkPrama); 205 ASSERT_NE(DfxArk::Instance().stepArkWithJitFn_, nullptr); 206 DfxArk::Instance().stepArkWithJitFn_ = nullptr; 207 GTEST_LOG_(INFO) << "ArkTest007: end."; 208 } 209 210 /** 211 * @tc.name: ArkTest008 212 * @tc.desc: test JitCodeWriteFile functions 213 * @tc.type: FUNC 214 */ 215 HWTEST_F(ArkTest, ArkTest008, TestSize.Level2) 216 { 217 GTEST_LOG_(INFO) << "ArkTest008: start."; 218 void* ctx = nullptr; 219 OHOS::HiviewDFX::ReadMemFunc readMemFn = nullptr; 220 int fd = -1; 221 const uintptr_t* const jitCodeArray = nullptr; 222 const size_t jitSize = 0; 223 DfxArk::Instance().JitCodeWriteFile(ctx, readMemFn, fd, jitCodeArray, jitSize); 224 ASSERT_NE(DfxArk::Instance().jitCodeWriteFileFn_, nullptr); 225 DfxArk::Instance().jitCodeWriteFileFn_ = nullptr; 226 GTEST_LOG_(INFO) << "ArkTest008: end."; 227 } 228 229 /** 230 * @tc.name: ArkTest009 231 * @tc.desc: test rustc_demangle functions 232 * @tc.type: FUNC 233 */ 234 HWTEST_F(ArkTest, ArkTest009, TestSize.Level2) 235 { 236 GTEST_LOG_(INFO) << "ArkTest009: start."; 237 void* handle = dlopen("librustc_demangle.z.so", RTLD_LAZY | RTLD_NODELETE); 238 ASSERT_TRUE(handle) << "Failed to dlopen librustc_demangle"; 239 g_rustDemangleFn = (RustDemangleFn)dlsym(handle, "rustc_demangle"); 240 ASSERT_TRUE(g_rustDemangleFn) << "Failed to dlsym rustc_demangle"; 241 std::string reason = "reason"; 242 const char *bufStr = reason.c_str(); 243 g_rustDemangleFn(bufStr); 244 g_rustDemangleFn = nullptr; 245 GTEST_LOG_(INFO) << "ArkTest009: end."; 246 } 247 } 248 }