• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 
16 #include "hichecker.h"
17 
18 #include <csignal>
19 #include <sys/types.h>
20 #include <unistd.h>
21 
22 #include "dfx_dump_catcher.h"
23 #include "hilog/log_c.h"
24 #include "hilog/log_cpp.h"
25 
26 namespace OHOS {
27 namespace HiviewDFX {
28 std::mutex HiChecker::mutexLock_;
29 volatile bool HiChecker::checkMode_;
30 volatile uint64_t HiChecker::processRules_;
31 thread_local uint64_t HiChecker::threadLocalRules_;
32 
33 static constexpr HiLogLabel LABEL = { LOG_CORE, 0xD002D0B, "HICHECKER" };
34 
AddRule(uint64_t rule)35 void HiChecker::AddRule(uint64_t rule)
36 {
37     std::lock_guard<std::mutex> lock(mutexLock_);
38     if (!CheckRule(rule)) {
39         return;
40     }
41     if ((Rule::RULE_CHECK_SLOW_EVENT & rule)) {
42         checkMode_ = true;
43     }
44     threadLocalRules_ |= (Rule::ALL_THREAD_RULES | Rule::ALL_CAUTION_RULES) & rule;
45     processRules_ |= (Rule::ALL_PROCESS_RULES | Rule::ALL_CAUTION_RULES) & rule;
46 }
47 
RemoveRule(uint64_t rule)48 void HiChecker::RemoveRule(uint64_t rule)
49 {
50     std::lock_guard<std::mutex> lock(mutexLock_);
51     if (!CheckRule(rule)) {
52         return;
53     }
54     if ((Rule::RULE_CHECK_SLOW_EVENT & rule)) {
55         checkMode_ = false;
56     }
57     threadLocalRules_ ^= threadLocalRules_ & rule;
58     processRules_ ^= processRules_ & rule;
59 }
60 
GetRule()61 uint64_t HiChecker::GetRule()
62 {
63     std::lock_guard<std::mutex> lock(mutexLock_);
64     return (threadLocalRules_ | processRules_);
65 }
66 
Contains(uint64_t rule)67 bool HiChecker::Contains(uint64_t rule)
68 {
69     std::lock_guard<std::mutex> lock(mutexLock_);
70     if (!CheckRule(rule)) {
71         return false;
72     }
73     return rule == (rule & (threadLocalRules_ | processRules_));
74 }
75 
NotifySlowProcess(const std::string & tag)76 void HiChecker::NotifySlowProcess(const std::string& tag)
77 {
78     if ((threadLocalRules_ & Rule::RULE_THREAD_CHECK_SLOW_PROCESS) == 0) {
79         return;
80     }
81     std::string stackTrace;
82     DumpStackTrace(stackTrace);
83     Caution caution(Rule::RULE_THREAD_CHECK_SLOW_PROCESS,
84         "trigger:RULE_THREAD_CHECK_SLOW_PROCESS," + tag, stackTrace);
85     HandleCaution(caution);
86 }
87 
NotifySlowEvent(const std::string & tag)88 void HiChecker::NotifySlowEvent(const std::string& tag)
89 {
90     if ((processRules_ & Rule::RULE_CHECK_SLOW_EVENT) == 0) {
91         return;
92     }
93     std::string stackTrace;
94     DumpStackTrace(stackTrace);
95     Caution caution(Rule::RULE_CHECK_SLOW_EVENT,
96         "trigger:RULE_CHECK_SLOW_EVENT," + tag, stackTrace);
97     HandleCaution(caution);
98 }
99 
NotifyAbilityConnectionLeak(const Caution & caution)100 void HiChecker::NotifyAbilityConnectionLeak(const Caution& caution)
101 {
102     if ((processRules_ & Rule::RULE_CHECK_ABILITY_CONNECTION_LEAK) == 0) {
103         return;
104     }
105     HandleCaution(caution);
106 }
107 
HandleCaution(const Caution & caution)108 void HiChecker::HandleCaution(const Caution& caution)
109 {
110     uint64_t triggerRule = caution.GetTriggerRule();
111     if ((threadLocalRules_ & triggerRule)) {
112         CautionDetail cautionDetail(caution, threadLocalRules_);
113         OnThreadCautionFound(cautionDetail);
114         return;
115     }
116     if ((processRules_ & triggerRule)) {
117         CautionDetail cautionDetail(caution, processRules_);
118         OnProcessCautionFound(cautionDetail);
119         return;
120     }
121 }
122 
OnThreadCautionFound(CautionDetail & cautionDetail)123 void HiChecker::OnThreadCautionFound(CautionDetail& cautionDetail)
124 {
125     if ((cautionDetail.rules_ & Rule::ALL_CAUTION_RULES) == 0) {
126         cautionDetail.rules_ |= Rule::RULE_CAUTION_PRINT_LOG;
127     }
128     if (cautionDetail.CautionEnable(Rule::RULE_CAUTION_PRINT_LOG)
129         && !cautionDetail.CautionEnable(Rule::RULE_CAUTION_TRIGGER_CRASH)) {
130         PrintLog(cautionDetail);
131     }
132     if (cautionDetail.CautionEnable(Rule::RULE_CAUTION_TRIGGER_CRASH)) {
133         TriggerCrash(cautionDetail);
134     }
135 }
136 
OnProcessCautionFound(CautionDetail & cautionDetail)137 void HiChecker::OnProcessCautionFound(CautionDetail& cautionDetail)
138 {
139     OnThreadCautionFound(cautionDetail);
140 }
141 
PrintLog(const CautionDetail & cautionDetail)142 void HiChecker::PrintLog(const CautionDetail& cautionDetail)
143 {
144     HiLog::Info(LABEL,
145         "HiChecker caution with RULE_CAUTION_PRINT_LOG.\nCautionMsg:%{public}s\nStackTrace:\n%{public}s",
146         cautionDetail.caution_.GetCautionMsg().c_str(),
147         cautionDetail.caution_.GetStackTrace().c_str());
148 }
149 
TriggerCrash(const CautionDetail & cautionDetail)150 void HiChecker::TriggerCrash(const CautionDetail& cautionDetail)
151 {
152     HiLog::Info(LABEL,
153         "HiChecker caution with RULE_CAUTION_TRIGGER_CRASH; exit.\nCautionMsg:%{public}s\nStackTrace:\n%{public}s",
154         cautionDetail.caution_.GetCautionMsg().c_str(),
155         cautionDetail.caution_.GetStackTrace().c_str());
156     kill(getpid(), SIGABRT);
157 }
158 
NeedCheckSlowEvent()159 bool HiChecker::NeedCheckSlowEvent()
160 {
161     return checkMode_;
162 }
163 
HasCautionRule(uint64_t rules)164 bool HiChecker::HasCautionRule(uint64_t rules)
165 {
166     return (rules & Rule::ALL_CAUTION_RULES);
167 }
168 
DumpStackTrace(std::string & msg)169 void HiChecker::DumpStackTrace(std::string& msg)
170 {
171     DfxDumpCatcher dumplog;
172     if (!dumplog.DumpCatch(getpid(), gettid(), msg)) {
173         HiLog::Info(LABEL, "HiChecker DumpStackTrace fail.");
174     }
175 }
176 
CheckRule(uint64_t rule)177 bool HiChecker::CheckRule(uint64_t rule)
178 {
179     if (rule <= 0 || Rule::ALL_RULES != (Rule::ALL_RULES | rule)) {
180         HiLog::Info(LABEL, "input rule is not exist,please check.");
181         return false;
182     }
183     return true;
184 }
185 } // HiviewDFX
186 } // OHOS