1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2023. 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 #include "native_memory_profiler_sa_client_manager.h"
17
18 #include <cstdio>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <fcntl.h>
22 #include <iostream>
23 #include <unistd.h>
24 #include <sstream>
25
26 using namespace OHOS::Developtools::NativeDaemon;
27 const int ONLY_NMD = 2;
28 namespace {
TestDumpFile(const std::string postfix="")29 static uint32_t TestDumpFile(const std::string postfix = "")
30 {
31 uint32_t fd = static_cast<uint32_t>(open(("/data/local/tmp/test_dump_file" + postfix + ".htrace").c_str(),
32 O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
33 return fd;
34 }
35
IsNumeric(const std::string & str)36 bool IsNumeric(const std::string& str)
37 {
38 std::istringstream iss(str);
39 int number;
40 char trailingCharacter;
41 if (!(iss >> number)) {
42 return false;
43 }
44 if (iss >> trailingCharacter) {
45 return false;
46 }
47 return true;
48 }
49 }
50
main(int32_t argc,char * argv[])51 int32_t main(int32_t argc, char* argv[])
52 {
53 if (argc > 50) { // 50: max args size
54 printf("error too many args.\n");
55 return 0;
56 }
57 std::shared_ptr<NativeMemoryProfilerSaConfig> config = std::make_shared<NativeMemoryProfilerSaConfig>();
58 bool start = false;
59 bool stop = false;
60 bool error = false;
61 bool dumpData = false;
62 for (int32_t i = 1; i < argc; ++i) {
63 std::string arg(argv[i]);
64 if (arg == "--help" || arg == "-h") {
65 printf(" --start -s : start, default: false\n");
66 printf(" --stop -k : stop, default: false\n");
67 printf(" --pid -p : pid\n");
68 printf(" --filePath -f : filePath, default: ");
69 printf("/data/local/tmp/hiprofiler_data.htrace\n");
70 printf(" --duration -d : duration, default: 20s\n");
71 printf(" --filterSize -fs : filterSize, default: 0\n");
72 printf(" --shareMemorySize -sms : shareMemorySize, default: 16384\n");
73 printf(" --processName -pn : processName\n");
74 printf(" --maxStackDepth -msd : maxStackDepth, default: 30\n");
75 printf(" --mallocDisable -mad : mallocDisable, default: false\n");
76 printf(" --mmapDisable -mmd : mmapDisable, default: false\n");
77 printf(" --freeStackData -fsd : freeStackData, default: false\n");
78 printf(" --munmapStackData -musd : munmapStackData, default: false\n");
79 printf(" --mallocFreeMatchingInterval -mfmi : mallocFreeMatchingInterval\n");
80 printf(" --mallocFreeMatchingCnt -mfmc : mallocFreeMatchingCnt\n");
81 printf(" --disable_stringCompressed -sc : disable_stringCompressed, ");
82 printf("default: stringCompressed\n");
83 printf(" --dwarf -df : dwarf unwind, default: fp\n");
84 printf(" --disable_blocked -b : disable_blocked, default: blocked\n");
85 printf(" --disable_recordAccurately -ra : disable_recordAccurately, ");
86 printf("default: recordAccurately\n");
87 printf(" --startupMode -sm : startupMode, default: false\n");
88 printf(" --memtraceEnable -me : memtraceEnable, default: false\n");
89 printf(" --offlineSymbolization -os : offlineSymbolization, default: false\n");
90 printf(" --callframeCompress -cc : callframeCompress, default: false\n");
91 printf(" --statisticsInterval -si : statisticsInterval\n");
92 printf(" --clockId -c : clockId\n");
93 printf(" --dumpData -dd : dump data\n");
94 printf(" --sampleInterval -spi : sampleInterval, default: 0\n");
95 printf(" --jsStackReport -jr : jsStackReport, default: 0\n");
96 printf(" --maxJsStackDepth -mjsd : maxJsStackDepth, default: 0\n");
97 printf(" --filterNapiName -fnapi : filterNapiName \n");
98 printf(" --hookstandalone -hsa : hookstandalone \n");
99 printf(" --save_file -sf : save_file \n");
100 printf(" ----fileName -fn : file_name \n");
101 return 0;
102 }
103
104 if ((arg == "--start") || (arg == "-s")) {
105 start = true;
106 } else if ((arg == "--stop") || (arg == "-k")) {
107 stop = true;
108 } else if ((arg == "--pid") || (arg == "-p")) {
109 config->pid_ = i + 1 < argc && IsNumeric(argv[i + 1]) ? std::stoi(argv[++i]) : 0;
110 } else if ((arg == "--filePath") || (arg == "-f")) {
111 config->filePath_ = i + 1 < argc ? std::string(argv[++i]) : "";
112 } else if ((arg == "--duration") || (arg == "-d")) {
113 config->duration_ =
114 i + 1 < argc && IsNumeric(argv[i + 1]) ? static_cast<uint32_t>(std::stoi(argv[++i])) : 0;
115 } else if ((arg == "--filterSize") || (arg == "-fs")) {
116 config->filterSize_ = i + 1 < argc && IsNumeric(argv[i + 1]) ? std::stoi(argv[++i]) : 0;
117 } else if ((arg == "--shareMemorySize") || (arg == "-sms")) {
118 config->shareMemorySize_ =
119 i + 1 < argc && IsNumeric(argv[i + 1]) ? static_cast<uint32_t>(std::stoi(argv[++i])) : 0;
120 } else if ((arg == "--processName") || (arg == "-pn")) {
121 config->processName_ = i + 1 < argc ? std::string(argv[++i]) : "";
122 } else if ((arg == "--maxStackDepth") || (arg == "-msd")) {
123 config->maxStackDepth_ =
124 i + 1 < argc && IsNumeric(argv[i + 1]) ? static_cast<uint8_t>(std::stoi(argv[++i])) : 0;
125 } else if ((arg == "--mallocDisable") || (arg == "-mad")) {
126 config->mallocDisable_ = true;
127 } else if ((arg == "--mmapDisable") || (arg == "-mmd")) {
128 config->mmapDisable_ = true;
129 } else if ((arg == "--freeStackData") || (arg == "-fsd")) {
130 config->freeStackData_ = true;
131 } else if ((arg == "--munmapStackData") || (arg == "-musd")) {
132 config->munmapStackData_ = true;
133 } else if ((arg == "--mallocFreeMatchingInterval") || (arg == "-mfmi")) {
134 config->mallocFreeMatchingInterval_ =
135 i + 1 < argc && IsNumeric(argv[i + 1]) ? static_cast<uint32_t>(std::stoi(argv[++i])) : 0;
136 } else if ((arg == "--mallocFreeMatchingCnt") || (arg == "-mfmc")) {
137 config->mallocFreeMatchingCnt_ =
138 i + 1 < argc && IsNumeric(argv[i + 1]) ? static_cast<uint32_t>(std::stoi(argv[++i])) : 0;
139 } else if ((arg == "--disable_stringCompressed") || (arg == "-sc")) {
140 config->stringCompressed_ = false;
141 } else if ((arg == "--dwarf") || (arg == "-df")) {
142 config->fpUnwind_ = false;
143 } else if ((arg == "--disable_blocked") || (arg == "-b")) {
144 config->blocked_ = false;
145 } else if ((arg == "--disable_recordAccurately") || (arg == "-ra")) {
146 config->recordAccurately_ = false;
147 } else if ((arg == "--startupMode") || (arg == "-sm")) {
148 config->startupMode_ = true;
149 } else if ((arg == "--memtraceEnable") || (arg == "-me")) {
150 config->memtraceEnable_ = true;
151 } else if ((arg == "--onlineSymbolization") || (arg == "-os")) {
152 config->offlineSymbolization_ = false;
153 } else if ((arg == "--callframeCompress") || (arg == "-cc")) {
154 config->callframeCompress_ = true;
155 } else if ((arg == "--statisticsInterval") || (arg == "-si")) {
156 config->statisticsInterval_ =
157 i + 1 < argc && IsNumeric(argv[i + 1]) ? static_cast<uint32_t>(std::stoi(argv[++i])) : 0;
158 } else if ((arg == "--clockId") || (arg == "-c")) {
159 config->clockId_ = i + 1 < argc && IsNumeric(argv[i + 1]) ? std::stoi(argv[++i]) : 0;
160 } else if ((arg == "--dumpData") || (arg == "-dd")) {
161 dumpData = true;
162 } else if ((arg == "--sampleInterval ") || (arg == "-spi")) {
163 config->sampleInterval_ =
164 i + 1 < argc && IsNumeric(argv[i + 1]) ? static_cast<uint32_t>(std::stoi(argv[++i])) : 0;
165 } else if ((arg == "--responseLibraryMode") || (arg == "-r")) {
166 config->responseLibraryMode_ = true;
167 } else if ((arg == "--printNmd") || (arg == "-nmd")) {
168 config->printNmd_ = true;
169 } else if ((arg == "--jsStackReport") || (arg == "-jr")) {
170 config->jsStackReport_ =
171 i + 1 < argc && IsNumeric(argv[i + 1]) ? static_cast<int32_t>(std::stoi(argv[++i])) : 0;
172 } else if ((arg == "--maxJsStackDepth") || (arg == "-mjsd")) {
173 config->maxJsStackDepth_ =
174 i + 1 < argc && IsNumeric(argv[i + 1]) ? static_cast<uint8_t>(std::stoi(argv[++i])) : 0;
175 } else if ((arg == "--filterNapiName") || (arg == "-fnapi")) {
176 config->filterNapiName_ = i + 1 < argc ? std::string(argv[i + 1]) : "";
177 } else if ((arg == "--hookstandalone") || (arg == "-hsa")) {
178 config->hookstandalone_ = true;
179 } else if ((arg == "--save_file") || (arg == "-sf")) {
180 config->saveFile_ = true;
181 } else if ((arg == "--fileName") || (arg == "-fn")) {
182 config->fileName_ = i + 1 < argc ? std::string(argv[++i]) : "";
183 } else {
184 printf("error arg: %s\n", arg.c_str());
185 error = true;
186 break;
187 }
188 }
189
190 if (error) {
191 return 0;
192 }
193
194 if (start) {
195 std::cout << "start....." << std::endl;
196 if (config->printNmd_) {
197 uint32_t fdFirst = TestDumpFile(std::to_string(0));
198 NativeMemoryProfilerSaClientManager::GetMallocStats(fdFirst, config->pid_, ONLY_NMD, true);
199 close(fdFirst);
200 } else if (dumpData) {
201 uint32_t fd = TestDumpFile();
202 NativeMemoryProfilerSaClientManager::DumpData(fd, config);
203 close(fd);
204 } else {
205 NativeMemoryProfilerSaClientManager::Start(config);
206 }
207 } else if (stop) {
208 std::cout << "stop....." << std::endl;
209 if (config->pid_ > 0) {
210 NativeMemoryProfilerSaClientManager::Stop(config->pid_);
211 } else {
212 NativeMemoryProfilerSaClientManager::Stop(config->processName_);
213 }
214 } else {
215 printf("The start or stop parameter is not configured.\n");
216 }
217 return 0;
218 }