• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
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 #ifndef HOOK_COMMON_H
17 #define HOOK_COMMON_H
18 
19 #if defined(HAVE_LIBUNWIND) && HAVE_LIBUNWIND
20 // for libunwind.h empty struct has size 0 in c, size 1 in c++
21 #define UNW_EMPTY_STRUCT uint8_t unused;
22 #include <libunwind.h>
23 #endif
24 
25 #include "register.h"
26 #include "utilities.h"
27 
28 #define MAX_THREAD_NAME (32)
29 #define MAX_UNWIND_DEPTH (100)
30 
31 namespace OHOS {
32 namespace Developtools {
33 namespace NativeDaemon {
34 constexpr int STACK_DATA_SIZE = 400000;
35 constexpr int SPEED_UP_THRESHOLD = STACK_DATA_SIZE / 2;
36 constexpr int SLOW_DOWN_THRESHOLD = STACK_DATA_SIZE / 4;
37 constexpr int32_t MIN_STACK_DEPTH = 6;
38 // filter two layers of dwarf stack in libnative_hook.z.so
39 const size_t FILTER_STACK_DEPTH = 2;
40 const size_t MAX_CALL_FRAME_UNWIND_SIZE = MAX_UNWIND_DEPTH + FILTER_STACK_DEPTH;
41 // dlopen function minimum stack depth
42 const int32_t DLOPEN_MIN_UNWIND_DEPTH = 5;
43 // default max js stack depth
44 const int32_t DEFAULT_MAX_JS_STACK_DEPTH = 10;
45 constexpr int SHARED_MEMORY_NUM = 3;
46 constexpr uint64_t DWARF_ERROR_ID = 999999;
47 constexpr uint64_t SIZE_MASK = 0xFFFFFF0000000000;
48 }
49 }
50 }
51 
52 constexpr size_t MAX_REG_SIZE = sizeof(uint64_t)
53     * OHOS::Developtools::NativeDaemon::PERF_REG_ARM64_MAX;
54 constexpr size_t MAX_HOOK_PATH = 256;
55 
56 enum {
57     MALLOCDISABLE = (1u << 0),
58     MMAPDISABLE = (1u << 1),
59     FREEMSGSTACK = (1u << 2),
60     MUNMAPMSGSTACK = (1u << 3),
61     FPUNWIND = (1u << 4),
62     BLOCKED = (1u << 5),
63     MEMTRACE_ENABLE = (1u << 6),
64 };
65 
66 enum {
67     MALLOC_MSG = 0,
68     FREE_MSG,
69     MMAP_MSG,
70     MMAP_FILE_PAGE_MSG,
71     MUNMAP_MSG,
72     MEMORY_USING_MSG,
73     MEMORY_UNUSING_MSG,
74     MEMORY_TAG,
75     THREAD_NAME_MSG,
76     PR_SET_VMA_MSG,
77     JS_STACK_MSG,
78     MMAP_FILE_TYPE,
79     NMD_MSG,
80     END_MSG,
81     FREE_MSG_SIMP,
82     UNKNOWN,
83 };
84 
85 enum SymbolType {
86     NATIVE_SYMBOL,
87     JS_SYMBOL,
88 };
89 
90 struct Range {
91     uint64_t start;
92     uint64_t end;
93 };
94 
95 struct alignas(8) MmapFileRawData { // 8 is 8 bit
96     off_t offset;
97     uint32_t flags;
98 };
99 
100 struct alignas(8) BaseStackRawData { // 8 is 8 bit
101     union {
102         struct timespec ts;
103         MmapFileRawData mmapArgs;
104     };
105     void* addr;
106     size_t mallocSize;
107     uint64_t jsChainId;
108     uint32_t pid;
109     uint32_t tid;
110     uint16_t type;
111     uint16_t tagId;
112 };
113 
114 struct alignas(8) StackRawData: public BaseStackRawData { // 8 is 8 bit
115     union {
116         char regs[MAX_REG_SIZE];
117         uint64_t ip[MAX_UNWIND_DEPTH];
118     };
119 };
120 
121 struct alignas(8) NameData: public BaseStackRawData { // 8 is 8 bit
122     char name[MAX_HOOK_PATH + 1] {0};
123 };
124 
125 struct alignas(8) ReportEventBaseData { // 8 is 8 bit
126     ReportEventBaseData(const BaseStackRawData* baseData, uint32_t id = 0)
127     {
128         ts = baseData->ts;
129         addr = reinterpret_cast<uint64_t>(baseData->addr);
130         type = baseData->type;
131         tagId = baseData->tagId;
132         mallocSize = baseData->mallocSize;
133         tid = baseData->tid;
134         stackMapId = id;
135     }
136     struct timespec ts;
137     uint64_t addr : 40;
138     uint64_t type : 8;
139     uint64_t tagId : 16;
140     uint32_t mallocSize;
141     uint32_t tid;
142     uint32_t stackMapId;
143 };
144 
145 struct alignas(8) ArkTsClientConfig { // 8 is 8 bit
146         int32_t jsStackReport = 0;
147         uint8_t maxJsStackDepth = 0;
148         bool jsFpunwind = false;
149         char filterNapiName[64] = {""};
150 };
151 
152 struct alignas(8) ClientConfig { // 8 is 8 bit
ResetClientConfig153     void Reset()
154     {
155         filterSize = -1;
156         shareMemorySize = 0;
157         clockId = CLOCK_REALTIME;
158         maxStackDepth = 0;
159         statisticsInterval = 0;
160         sampleInterval = 0;
161         mallocDisable = false;
162         mmapDisable = false;
163         freeStackData = false;
164         munmapStackData = false;
165         fpunwind = false;
166         isBlocked = false;
167         memtraceEnable = false;
168         responseLibraryMode = false;
169         freeEventOnlyAddrEnable = false;
170         printNmd = false;
171         nmdType = -1;
172         isSaMode = false;
173         offlineSymbolization = false;
174         arktsConfig.jsStackReport = 0;
175         arktsConfig.maxJsStackDepth = 0;
176         arktsConfig.jsFpunwind = false;
177         arktsConfig.filterNapiName[0] = '\0';
178         largestSize = 0;
179         secondLargestSize = 0;
180         maxGrowthSize = 0;
181         targetSoName = "";
182     }
183 
ToStringClientConfig184     std::string ToString()
185     {
186         std::stringstream ss;
187         ss << "filterSize:" << filterSize << ", shareMemorySize:" << shareMemorySize
188             << ", clockId:" << clockId << ", maxStackDepth:" << std::to_string(maxStackDepth)
189             << ", mallocDisable:" << mallocDisable << ", mmapDisable:" << mmapDisable
190             << ", freeStackData:" << freeStackData << ", munmapStackData:" << munmapStackData
191             << ", fpunwind:" << fpunwind << ", isBlocked:" << isBlocked << ", memtraceEnable:" << memtraceEnable
192             << ", sampleInterval: " << sampleInterval << ", responseLibraryMode: " << responseLibraryMode
193             << ", freeEventOnlyAddrEnable: " << freeEventOnlyAddrEnable << ", jsStackReport: "
194             << arktsConfig.jsStackReport << ", maxJsStackDepth: "
195             << std::to_string(arktsConfig.maxJsStackDepth) << ", filterNapiName: "
196             << arktsConfig.filterNapiName << ", jsFpunwind: " << arktsConfig.jsFpunwind
197             << ", largestSize: " << largestSize  << ", secondLargestSize: " << secondLargestSize
198             << ", maxGrowthSize: " << maxGrowthSize << ", offline:" << offlineSymbolization;
199         return ss.str();
200     }
201 
202     int32_t filterSize = -1;
203     uint32_t shareMemorySize = 0;
204     uint32_t sampleInterval = 0;
205     uint32_t statisticsInterval = 0;
206     clockid_t clockId = CLOCK_REALTIME;
207     uint8_t maxStackDepth = 0;
208     bool mallocDisable = false;
209     bool mmapDisable = false;
210     bool freeStackData = false;
211     bool munmapStackData = false;
212     bool fpunwind = false;
213     bool isBlocked = false;
214     bool memtraceEnable = false;
215     bool responseLibraryMode = false;
216     bool freeEventOnlyAddrEnable = false;
217     bool printNmd = false;
218     int nmdType = -1;
219     bool isSaMode = false;
220     bool offlineSymbolization = false;
221     ArkTsClientConfig arktsConfig = {0};
222     uint32_t largestSize = 0;
223     uint32_t secondLargestSize = 0;
224     uint32_t maxGrowthSize = 0;
225     std::string targetSoName;
226 };
227 #endif // HOOK_COMMON_H