• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 
16 #include "dfx_ark.h"
17 
18 #include <algorithm>
19 #include <cstdio>
20 #include <cstdlib>
21 #include <dlfcn.h>
22 #include <pthread.h>
23 
24 #include "dfx_define.h"
25 #include "dfx_log.h"
26 #include "string_util.h"
27 
28 namespace OHOS {
29 namespace HiviewDFX {
30 namespace {
31 #undef LOG_DOMAIN
32 #undef LOG_TAG
33 #define LOG_DOMAIN 0xD002D11
34 #define LOG_TAG "DfxArk"
35 
36 static const char ARK_LIB_NAME[] = "libark_jsruntime.so";
37 
38 static void* g_handle = nullptr;
39 static pthread_mutex_t g_mutex;
40 static int (*g_getArkNativeFrameInfoFn)(int, uintptr_t*, uintptr_t*, uintptr_t*, JsFrame*, size_t&);
41 static int (*g_stepArkManagedNativeFrameFn)(int, uintptr_t*, uintptr_t*, uintptr_t*, char*, size_t);
42 static int (*g_getArkJsHeapCrashInfoFn)(int, uintptr_t *, uintptr_t *, int, char *, size_t);
43 }
44 
GetArkNativeFrameInfo(int pid,uintptr_t & pc,uintptr_t & fp,uintptr_t & sp,JsFrame * frames,size_t & size)45 int DfxArk::GetArkNativeFrameInfo(int pid, uintptr_t& pc, uintptr_t& fp, uintptr_t& sp, JsFrame* frames, size_t& size)
46 {
47     if (g_getArkNativeFrameInfoFn != nullptr) {
48         return g_getArkNativeFrameInfoFn(pid, &pc, &fp, &sp, frames, size);
49     }
50 
51     pthread_mutex_lock(&g_mutex);
52     if (g_getArkNativeFrameInfoFn != nullptr) {
53         pthread_mutex_unlock(&g_mutex);
54         return g_getArkNativeFrameInfoFn(pid, &pc, &fp, &sp, frames, size);
55     }
56 
57     if (g_handle == nullptr) {
58         g_handle = dlopen(ARK_LIB_NAME, RTLD_LAZY);
59         if (g_handle == nullptr) {
60             LOGU("Failed to load library(%s).", dlerror());
61             pthread_mutex_unlock(&g_mutex);
62             return -1;
63         }
64     }
65 
66     *(void**)(&g_getArkNativeFrameInfoFn) = dlsym(g_handle, "get_ark_native_frame_info");
67     if (!g_getArkNativeFrameInfoFn) {
68         LOGU("Failed to find symbol(%s).", dlerror());
69         g_handle = nullptr;
70         pthread_mutex_unlock(&g_mutex);
71         return -1;
72     }
73 
74     pthread_mutex_unlock(&g_mutex);
75     return g_getArkNativeFrameInfoFn(pid, &pc, &fp, &sp, frames, size);
76 }
77 
StepArkManagedNativeFrame(int pid,uintptr_t & pc,uintptr_t & fp,uintptr_t & sp,char * buf,size_t bufSize)78 int DfxArk::StepArkManagedNativeFrame(int pid, uintptr_t& pc, uintptr_t& fp, uintptr_t& sp, char* buf, size_t bufSize)
79 {
80     if (g_stepArkManagedNativeFrameFn != nullptr) {
81         return g_stepArkManagedNativeFrameFn(pid, &pc, &fp, &sp, buf, bufSize);
82     }
83 
84     pthread_mutex_lock(&g_mutex);
85     if (g_stepArkManagedNativeFrameFn != nullptr) {
86         pthread_mutex_unlock(&g_mutex);
87         return g_stepArkManagedNativeFrameFn(pid, &pc, &fp, &sp, buf, bufSize);
88     }
89 
90     if (g_handle == nullptr) {
91         g_handle = dlopen(ARK_LIB_NAME, RTLD_LAZY);
92         if (g_handle == nullptr) {
93             LOGU("Failed to load library(%s).", dlerror());
94             pthread_mutex_unlock(&g_mutex);
95             return -1;
96         }
97     }
98 
99     *(void**)(&g_stepArkManagedNativeFrameFn) = dlsym(g_handle, "step_ark_managed_native_frame");
100     if (!g_stepArkManagedNativeFrameFn) {
101         LOGU("Failed to find symbol(%s).", dlerror());
102         g_handle = nullptr;
103         pthread_mutex_unlock(&g_mutex);
104         return -1;
105     }
106 
107     pthread_mutex_unlock(&g_mutex);
108     return g_stepArkManagedNativeFrameFn(pid, &pc, &fp, &sp, buf, bufSize);
109 }
110 
GetArkJsHeapCrashInfo(int pid,uintptr_t & x20,uintptr_t & fp,int outJsInfo,char * buf,size_t bufSize)111 int DfxArk::GetArkJsHeapCrashInfo(int pid, uintptr_t& x20, uintptr_t& fp, int outJsInfo, char* buf, size_t bufSize)
112 {
113     if (g_getArkJsHeapCrashInfoFn != nullptr) {
114         return g_getArkJsHeapCrashInfoFn(pid, &x20, &fp, outJsInfo, buf, bufSize);
115     }
116 
117     pthread_mutex_lock(&g_mutex);
118     if (g_getArkJsHeapCrashInfoFn != nullptr) {
119         pthread_mutex_unlock(&g_mutex);
120         return g_getArkJsHeapCrashInfoFn(pid, &x20, &fp, outJsInfo, buf, bufSize);
121     }
122 
123     if (g_handle == nullptr) {
124         g_handle = dlopen(ARK_LIB_NAME, RTLD_LAZY);
125         if (g_handle == nullptr) {
126             LOGU("Failed to load library(%s).", dlerror());
127             pthread_mutex_unlock(&g_mutex);
128             return -1;
129         }
130     }
131 
132     *(void**)(&g_getArkJsHeapCrashInfoFn) = dlsym(g_handle, "get_ark_js_heap_crash_info");
133     if (!g_getArkJsHeapCrashInfoFn) {
134         LOGU("Failed to find symbol(%s).", dlerror());
135         g_handle = nullptr;
136         pthread_mutex_unlock(&g_mutex);
137         return -1;
138     }
139 
140     pthread_mutex_unlock(&g_mutex);
141     return g_getArkJsHeapCrashInfoFn(pid, &x20, &fp, outJsInfo, buf, bufSize);
142 }
143 } // namespace HiviewDFX
144 } // namespace OHOS
145