• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
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 "decoded/decoded_event.h"
17 
18 #include <functional>
19 #include <securec.h>
20 #include <sstream>
21 #include <unordered_map>
22 
23 #include "base/raw_data_base_def.h"
24 #include "decoded/raw_data_decoder.h"
25 #include "logger.h"
26 
27 namespace OHOS {
28 namespace HiviewDFX {
29 namespace EventRaw {
30 DEFINE_LOG_TAG("HiView-DecodedEvent");
31 namespace {
32 constexpr size_t MAX_BLOCK_SIZE = 384 * 1024; // 384K
33 
TransUInt64ToFixedLengthStr(uint64_t src)34 std::string TransUInt64ToFixedLengthStr(uint64_t src)
35 {
36     const size_t maxIdLen = 20;
37     std::string uint64Str = std::to_string(src);
38     if (uint64Str.size() >= maxIdLen) {
39         return uint64Str;
40     }
41     std::string dest(maxIdLen, '0');
42     dest.replace(maxIdLen - uint64Str.size(), uint64Str.size(), uint64Str);
43     return dest;
44 }
45 }
46 
DecodedEvent(uint8_t * src)47 DecodedEvent::DecodedEvent(uint8_t* src)
48 {
49     if (src == nullptr) {
50         return;
51     }
52     size_t blockSize = static_cast<size_t>(*(reinterpret_cast<int32_t*>(src)));
53     if (blockSize < GetValidDataMinimumByteCount() || blockSize > MAX_BLOCK_SIZE) {
54         HIVIEW_LOGE("size of raw data is %{public}zu, which is invalid.", blockSize);
55         return;
56     }
57     rawData_ = new(std::nothrow) uint8_t[blockSize];
58     if (rawData_ == nullptr) {
59         return;
60     }
61     auto ret = memcpy_s(rawData_, blockSize, src, blockSize);
62     if (ret != EOK) {
63         HIVIEW_LOGE("Decode memory copy failed, ret is %{public}d.", ret);
64         delete[] rawData_;
65         return;
66     }
67     Parse();
68 }
69 
~DecodedEvent()70 DecodedEvent::~DecodedEvent()
71 {
72     if (rawData_ != nullptr) {
73         delete[] rawData_;
74         rawData_ = nullptr;
75     }
76 }
77 
AppendBaseInfo(std::stringstream & ss)78 void DecodedEvent::AppendBaseInfo(std::stringstream& ss)
79 {
80     char* domain = new(std::nothrow) char[MAX_DOMAIN_LENGTH + 1];
81     if (domain == nullptr) {
82         return;
83     }
84     if (memcpy_s(domain, MAX_DOMAIN_LENGTH, header_.domain, MAX_DOMAIN_LENGTH) != EOK) {
85         delete[] domain;
86         return;
87     }
88     domain[MAX_DOMAIN_LENGTH] = '\0';
89     auto eventDomain = std::string(domain);
90     AppendValue(ss, BASE_INFO_KEY_DOMAIN, eventDomain);
91     delete[] domain;
92     char* name = new(std::nothrow) char[MAX_EVENT_NAME_LENGTH + 1];
93     if (name == nullptr) {
94         return;
95     }
96     if (memcpy_s(name, MAX_EVENT_NAME_LENGTH, header_.name, MAX_EVENT_NAME_LENGTH) != EOK) {
97         delete[] name;
98         return;
99     }
100     name[MAX_EVENT_NAME_LENGTH] = '\0';
101     auto eventName = std::string(name);
102     AppendValue(ss, BASE_INFO_KEY_NAME, eventName);
103     delete[] name;
104     AppendValue(ss, BASE_INFO_KEY_TYPE, (static_cast<int>(header_.type) + 1)); // header_.type is only 2 bits which has
105                                                                           // been subtracted 1 before wrote.
106     AppendValue(ss, BASE_INFO_KEY_TIME_STAMP, header_.timestamp);
107     auto timeZone = ParseTimeZone(static_cast<size_t>(header_.timeZone));
108     AppendValue(ss, BASE_INFO_KEY_TIME_ZONE, timeZone);
109     AppendValue(ss, BASE_INFO_KEY_PID, header_.pid);
110     AppendValue(ss, BASE_INFO_KEY_TID, header_.tid);
111     AppendValue(ss, BASE_INFO_KEY_UID, header_.uid);
112     AppendValue(ss, BASE_INFO_KEY_ID, TransUInt64ToFixedLengthStr(header_.id));
113     if (header_.isTraceOpened == 1) {
114         AppendValue(ss, BASE_INFO_KEY_TRACE_FLAG, static_cast<int>(traceInfo_.traceFlag));
115         AppendValue(ss, BASE_INFO_KEY_TRACE_ID, TransNumToHexStr(traceInfo_.traceId));
116         AppendValue(ss, BASE_INFO_KEY_SPAN_ID, TransNumToHexStr(traceInfo_.spanId));
117         AppendValue(ss, BASE_INFO_KEY_PARENT_SPAN_ID, TransNumToHexStr(traceInfo_.pSpanId));
118     }
119 }
120 
AppendCustomizedArrayParam(std::stringstream & ss,std::shared_ptr<DecodedParam> param)121 void DecodedEvent::AppendCustomizedArrayParam(std::stringstream& ss, std::shared_ptr<DecodedParam> param)
122 {
123     std::unordered_map<DataCodedType, std::function<void(std::shared_ptr<DecodedParam>)>> allFuncs = {
124         {DataCodedType::UNSIGNED_VARINT_ARRAY, std::bind([this, &ss](std::shared_ptr<DecodedParam> param) {
125                 std::vector<uint64_t> u64Vec;
126                 if (param->AsUint64Vec(u64Vec)) {
127                     this->AppendValue(ss, param->GetKey(), u64Vec);
128                 }
129             }, std::placeholders::_1)},
130         {DataCodedType::SIGNED_VARINT_ARRAY, std::bind([this, &ss](std::shared_ptr<DecodedParam> param) {
131                 std::vector<int64_t> i64Vec;
132                 if (param->AsInt64Vec(i64Vec)) {
133                     this->AppendValue(ss, param->GetKey(), i64Vec);
134                 }
135             }, std::placeholders::_1)},
136         {DataCodedType::FLOATING_ARRAY, std::bind([this, &ss](std::shared_ptr<DecodedParam> param) {
137                 std::vector<double> dVec;
138                 if (param->AsDoubleVec(dVec)) {
139                     this->AppendValue(ss, param->GetKey(), dVec);
140                 }
141             }, std::placeholders::_1)},
142         {DataCodedType::DSTRING_ARRAY, std::bind([this, &ss](std::shared_ptr<DecodedParam> param) {
143                 std::vector<std::string> strVec;
144                 if (param->AsStringVec(strVec)) {
145                     this->AppendValue(ss, param->GetKey(), strVec);
146                 }
147             }, std::placeholders::_1)},
148     };
149     auto iter = allFuncs.find(param->GetDataCodedType());
150     if (iter == allFuncs.end()) {
151         return;
152     }
153     iter->second(param);
154 }
155 
AppendCustomizedParam(std::stringstream & ss,std::shared_ptr<DecodedParam> param)156 void DecodedEvent::AppendCustomizedParam(std::stringstream& ss, std::shared_ptr<DecodedParam> param)
157 {
158     std::unordered_map<DataCodedType, std::function<void(std::shared_ptr<DecodedParam>)>> allFuncs = {
159         {DataCodedType::UNSIGNED_VARINT, std::bind([this, &ss](std::shared_ptr<DecodedParam> param) {
160                 uint64_t uint64DecodedVal;
161                 if (param->AsUint64(uint64DecodedVal)) {
162                     this->AppendValue(ss, param->GetKey(), uint64DecodedVal);
163                 }
164             }, std::placeholders::_1)},
165         {DataCodedType::SIGNED_VARINT, std::bind([this, &ss](std::shared_ptr<DecodedParam> param) {
166                 int64_t int64DecodedVal;
167                 if (param->AsInt64(int64DecodedVal)) {
168                     this->AppendValue(ss, param->GetKey(), int64DecodedVal);
169                 }
170             }, std::placeholders::_1)},
171         {DataCodedType::FLOATING, std::bind([this, &ss](std::shared_ptr<DecodedParam> param) {
172                 double dDecodedVal;
173                 if (param->AsDouble(dDecodedVal)) {
174                     this->AppendValue(ss, param->GetKey(), dDecodedVal);
175                 }
176             }, std::placeholders::_1)},
177         {DataCodedType::DSTRING, std::bind([this, &ss](std::shared_ptr<DecodedParam> param) {
178                 std::string strDecodedVal;
179                 if (param->AsString(strDecodedVal)) {
180                     this->AppendValue(ss, param->GetKey(), strDecodedVal);
181                 }
182             }, std::placeholders::_1)},
183     };
184     auto iter = allFuncs.find(param->GetDataCodedType());
185     if (iter == allFuncs.end()) {
186         return;
187     }
188     iter->second(param);
189 }
190 
AppendCustomizedParams(std::stringstream & ss)191 void DecodedEvent::AppendCustomizedParams(std::stringstream& ss)
192 {
193     for (auto param: allParams_) {
194         if (param == nullptr) {
195             continue;
196         }
197         std::vector<DataCodedType> noArrayEncodedTypes = {
198             DataCodedType::UNSIGNED_VARINT,
199             DataCodedType::SIGNED_VARINT,
200             DataCodedType::FLOATING,
201             DataCodedType::DSTRING,
202         };
203         if (find(noArrayEncodedTypes.begin(), noArrayEncodedTypes.end(), param->GetDataCodedType()) !=
204             noArrayEncodedTypes.end()) {
205             AppendCustomizedParam(ss, param);
206             continue;
207         }
208         AppendCustomizedArrayParam(ss, param);
209     }
210 }
211 
AsJsonStr()212 std::string DecodedEvent::AsJsonStr()
213 {
214     std::stringstream jsonStream;
215     jsonStream << "{";
216     AppendBaseInfo(jsonStream);
217     AppendCustomizedParams(jsonStream);
218     if (jsonStream.tellp() != 0) {
219         jsonStream.seekp(-1, std::ios_base::end);
220     }
221     jsonStream << "}";
222     return jsonStream.str();
223 }
224 
GetRawData()225 std::shared_ptr<RawData> DecodedEvent::GetRawData()
226 {
227     return std::make_shared<RawData>(rawData_, pos_);
228 }
229 
IsValid()230 bool DecodedEvent::IsValid()
231 {
232     return isValid_;
233 }
234 
GetHeader()235 const struct HiSysEventHeader& DecodedEvent::GetHeader()
236 {
237     return header_;
238 }
239 
GetTraceInfo()240 const struct TraceInfo& DecodedEvent::GetTraceInfo()
241 {
242     return traceInfo_;
243 }
244 
GetAllCustomizedValues()245 const std::vector<std::shared_ptr<DecodedParam>>& DecodedEvent::GetAllCustomizedValues()
246 {
247     return allParams_;
248 }
249 
Parse()250 void DecodedEvent::Parse()
251 {
252     isValid_ = true;
253     if (rawData_ == nullptr) {
254         isValid_ = false;
255         return;
256     }
257     pos_ = 0; // reset to 0
258     // decode block size
259     size_t blockSize = static_cast<size_t>(*(reinterpret_cast<int32_t*>(rawData_)));
260     pos_ += sizeof(int32_t);
261     ParseHeader(blockSize);
262     ParseCustomizedParams(blockSize);
263 }
264 
ParseHeader(const size_t maxLen)265 void DecodedEvent::ParseHeader(const size_t maxLen)
266 {
267     // decode event header
268     if ((pos_ + sizeof(struct HiSysEventHeader)) > maxLen) {
269         isValid_ = false;
270         return;
271     }
272     header_ = *(reinterpret_cast<struct HiSysEventHeader*>(rawData_ + pos_));
273     pos_ += sizeof(struct HiSysEventHeader);
274     // decode trace info
275     if (header_.isTraceOpened == 1) { // 1: include trace info, 0: exclude trace info
276         if (((pos_ + sizeof(struct TraceInfo)) > maxLen)) {
277             isValid_ = false;
278             return;
279         }
280         traceInfo_ = *(reinterpret_cast<struct TraceInfo*>(rawData_ + pos_));
281         pos_ += sizeof(struct TraceInfo);
282     }
283 }
284 
ParseCustomizedParams(const size_t maxLen)285 void DecodedEvent::ParseCustomizedParams(const size_t maxLen)
286 {
287     if ((pos_ + sizeof(int32_t)) > maxLen) {
288         isValid_ = false;
289         return;
290     }
291     auto paramCnt = static_cast<size_t>(*(reinterpret_cast<int32_t*>(rawData_ + pos_)));
292     pos_ += sizeof(int32_t);
293     while (paramCnt > 0) {
294         auto decodedParam = ParseCustomizedParam(maxLen);
295         if (decodedParam == nullptr || !(decodedParam->DecodeValue())) {
296             HIVIEW_LOGE("Value of customized parameter is decoded failed.");
297             isValid_ = false;
298             return;
299         }
300         pos_ = decodedParam->GetPosition();
301         allParams_.emplace_back(decodedParam);
302         --paramCnt;
303     }
304 }
305 
CreateFloatingNumTypeDecodedParam(const size_t maxLen,const std::string & key,bool isArray)306 std::shared_ptr<DecodedParam> DecodedEvent::CreateFloatingNumTypeDecodedParam(const size_t maxLen,
307     const std::string& key, bool isArray)
308 {
309     if (isArray) {
310         return std::make_shared<FloatingNumberDecodedArrayParam>(rawData_, maxLen, pos_, key);
311     }
312     return std::make_shared<FloatingNumberDecodedParam>(rawData_, maxLen, pos_, key);
313 }
314 
CreateSignedVarintTypeDecodedParam(const size_t maxLen,const std::string & key,bool isArray)315 std::shared_ptr<DecodedParam> DecodedEvent::CreateSignedVarintTypeDecodedParam(const size_t maxLen,
316     const std::string& key, bool isArray)
317 {
318     if (isArray) {
319         return std::make_shared<SignedVarintDecodedArrayParam>(rawData_, maxLen, pos_, key);
320     }
321     return std::make_shared<SignedVarintDecodedParam>(rawData_, maxLen, pos_, key);
322 }
323 
CreateStringTypeDecodedParam(const size_t maxLen,const std::string & key,bool isArray)324 std::shared_ptr<DecodedParam> DecodedEvent::CreateStringTypeDecodedParam(const size_t maxLen,
325     const std::string& key, bool isArray)
326 {
327     if (isArray) {
328         return std::make_shared<StringDecodedArrayParam>(rawData_, maxLen, pos_, key);
329     }
330     return std::make_shared<StringDecodedParam>(rawData_, maxLen, pos_, key);
331 }
332 
CreateUnsignedVarintTypeDecodedParam(const size_t maxLen,const std::string & key,bool isArray)333 std::shared_ptr<DecodedParam> DecodedEvent::CreateUnsignedVarintTypeDecodedParam(const size_t maxLen,
334     const std::string& key, bool isArray)
335 {
336     if (isArray) {
337         return std::make_shared<UnsignedVarintDecodedArrayParam>(rawData_, maxLen, pos_, key);
338     }
339     return std::make_shared<UnsignedVarintDecodedParam>(rawData_, maxLen, pos_, key);
340 }
341 
ParseCustomizedParam(const size_t maxLen)342 std::shared_ptr<DecodedParam> DecodedEvent::ParseCustomizedParam(const size_t maxLen)
343 {
344     std::string key;
345     if (!RawDataDecoder::StringValueDecoded(rawData_, maxLen, pos_, key)) {
346         isValid_ = false;
347         return nullptr;
348     }
349     struct ParamValueType valueType {
350         .isArray = 0,
351         .valueType = static_cast<uint8_t>(ValueType::UNKNOWN),
352         .valueByteCnt = 0,
353     };
354     if (!RawDataDecoder::ValueTypeDecoded(rawData_, maxLen, pos_, valueType)) {
355         isValid_ = false;
356         return nullptr;
357     }
358     std::shared_ptr<DecodedParam> ret = nullptr;
359     switch (ValueType(valueType.valueType)) {
360         case ValueType::STRING: {
361             ret = CreateStringTypeDecodedParam(maxLen, key, valueType.isArray == 1);
362             break;
363         }
364         case ValueType::FLOAT:
365         case ValueType::DOUBLE: {
366             ret = CreateFloatingNumTypeDecodedParam(maxLen, key, valueType.isArray == 1);
367             break;
368         }
369         case ValueType::UINT8:
370         case ValueType::UINT16:
371         case ValueType::UINT32:
372         case ValueType::UINT64: {
373             ret = CreateUnsignedVarintTypeDecodedParam(maxLen, key, valueType.isArray == 1);
374             break;
375         }
376         case ValueType::BOOL:
377         case ValueType::INT8:
378         case ValueType::INT16:
379         case ValueType::INT32:
380         case ValueType::INT64: {
381             ret = CreateSignedVarintTypeDecodedParam(maxLen, key, valueType.isArray == 1);
382             break;
383         }
384         default:
385             break;
386     }
387     return ret;
388 }
389 } // namespace EventRaw
390 } // namespace HiviewDFX
391 } // namespace OHOS