• 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 #include "bytrace_module.h"
16 
17 #include <array>
18 #include <poll.h>
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 #include <sys/wait.h>
22 #include <unistd.h>
23 #include <vector>
24 
25 #include "bytrace_plugin_config.pb.h"
26 #include "logging.h"
27 #include "securec.h"
28 
29 namespace {
30 constexpr uint32_t MAX_BUFFER_SIZE = 4 * 1024 * 1024;
31 constexpr uint32_t READ_BUFFER_SIZE = 4096;
32 const std::string DEFAULT_FILE = "/local/data/tmp/bytrace.txt";
33 
34 std::mutex g_taskMutex;
35 
36 struct BytraceInfo {
37     bool isRoot;
38     uint32_t buffSize;
39     uint32_t time;
40     std::string clockType;
41     std::string outFile;
42     std::vector<std::string> categoryVec;
43 };
44 std::unique_ptr<BytraceInfo> g_bytraceInfo = nullptr;
45 
ParseConfig(const BytracePluginConfig & config)46 void ParseConfig(const BytracePluginConfig& config)
47 {
48     if (config.buffe_size() != 0) {
49         g_bytraceInfo->buffSize = config.buffe_size();
50     }
51     g_bytraceInfo->time =  config.time();
52     g_bytraceInfo->isRoot = config.is_root();
53     if (!config.clock().empty()) {
54         g_bytraceInfo->clockType = config.clock();
55     }
56     if (!config.outfile_name().empty()) {
57         g_bytraceInfo->outFile = config.outfile_name();
58     }
59     if (!config.categories().empty()) {
60         for (std::string category : config.categories()) {
61             g_bytraceInfo->categoryVec.push_back(category);
62         }
63     }
64 }
65 
RunCommand(const std::string & cmd)66 bool RunCommand(const std::string& cmd)
67 {
68     PROFILER_LOG_INFO(LOG_CORE, "%s:start running commond: %s", __func__, cmd.c_str());
69     return true;
70 }
71 
BeginTrace()72 bool BeginTrace()
73 {
74     // two case: real-time and offline type.
75     std::string beginCmd;
76     if (g_bytraceInfo->isRoot) {
77         beginCmd = "su root ";
78     }
79     beginCmd += "bytrace ";
80     if (g_bytraceInfo->buffSize != 0) {
81         beginCmd += " -b " + std::to_string(g_bytraceInfo->buffSize);
82     }
83     if (!g_bytraceInfo->clockType.empty()) {
84         beginCmd += " --trace_clock " + g_bytraceInfo->clockType;
85     }
86     // real-time: time is set 0.
87     if (g_bytraceInfo->time == 0) {
88         // if time is not set 1s(must >= 1), bytrace tool will use 5s by default.
89         beginCmd += " -t 1 ";
90         beginCmd += " --trace_begin ";
91     } else {
92         beginCmd += " -t " + std::to_string(g_bytraceInfo->time);
93         beginCmd += " -o ";
94         beginCmd += g_bytraceInfo->outFile;
95         beginCmd += " ";
96     }
97     for (const std::string& category : g_bytraceInfo->categoryVec) {
98         beginCmd += category;
99         beginCmd += " ";
100     }
101     return RunCommand(beginCmd);
102 }
103 
StopTrace()104 bool StopTrace()
105 {
106     std::string finishCmd;
107     if (g_bytraceInfo->isRoot) {
108         finishCmd = "su root ";
109     }
110     finishCmd += "bytrace --trace_finish --trace_dump";
111     if (g_bytraceInfo->outFile.empty()) {
112         g_bytraceInfo->outFile = DEFAULT_FILE;
113     }
114     finishCmd += " -o ";
115     finishCmd += g_bytraceInfo->outFile;
116     return RunCommand(finishCmd);
117 }
118 } // namespace
119 
BytracePluginSessionStart(const uint8_t * configData,const uint32_t configSize)120 int BytracePluginSessionStart(const uint8_t* configData, const uint32_t configSize)
121 {
122     std::lock_guard<std::mutex> guard(g_taskMutex);
123     BytracePluginConfig config;
124     int res = config.ParseFromArray(configData, configSize);
125     CHECK_TRUE(res, 0, "BytracePluginSessionStart, parse config FAILED! configSize: %u", configSize);
126     g_bytraceInfo = std::make_unique<BytraceInfo>();
127     ParseConfig(config);
128     res = BeginTrace();
129     CHECK_TRUE(res, 0, "BytracePluginSessionStart, bytrace begin FAILED!");
130     return 0;
131 }
132 
BytracePluginSessionStop()133 int BytracePluginSessionStop()
134 {
135     std::lock_guard<std::mutex> guard(g_taskMutex);
136     // real-time type need finish trace.
137     if (g_bytraceInfo->time == 0) {
138         int res = StopTrace();
139         CHECK_TRUE(res, 0, "BytracePluginSessionStop, bytrace finish FAILED!");
140     }
141     g_bytraceInfo = nullptr;
142     return 0;
143 }
144 
BytraceRegisterWriterStruct(const WriterStruct * writer)145 int BytraceRegisterWriterStruct(const WriterStruct* writer)
146 {
147     PROFILER_LOG_INFO(LOG_CORE, "%s:writer %p", __func__, writer);
148     return 0;
149 }
150 
151 static PluginModuleCallbacks g_callbacks = {
152     .onPluginSessionStart = BytracePluginSessionStart,
153     .onPluginReportResult = nullptr,
154     .onPluginSessionStop = BytracePluginSessionStop,
155     .onRegisterWriterStruct = BytraceRegisterWriterStruct,
156 };
157 
158 EXPORT_API PluginModuleStruct g_pluginModule = {
159     .callbacks = &g_callbacks,
160     .name = "bytrace_plugin",
161     .version = "1.02",
162     .resultBufferSizeHint = MAX_BUFFER_SIZE,
163 };