• 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 #ifndef DFX_TEST_UTIL_H
16 #define DFX_TEST_UTIL_H
17 
18 #include <string>
19 #include <vector>
20 #include <list>
21 #include <csignal>
22 #include <regex>
23 #include <sys/wait.h>
24 #include <thread>
25 #include <mutex>
26 #include <atomic>
27 #include <ctime>
28 
29 #define NOINLINE __attribute__((noinline))
30 
31 #define POWERMGR_NAME             "powermgr"
32 #define FOUNDATION_NAME           "foundation"
33 #define APPSPAWN_NAME             "appspawn"
34 #define TEST_BUNDLE_NAME          "com.example.myapplication"
35 #define TRUNCATE_TEST_BUNDLE_NAME "e.myapplication"
36 
37 
38 #if defined(__arm__)
39 #define REGISTERS           "r0:","r1:","r2:","r3:","r4:","r5:","r6:",\
40                             "r7:","r8:","r9:","r10:","fp:","ip:","sp:","lr:","pc:"
41 #define REGISTERS_NUM       16
42 #define REGISTER_FORMAT_LENGTH    8
43 #elif defined(__aarch64__)
44 #define REGISTERS           "x0:","x1:","x2:","x3:","x4:","x5:","x6:","x7:","x8:",\
45                             "x9:","x10:","x11:","x12:","x13:","x14:","x15:","x16:",\
46                             "x17:","x18:","x19:","x20:","x21:","x22:","x23:","x24:",\
47                             "x25:","x26:","x27:","x28:","x29:","lr:","sp:","pc:"
48 #define REGISTERS_NUM       33
49 #define REGISTER_FORMAT_LENGTH    16
50 #elif defined(__x86_64__)
51 #define REGISTERS           "rax:","rdx:","rcx:","rbx:","rsi:","rdi:","rbp:","rsp:",\
52                             "r8:","r9:","r10:","r11:","r12:","r13:","r14:","r15:","rip:"
53 #define REGISTERS_NUM       17
54 #define REGISTER_FORMAT_LENGTH    16
55 #endif
56 const char* const TEMP_DIR = "/data/log/faultlog/temp/";
57 
58 namespace OHOS {
59 namespace HiviewDFX {
60 class TestScopedPidReaper {
61 public:
TestScopedPidReaper(pid_t pid)62     explicit TestScopedPidReaper(pid_t pid) : pid_(pid) {}
~TestScopedPidReaper()63     ~TestScopedPidReaper() { Kill(pid_); }
64 
Kill(pid_t pid)65     static void Kill(pid_t pid)
66     {
67         if (pid <= 0) {
68             return;
69         }
70         kill(pid, SIGKILL);
71         waitpid(pid, nullptr, 0);
72     }
73 private:
74     pid_t pid_;
75 };
76 
77 enum CrasherType {
78     CRASHER_C,
79     CRASHER_CPP
80 };
81 
82 struct LineRule {
83     std::string regString;
84     std::regex lineReg;
85     size_t needMatchCnt{1};
86 
regStringLineRule87     explicit LineRule(std::string reg, size_t cnt = 1) : regString(reg), lineReg(std::regex(reg)), needMatchCnt(cnt) {}
88 };
89 
90 std::string ExecuteCommands(const std::string& cmds);
91 bool ExecuteCommands(const std::string& cmds, std::vector<std::string>& ress);
92 int GetProcessPid(const std::string& processName);
93 int LaunchTestHap(const std::string& abilityName, const std::string& bundleName);
94 void StopTestHap(const std::string& bundleName);
95 void InstallTestHap(const std::string& hapName);
96 void UninstallTestHap(const std::string& bundleName);
97 int CountLines(const std::string& fileName);
98 bool CheckProcessComm(int pid, const std::string& name);
99 int CheckKeyWords(const std::string& filePath, std::string *keywords, int length, int minRegIdx);
100 bool CheckContent(const std::string& content, const std::string& keyContent, bool checkExist);
101 int GetKeywordsNum(const std::string& msg, std::string *keywords, int length);
102 int GetKeywordCount(const std::string& msg, const std::string& keyword);
103 std::string GetDumpLogFileName(const std::string& prefix, const pid_t pid, const std::string& tempPath);
104 std::string GetCppCrashFileName(const pid_t pid, const std::string& tempPath = TEMP_DIR);
105 uint32_t GetSelfFdCount();
106 uint32_t GetSelfMapsCount();
107 uint64_t GetSelfMemoryCount();
108 void CheckResourceUsage(uint32_t fdCount, uint32_t mapsCount, uint64_t memCount);
109 std::string WaitCreateCrashFile(const std::string& prefix, pid_t pid, int retryCnt = 3);
110 std::string WaitCreateFile(const std::string& folder, std::regex& reg, time_t timeOut = 10);
111 bool CreatePipeFd(int (&fd)[2]);
112 void NotifyProcStart(int (&fd)[2]);
113 void WaitProcStart(int (&fd)[2]);
114 void CheckAndExit(bool hasFailure);
115 bool IsLinuxKernel();
116 bool CheckLineMatch(const std::string& filePath, std::list<LineRule>& rules);
117 
118 template<typename T>
119 class AsyncWorker {
120 public:
AsyncWorker(std::function<void (T &)> dataClean)121     explicit AsyncWorker(std::function<void(T&)> dataClean)
122         : thread_(), result_(), ready_(false), resultClean_(dataClean) {}
~AsyncWorker()123     ~AsyncWorker()
124     {
125         if (thread_.joinable()) {
126             thread_.join();
127         }
128     }
129 
130     // 启动异步任务(只能调用一次)
Start(std::function<T (void)> func)131     void Start(std::function<T(void)> func)
132     {
133         if (!started_.test_and_set()) {
134             thread_ = std::thread([this, func] { this->Task(func); });
135         }
136     }
137 
138     // 等待并获取结果
GetResult(std::chrono::seconds timeOut)139     T GetResult(std::chrono::seconds timeOut)
140     {
141         std::unique_lock<std::mutex> lock(mutex_);
142         if (!cv_.wait_for(lock, timeOut, [this] { return ready_; })) {
143             resultClean_(result_);
144         }
145         return result_;
146     }
147 
148 private:
Task(std::function<T (void)> func)149     void Task(std::function<T(void)> func)
150     {
151         T res = func();
152         {
153             std::lock_guard<std::mutex> lock(mutex_);
154             result_ = res;
155             ready_ = true;
156         }
157         cv_.notify_one();
158     }
159 
160     std::thread thread_;
161     std::mutex mutex_;
162     std::condition_variable cv_;
163     T result_;
164     bool ready_;
165     std::atomic_flag started_ = ATOMIC_FLAG_INIT;
166     std::function<void(T&)> resultClean_;
167 };
168 } // namespace HiviewDFX
169 } // namespace OHOS
170 #endif // DFX_TEST_UTIL
171