• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 #ifndef LPERF_EVENT_RECORD_H
16 #define LPERF_EVENT_RECORD_H
17 
18 #include <cstdint>
19 #include <linux/perf_event.h>
20 #include <securec.h>
21 #include <string>
22 #include "dfx_log.h"
23 
24 namespace OHOS {
25 namespace HiviewDFX {
26 constexpr uint32_t RECORD_SIZE_LIMIT = 65535;
27 constexpr ssize_t ERRINFOLEN = 512;
28 
29 struct LperfRecordSampleData {
30     uint32_t pid = 0;
31     uint32_t tid = 0;                       /* if PERF_SAMPLE_TID */
32     uint64_t time = 0;                      /* if PERF_SAMPLE_TIME */
33     uint64_t nr = 0;                        /* if PERF_SAMPLE_CALLCHAIN */
34     uint64_t* ips = nullptr;                /* if PERF_SAMPLE_CALLCHAIN */
35 };
36 
StringFormat(const char * fmt,...)37 inline std::string StringFormat(const char* fmt, ...)
38 {
39     va_list vargs;
40     char buf[1024] = {0}; // 1024: buf size
41     std::string format(fmt);
42     va_start(vargs, fmt);
43     if (vsnprintf_s(buf, sizeof(buf), sizeof(buf) - 1, format.c_str(), vargs) < 0) {
44         va_end(vargs);
45         return "";
46     }
47 
48     va_end(vargs);
49     return buf;
50 }
51 
52 class LperfRecordSample {
53 public:
54     LperfRecordSampleData data_ = {};
55     LperfRecordSample() = default;
56 
57     const char* GetName();
58     uint32_t GetType() const;
59     bool Init(uint8_t* data);
60     void Clear();
61 protected:
62     void InitHeader(uint8_t* data);
63 
64 private:
65     struct perf_event_header header_ = {};
66     uint64_t sampleType_ = PERF_SAMPLE_TID | PERF_SAMPLE_CALLCHAIN | PERF_SAMPLE_TIME;
67 };
68 
69 class LperfRecordFactory {
70 public:
71     static LperfRecordSample& GetLperfRecord(uint32_t type, uint8_t* data);
72     static void ClearData();
73 
74 private:
75     static LperfRecordSample record_;
76 };
77 
78 template<typename T>
79 bool PopFromBinary(bool condition, uint8_t*& data, T& dest, uint64_t& size);
80 
81 template<typename T1, typename T2>
82 bool PopFromBinary2(bool condition, uint8_t*& data, T1& dest1, T2& dest2, uint64_t& size);
83 
84 bool SetPointerOffset(uint8_t*& data, uint64_t offset, uint64_t& size);
85 
86 #define NO_RETVAL /* retval */
87 #ifndef CHECK_TRUE_AND_RET
88 #define CHECK_TRUE_AND_RET(condition, retval, fmt, ...)                                            \
89     do {                                                                                           \
90         if (!(condition)) [[unlikely]] {                                                           \
91             std::string str = StringFormat(fmt, ##__VA_ARGS__);                                    \
92             DFXLOGE("%{public}s", str.c_str());                                                    \
93             return retval;                                                                         \
94         }                                                                                          \
95     } while (0)
96 #endif
97 
98 #ifndef CHECK_ERR
99 #define CHECK_ERR(err, fmt, ...)                                                                   \
100     do {                                                                                           \
101         if (err < 0) [[unlikely]] {                                                                \
102             char errInfo[ERRINFOLEN] = { 0 };                                                      \
103             strerror_r(errno, errInfo, ERRINFOLEN);                                                \
104             DFXLOGE("%{public}s, error: %{public}d, errInfo: %{public}s",                          \
105                           StringFormat(fmt, ##__VA_ARGS__).c_str(), errno, errInfo);               \
106             return false;                                                                          \
107         }                                                                                          \
108     } while (0)
109 #endif
110 } // namespace HiviewDFX
111 } // namespace OHOS
112 #endif // LPERF_EVENT_RECORD_H