/* * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "appcapture_perf.h" #include #include #include #include "hisysevent.h" #include "lperf.h" #include "hilog_tag_wrapper.h" namespace OHOS { namespace AppExecFwk { const int32_t CAPTURE_DURATION = 1000; const int32_t FREQ = 100; const int32_t ERROR = -1; const int32_t NO_ERROR = 0; AppCapturePerf &AppCapturePerf::GetInstance() { static AppCapturePerf instance_; return instance_; } std::vector AppCapturePerf::SplitStr(const std::string &s, char delimiter) { std::vector tokens; std::string token; std::istringstream tokenStream(s); while (std::getline(tokenStream, token, delimiter)) { tokens.push_back(token); } return tokens; } int32_t AppCapturePerf::CapturePerf(const FaultData &faultData) { std::lock_guard lock(singletonMutex_); int64_t perfId = 0; auto ret = std::from_chars(faultData.timeoutMarkers.c_str(), faultData.timeoutMarkers.c_str() + faultData.timeoutMarkers.size(), perfId); if (ret.ec != std::errc()) { TAG_LOGE(AAFwkTag::APPDFR, "perfId stoi(%{public}s) failed", faultData.timeoutMarkers.c_str()); return ERROR; } std::vector tids; std::vector threads = SplitStr(faultData.errorObject.stack, ','); for (uint32_t i = 0; i < threads.size(); i++) { if (threads[i] == "") { continue; } int32_t tid = -1; auto res = std::from_chars(threads[i].c_str(), threads[i].c_str() + threads[i].size(), tid); if (res.ec != std::errc()) { TAG_LOGE(AAFwkTag::APPDFR, "tid conversion failed"); } tids.push_back(tid); } if (tids.empty()) { TAG_LOGE(AAFwkTag::APPDFR, "No valid thread IDs found"); return ERROR; } int res = 0; auto &instance = Developtools::HiPerf::HiPerfLocal::Lperf::GetInstance(); res = instance.StartProcessStackSampling(tids, FREQ, CAPTURE_DURATION, false); if (res != 0) { TAG_LOGE(AAFwkTag::APPDFR, "hiperf stack capture failed"); } std::vector perf; for (uint32_t i = 0; i < tids.size(); i++) { std::string info; res = instance.CollectSampleStackByTid(tids[i], info); if (res != 0) { perf.push_back(""); continue; } perf.push_back(info); } instance.FinishProcessStackSampling(); HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::AAFWK, "CPU_LOAD_CAPTURE_STACK", HiviewDFX::HiSysEvent::EventType::STATISTIC, "APP_NAME", faultData.errorObject.name, "TIDS", tids, "PERF", perf, "PERFID", perfId); return NO_ERROR; } } // namespace AppExecFwk } // namespace OHOS