• 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 const int STACK_DATA_SIZE = 40000;
35 const int SPEED_UP_THRESHOLD = STACK_DATA_SIZE / 2;
36 const int SLOW_DOWN_THRESHOLD = STACK_DATA_SIZE / 4;
37 const 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 const uint32_t  MMAP_FILE_TYPE = (1u << 8);
44 // default max js stack depth
45 const int32_t DEFAULT_MAX_JS_STACK_DEPTH = 10;
46 }
47 }
48 }
49 
50 constexpr size_t MAX_REG_SIZE = sizeof(uint64_t)
51     * OHOS::Developtools::NativeDaemon::PERF_REG_ARM64_MAX;
52 constexpr size_t MAX_HOOK_PATH = 256;
53 
54 enum {
55     MALLOCDISABLE = (1u << 0),
56     MMAPDISABLE = (1u << 1),
57     FREEMSGSTACK = (1u << 2),
58     MUNMAPMSGSTACK = (1u << 3),
59     FPUNWIND = (1u << 4),
60     BLOCKED = (1u << 5),
61     MEMTRACE_ENABLE = (1u << 6),
62 };
63 
64 enum {
65     MALLOC_MSG = 0,
66     FREE_MSG,
67     MMAP_MSG,
68     MMAP_FILE_PAGE_MSG,
69     MUNMAP_MSG,
70     MEMORY_USING_MSG,
71     MEMORY_UNUSING_MSG,
72     MEMORY_TAG,
73     THREAD_NAME_MSG,
74     PR_SET_VMA_MSG,
75     JS_STACK_MSG,
76     NMD_MSG,
77     END_MSG,
78 };
79 
80 struct alignas(8) MmapFileRawData { // 8 is 8 bit
81     off_t offset;
82     uint32_t flags;
83 };
84 
85 struct alignas(8) BaseStackRawData { // 8 is 8 bit
86     union {
87         struct timespec ts;
88         MmapFileRawData mmapArgs;
89     };
90     void* addr;
91     size_t mallocSize;
92     uint64_t jsChainId;
93     uint32_t pid;
94     uint32_t tid;
95     uint16_t type;
96     uint16_t tagId;
97 };
98 
99 struct alignas(8) StackRawData: public BaseStackRawData { // 8 is 8 bit
100     union {
101         char regs[MAX_REG_SIZE];
102         uint64_t ip[MAX_UNWIND_DEPTH];
103     };
104 };
105 
106 struct alignas(8) NameData: public BaseStackRawData { // 8 is 8 bit
107     char name[MAX_HOOK_PATH + 1] {0};
108 };
109 
110 struct alignas(8) ReportEventBaseData { // 8 is 8 bit
111     ReportEventBaseData(const BaseStackRawData* baseData, uint32_t id = 0)
112     {
113         ts = baseData->ts;
114         addr = reinterpret_cast<uint64_t>(baseData->addr);
115         type = baseData->type;
116         tagId = baseData->tagId;
117         mallocSize = baseData->mallocSize;
118         tid = baseData->tid;
119         stackMapId = id;
120     }
121     struct timespec ts;
122     uint64_t addr : 40;
123     uint64_t type : 8;
124     uint64_t tagId : 16;
125     uint32_t mallocSize;
126     uint32_t tid;
127     uint32_t stackMapId;
128 };
129 
130 struct alignas(8) ArkTsClientConfig { // 8 is 8 bit
131         int32_t jsStackReport = 0;
132         uint8_t maxJsStackDepth = 0;
133         bool jsFpunwind = false;
134         char filterNapiName[64] = {""};
135 };
136 
137 struct alignas(8) ClientConfig { // 8 is 8 bit
ResetClientConfig138     void Reset()
139     {
140         filterSize = -1;
141         shareMemorySize = 0;
142         clockId = CLOCK_REALTIME;
143         maxStackDepth = 0;
144         statisticsInterval = 0;
145         sampleInterval = 0;
146         mallocDisable = false;
147         mmapDisable = false;
148         freeStackData = false;
149         munmapStackData = false;
150         fpunwind = false;
151         isBlocked = false;
152         memtraceEnable = false;
153         responseLibraryMode = false;
154         freeEventOnlyAddrEnable = false;
155         printNmd = false;
156         nmdType = -1;
157         isSaMode = false;
158         arktsConfig.jsStackReport = 0;
159         arktsConfig.maxJsStackDepth = 0;
160         arktsConfig.jsFpunwind = false;
161         arktsConfig.filterNapiName[0] = '\0';
162         largestSize = 0;
163         secondLargestSize = 0;
164         maxGrowthSize = 0;
165     }
166 
ToStringClientConfig167     std::string ToString()
168     {
169         std::stringstream ss;
170         ss << "filterSize:" << filterSize << ", shareMemorySize:" << shareMemorySize
171             << ", clockId:" << clockId << ", maxStackDepth:" << std::to_string(maxStackDepth)
172             << ", mallocDisable:" << mallocDisable << ", mmapDisable:" << mmapDisable
173             << ", freeStackData:" << freeStackData << ", munmapStackData:" << munmapStackData
174             << ", fpunwind:" << fpunwind << ", isBlocked:" << isBlocked << ", memtraceEnable:" << memtraceEnable
175             << ", sampleInterval: " << sampleInterval << ", responseLibraryMode: " << responseLibraryMode
176             << ", freeEventOnlyAddrEnable: " << freeEventOnlyAddrEnable << ", jsStackReport: "
177             << arktsConfig.jsStackReport << ", maxJsStackDepth: "
178             << std::to_string(arktsConfig.maxJsStackDepth) << ", filterNapiName: "
179             << arktsConfig.filterNapiName << ", jsFpunwind: " << arktsConfig.jsFpunwind
180             << ", largestSize: " << largestSize  << ", secondLargestSize: " << secondLargestSize
181             << ", maxGrowthSize: " << maxGrowthSize;
182         return ss.str();
183     }
184 
185     int32_t filterSize = -1;
186     uint32_t shareMemorySize = 0;
187     uint32_t sampleInterval = 0;
188     uint32_t statisticsInterval = 0;
189     clockid_t clockId = CLOCK_REALTIME;
190     uint8_t maxStackDepth = 0;
191     bool mallocDisable = false;
192     bool mmapDisable = false;
193     bool freeStackData = false;
194     bool munmapStackData = false;
195     bool fpunwind = false;
196     bool isBlocked = false;
197     bool memtraceEnable = false;
198     bool responseLibraryMode = false;
199     bool freeEventOnlyAddrEnable = false;
200     bool printNmd = false;
201     int nmdType = -1;
202     bool isSaMode = false;
203     ArkTsClientConfig arktsConfig = {0};
204     uint32_t largestSize = 0;
205     uint32_t secondLargestSize = 0;
206     uint32_t maxGrowthSize = 0;
207 };
208 #endif // HOOK_COMMON_H