1800b99b8Sopenharmony_ci/* 2800b99b8Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3800b99b8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4800b99b8Sopenharmony_ci * you may not use this file except in compliance with the License. 5800b99b8Sopenharmony_ci * You may obtain a copy of the License at 6800b99b8Sopenharmony_ci * 7800b99b8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8800b99b8Sopenharmony_ci * 9800b99b8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10800b99b8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11800b99b8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12800b99b8Sopenharmony_ci * See the License for the specific language governing permissions and 13800b99b8Sopenharmony_ci * limitations under the License. 14800b99b8Sopenharmony_ci */ 15800b99b8Sopenharmony_ci 16800b99b8Sopenharmony_ci#include "dfx_test_util.h" 17800b99b8Sopenharmony_ci 18800b99b8Sopenharmony_ci#include <fstream> 19800b99b8Sopenharmony_ci#include <iostream> 20800b99b8Sopenharmony_ci#include <sstream> 21800b99b8Sopenharmony_ci#include <unistd.h> 22800b99b8Sopenharmony_ci 23800b99b8Sopenharmony_ci#include "dfx_define.h" 24800b99b8Sopenharmony_ci#include <directory_ex.h> 25800b99b8Sopenharmony_ci#include "file_util.h" 26800b99b8Sopenharmony_ci#include <string_ex.h> 27800b99b8Sopenharmony_ci 28800b99b8Sopenharmony_cinamespace OHOS { 29800b99b8Sopenharmony_cinamespace HiviewDFX { 30800b99b8Sopenharmony_cinamespace { 31800b99b8Sopenharmony_ciconst int BUF_LEN = 128; 32800b99b8Sopenharmony_ci} 33800b99b8Sopenharmony_ci 34800b99b8Sopenharmony_cistd::string ExecuteCommands(const std::string& cmds) 35800b99b8Sopenharmony_ci{ 36800b99b8Sopenharmony_ci if (cmds.empty()) { 37800b99b8Sopenharmony_ci return ""; 38800b99b8Sopenharmony_ci } 39800b99b8Sopenharmony_ci FILE *procFileInfo = nullptr; 40800b99b8Sopenharmony_ci std::string cmdLog = ""; 41800b99b8Sopenharmony_ci procFileInfo = popen(cmds.c_str(), "r"); 42800b99b8Sopenharmony_ci if (procFileInfo == nullptr) { 43800b99b8Sopenharmony_ci perror("popen execute failed\n"); 44800b99b8Sopenharmony_ci return cmdLog; 45800b99b8Sopenharmony_ci } 46800b99b8Sopenharmony_ci char res[BUF_LEN] = { '\0' }; 47800b99b8Sopenharmony_ci while (fgets(res, sizeof(res), procFileInfo) != nullptr) { 48800b99b8Sopenharmony_ci cmdLog += res; 49800b99b8Sopenharmony_ci } 50800b99b8Sopenharmony_ci pclose(procFileInfo); 51800b99b8Sopenharmony_ci return cmdLog; 52800b99b8Sopenharmony_ci} 53800b99b8Sopenharmony_ci 54800b99b8Sopenharmony_cibool ExecuteCommands(const std::string& cmds, std::vector<std::string>& ress) 55800b99b8Sopenharmony_ci{ 56800b99b8Sopenharmony_ci if (cmds.empty()) { 57800b99b8Sopenharmony_ci return false; 58800b99b8Sopenharmony_ci } 59800b99b8Sopenharmony_ci 60800b99b8Sopenharmony_ci ress.clear(); 61800b99b8Sopenharmony_ci FILE *fp = nullptr; 62800b99b8Sopenharmony_ci fp = popen(cmds.c_str(), "r"); 63800b99b8Sopenharmony_ci if (fp == nullptr) { 64800b99b8Sopenharmony_ci perror("popen execute failed\n"); 65800b99b8Sopenharmony_ci return false; 66800b99b8Sopenharmony_ci } 67800b99b8Sopenharmony_ci 68800b99b8Sopenharmony_ci char res[BUF_LEN] = { '\0' }; 69800b99b8Sopenharmony_ci while (fgets(res, sizeof(res), fp) != nullptr) { 70800b99b8Sopenharmony_ci ress.push_back(std::string(res)); 71800b99b8Sopenharmony_ci } 72800b99b8Sopenharmony_ci pclose(fp); 73800b99b8Sopenharmony_ci return true; 74800b99b8Sopenharmony_ci} 75800b99b8Sopenharmony_ci 76800b99b8Sopenharmony_ciint GetProcessPid(const std::string& processName) 77800b99b8Sopenharmony_ci{ 78800b99b8Sopenharmony_ci std::string cmd = "pidof " + processName; 79800b99b8Sopenharmony_ci std::string pidStr = ExecuteCommands(cmd); 80800b99b8Sopenharmony_ci int32_t pid = 0; 81800b99b8Sopenharmony_ci std::stringstream pidStream(pidStr); 82800b99b8Sopenharmony_ci pidStream >> pid; 83800b99b8Sopenharmony_ci printf("the pid of process(%s) is %s \n", processName.c_str(), pidStr.c_str()); 84800b99b8Sopenharmony_ci return pid; 85800b99b8Sopenharmony_ci} 86800b99b8Sopenharmony_ci 87800b99b8Sopenharmony_ciint LaunchTestHap(const std::string& abilityName, const std::string& bundleName) 88800b99b8Sopenharmony_ci{ 89800b99b8Sopenharmony_ci std::string launchCmd = "/system/bin/aa start -a " + abilityName + " -b " + bundleName; 90800b99b8Sopenharmony_ci (void)ExecuteCommands(launchCmd); 91800b99b8Sopenharmony_ci sleep(2); // 2 : sleep 2s 92800b99b8Sopenharmony_ci return GetProcessPid(bundleName); 93800b99b8Sopenharmony_ci} 94800b99b8Sopenharmony_ci 95800b99b8Sopenharmony_civoid StopTestHap(const std::string& bundleName) 96800b99b8Sopenharmony_ci{ 97800b99b8Sopenharmony_ci std::string stopCmd = "/system/bin/aa force-stop " + bundleName; 98800b99b8Sopenharmony_ci (void)ExecuteCommands(stopCmd); 99800b99b8Sopenharmony_ci} 100800b99b8Sopenharmony_ci 101800b99b8Sopenharmony_civoid InstallTestHap(const std::string& hapName) 102800b99b8Sopenharmony_ci{ 103800b99b8Sopenharmony_ci std::string installCmd = "bm install -p " + hapName; 104800b99b8Sopenharmony_ci (void)ExecuteCommands(installCmd); 105800b99b8Sopenharmony_ci} 106800b99b8Sopenharmony_ci 107800b99b8Sopenharmony_civoid UninstallTestHap(const std::string& bundleName) 108800b99b8Sopenharmony_ci{ 109800b99b8Sopenharmony_ci std::string uninstallCmd = "bm uninstall -n " + bundleName; 110800b99b8Sopenharmony_ci (void)ExecuteCommands(uninstallCmd); 111800b99b8Sopenharmony_ci} 112800b99b8Sopenharmony_ci 113800b99b8Sopenharmony_ciint CountLines(const std::string& fileName) 114800b99b8Sopenharmony_ci{ 115800b99b8Sopenharmony_ci std::ifstream readFile; 116800b99b8Sopenharmony_ci readFile.open(fileName.c_str(), std::ios::in); 117800b99b8Sopenharmony_ci if (readFile.fail()) { 118800b99b8Sopenharmony_ci return 0; 119800b99b8Sopenharmony_ci } else { 120800b99b8Sopenharmony_ci int n = 0; 121800b99b8Sopenharmony_ci std::string tmpuseValue; 122800b99b8Sopenharmony_ci while (getline(readFile, tmpuseValue, '\n')) { 123800b99b8Sopenharmony_ci n++; 124800b99b8Sopenharmony_ci } 125800b99b8Sopenharmony_ci readFile.close(); 126800b99b8Sopenharmony_ci return n; 127800b99b8Sopenharmony_ci } 128800b99b8Sopenharmony_ci} 129800b99b8Sopenharmony_ci 130800b99b8Sopenharmony_cibool CheckProcessComm(int pid, const std::string& name) 131800b99b8Sopenharmony_ci{ 132800b99b8Sopenharmony_ci std::string cmd = "cat /proc/" + std::to_string(pid) + "/comm"; 133800b99b8Sopenharmony_ci std::string comm = ExecuteCommands(cmd); 134800b99b8Sopenharmony_ci size_t pos = comm.find('\n'); 135800b99b8Sopenharmony_ci if (pos != std::string::npos) { 136800b99b8Sopenharmony_ci comm.erase(pos, 1); 137800b99b8Sopenharmony_ci } 138800b99b8Sopenharmony_ci if (!strcmp(comm.c_str(), name.c_str())) { 139800b99b8Sopenharmony_ci return true; 140800b99b8Sopenharmony_ci } 141800b99b8Sopenharmony_ci return false; 142800b99b8Sopenharmony_ci} 143800b99b8Sopenharmony_ci 144800b99b8Sopenharmony_ciint CheckKeyWords(const std::string& filePath, std::string *keywords, int length, int minRegIdx) 145800b99b8Sopenharmony_ci{ 146800b99b8Sopenharmony_ci std::ifstream file; 147800b99b8Sopenharmony_ci file.open(filePath.c_str(), std::ios::in); 148800b99b8Sopenharmony_ci long lines = CountLines(filePath); 149800b99b8Sopenharmony_ci std::vector<std::string> t(lines * 4); // 4 : max string blocks of one line 150800b99b8Sopenharmony_ci int i = 0; 151800b99b8Sopenharmony_ci int j = 0; 152800b99b8Sopenharmony_ci std::string::size_type idx; 153800b99b8Sopenharmony_ci int count = 0; 154800b99b8Sopenharmony_ci int maxRegIdx = minRegIdx + REGISTERS_NUM + 1; 155800b99b8Sopenharmony_ci while (!file.eof()) { 156800b99b8Sopenharmony_ci file >> t.at(i); 157800b99b8Sopenharmony_ci idx = t.at(i).find(keywords[j]); 158800b99b8Sopenharmony_ci if (idx != std::string::npos) { 159800b99b8Sopenharmony_ci if (minRegIdx != -1 && j > minRegIdx && // -1 : do not check register value 160800b99b8Sopenharmony_ci j < maxRegIdx && t.at(i).size() < (REGISTER_FORMAT_LENGTH + 3)) { // 3 : register label length 161800b99b8Sopenharmony_ci count--; 162800b99b8Sopenharmony_ci } 163800b99b8Sopenharmony_ci count++; 164800b99b8Sopenharmony_ci j++; 165800b99b8Sopenharmony_ci if (j == length) { 166800b99b8Sopenharmony_ci break; 167800b99b8Sopenharmony_ci } 168800b99b8Sopenharmony_ci continue; 169800b99b8Sopenharmony_ci } 170800b99b8Sopenharmony_ci i++; 171800b99b8Sopenharmony_ci } 172800b99b8Sopenharmony_ci file.close(); 173800b99b8Sopenharmony_ci std::cout << "Matched keywords count: " << count << std::endl; 174800b99b8Sopenharmony_ci if (j < length) { 175800b99b8Sopenharmony_ci std::cout << "Not found keyword: " << keywords[j] << std::endl; 176800b99b8Sopenharmony_ci } 177800b99b8Sopenharmony_ci return count; 178800b99b8Sopenharmony_ci} 179800b99b8Sopenharmony_ci 180800b99b8Sopenharmony_cibool CheckContent(const std::string& content, const std::string& keyContent, bool checkExist) 181800b99b8Sopenharmony_ci{ 182800b99b8Sopenharmony_ci bool findKeyContent = false; 183800b99b8Sopenharmony_ci if (content.find(keyContent) != std::string::npos) { 184800b99b8Sopenharmony_ci findKeyContent = true; 185800b99b8Sopenharmony_ci } 186800b99b8Sopenharmony_ci 187800b99b8Sopenharmony_ci if (checkExist && !findKeyContent) { 188800b99b8Sopenharmony_ci printf("Failed to find: %s in %s\n", keyContent.c_str(), content.c_str()); 189800b99b8Sopenharmony_ci return false; 190800b99b8Sopenharmony_ci } 191800b99b8Sopenharmony_ci 192800b99b8Sopenharmony_ci if (!checkExist && findKeyContent) { 193800b99b8Sopenharmony_ci printf("Find: %s in %s\n", keyContent.c_str(), content.c_str()); 194800b99b8Sopenharmony_ci return false; 195800b99b8Sopenharmony_ci } 196800b99b8Sopenharmony_ci return true; 197800b99b8Sopenharmony_ci} 198800b99b8Sopenharmony_ci 199800b99b8Sopenharmony_ciint GetKeywordsNum(const std::string& msg, std::string *keywords, int length) 200800b99b8Sopenharmony_ci{ 201800b99b8Sopenharmony_ci int count = 0; 202800b99b8Sopenharmony_ci std::string::size_type idx; 203800b99b8Sopenharmony_ci for (int i = 0; i < length; i++) { 204800b99b8Sopenharmony_ci idx = msg.find(keywords[i]); 205800b99b8Sopenharmony_ci if (idx != std::string::npos) { 206800b99b8Sopenharmony_ci count++; 207800b99b8Sopenharmony_ci } 208800b99b8Sopenharmony_ci } 209800b99b8Sopenharmony_ci return count; 210800b99b8Sopenharmony_ci} 211800b99b8Sopenharmony_ci 212800b99b8Sopenharmony_cistd::string GetCppCrashFileName(const pid_t pid, const std::string& tempPath) 213800b99b8Sopenharmony_ci{ 214800b99b8Sopenharmony_ci std::string filePath = ""; 215800b99b8Sopenharmony_ci if (pid <= 0) { 216800b99b8Sopenharmony_ci return filePath; 217800b99b8Sopenharmony_ci } 218800b99b8Sopenharmony_ci std::string fileNamePrefix = "cppcrash-" + std::to_string(pid); 219800b99b8Sopenharmony_ci std::vector<std::string> files; 220800b99b8Sopenharmony_ci OHOS::GetDirFiles(tempPath, files); 221800b99b8Sopenharmony_ci for (const auto& file : files) { 222800b99b8Sopenharmony_ci if (file.find(fileNamePrefix) != std::string::npos) { 223800b99b8Sopenharmony_ci filePath = file; 224800b99b8Sopenharmony_ci break; 225800b99b8Sopenharmony_ci } 226800b99b8Sopenharmony_ci } 227800b99b8Sopenharmony_ci return filePath; 228800b99b8Sopenharmony_ci} 229800b99b8Sopenharmony_ci 230800b99b8Sopenharmony_ciuint64_t GetSelfMemoryCount() 231800b99b8Sopenharmony_ci{ 232800b99b8Sopenharmony_ci std::string path = "/proc/self/smaps_rollup"; 233800b99b8Sopenharmony_ci std::string content; 234800b99b8Sopenharmony_ci if (!OHOS::HiviewDFX::LoadStringFromFile(path, content)) { 235800b99b8Sopenharmony_ci printf("Failed to load path content: %s\n", path.c_str()); 236800b99b8Sopenharmony_ci return 0; 237800b99b8Sopenharmony_ci } 238800b99b8Sopenharmony_ci 239800b99b8Sopenharmony_ci std::vector<std::string> result; 240800b99b8Sopenharmony_ci OHOS::SplitStr(content, "\n", result); 241800b99b8Sopenharmony_ci auto iter = std::find_if(result.begin(), result.end(), 242800b99b8Sopenharmony_ci [] (const std::string& str) { 243800b99b8Sopenharmony_ci return str.find("Pss:") != std::string::npos; 244800b99b8Sopenharmony_ci }); 245800b99b8Sopenharmony_ci if (iter == result.end()) { 246800b99b8Sopenharmony_ci perror("Failed to find Pss.\n"); 247800b99b8Sopenharmony_ci return 0; 248800b99b8Sopenharmony_ci } 249800b99b8Sopenharmony_ci 250800b99b8Sopenharmony_ci std::string pss = *iter; 251800b99b8Sopenharmony_ci uint64_t retVal = 0; 252800b99b8Sopenharmony_ci for (size_t i = 0; i < pss.size(); i++) { 253800b99b8Sopenharmony_ci if (isdigit(pss[i])) { 254800b99b8Sopenharmony_ci retVal = atoi(&pss[i]); 255800b99b8Sopenharmony_ci break; 256800b99b8Sopenharmony_ci } 257800b99b8Sopenharmony_ci } 258800b99b8Sopenharmony_ci return retVal; 259800b99b8Sopenharmony_ci} 260800b99b8Sopenharmony_ci 261800b99b8Sopenharmony_ciuint32_t GetSelfMapsCount() 262800b99b8Sopenharmony_ci{ 263800b99b8Sopenharmony_ci std::string path = std::string(PROC_SELF_MAPS_PATH); 264800b99b8Sopenharmony_ci std::string content; 265800b99b8Sopenharmony_ci if (!OHOS::HiviewDFX::LoadStringFromFile(path, content)) { 266800b99b8Sopenharmony_ci printf("Failed to load path content: %s\n", path.c_str()); 267800b99b8Sopenharmony_ci return 0; 268800b99b8Sopenharmony_ci } 269800b99b8Sopenharmony_ci 270800b99b8Sopenharmony_ci std::vector<std::string> result; 271800b99b8Sopenharmony_ci OHOS::SplitStr(content, "\n", result); 272800b99b8Sopenharmony_ci return result.size(); 273800b99b8Sopenharmony_ci} 274800b99b8Sopenharmony_ci 275800b99b8Sopenharmony_ciuint32_t GetSelfFdCount() 276800b99b8Sopenharmony_ci{ 277800b99b8Sopenharmony_ci std::string path = "/proc/self/fd"; 278800b99b8Sopenharmony_ci std::vector<std::string> content; 279800b99b8Sopenharmony_ci OHOS::GetDirFiles(path, content); 280800b99b8Sopenharmony_ci return content.size(); 281800b99b8Sopenharmony_ci} 282800b99b8Sopenharmony_ci 283800b99b8Sopenharmony_civoid CheckResourceUsage(uint32_t fdCount, uint32_t mapsCount, uint64_t memCount) 284800b99b8Sopenharmony_ci{ 285800b99b8Sopenharmony_ci // check memory/fd/maps 286800b99b8Sopenharmony_ci auto curFdCount = GetSelfFdCount(); 287800b99b8Sopenharmony_ci printf("AfterTest Fd New: %u\n", curFdCount); 288800b99b8Sopenharmony_ci printf("Fd Old: %u\n", fdCount); 289800b99b8Sopenharmony_ci 290800b99b8Sopenharmony_ci auto curMapsCount = GetSelfMapsCount(); 291800b99b8Sopenharmony_ci printf("AfterTest Maps New: %u\n", curMapsCount); 292800b99b8Sopenharmony_ci printf("Maps Old: %u\n", mapsCount); 293800b99b8Sopenharmony_ci 294800b99b8Sopenharmony_ci auto curMemSize = GetSelfMemoryCount(); 295800b99b8Sopenharmony_ci printf("AfterTest Memory New: %lu\n", static_cast<unsigned long>(curMemSize)); 296800b99b8Sopenharmony_ci printf("Memory Old: %lu\n", static_cast<unsigned long>(memCount)); 297800b99b8Sopenharmony_ci} 298800b99b8Sopenharmony_ci} // namespace HiviewDFX 299800b99b8Sopenharmony_ci} // namespace OHOS