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