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