• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "panic_error_info_handle.h"
17 #include <sys/stat.h>
18 #include "securec.h"
19 #include "hiview_logger.h"
20 #include "parameters.h"
21 #include "string_util.h"
22 #include "time_util.h"
23 
24 namespace OHOS {
25 namespace HiviewDFX {
26 namespace PanicErrorInfoHandle {
27 DEFINE_LOG_LABEL(0xD002D11, "PanicErrorInfoHandle");
28 
29 using namespace std;
30 
31 namespace {
32 constexpr int EVENT_MAX_LEN = 32;
33 constexpr int CATEGORY_MAX_LEN = 32;
34 constexpr int MODULE_MAX_LEN = 32;
35 constexpr int TIMESTAMP_MAX_LEN = 24;
36 constexpr int ERROR_DESC_MAX_LEN = 512;
37 
38 constexpr const char* const HISTORY_LOG_PATH = "/data/log/bbox/history.log";
39 constexpr const char* const SYS_FS_PSTORE_PATH = "/sys/fs/pstore/blackbox-ramoops-0";
40 
41 /* fault category type */
42 constexpr const char* const CATEGORY_SYSTEM_REBOOT = "SYSREBOOT";
43 constexpr const char* const CATEGORY_SYSTEM_POWEROFF = "POWEROFF";
44 constexpr const char* const CATEGORY_SYSTEM_PANIC = "PANIC";
45 constexpr const char* const CATEGORY_SYSTEM_OOPS = "OOPS";
46 constexpr const char* const CATEGORY_SYSTEM_CUSTOM = "CUSTOM";
47 constexpr const char* const CATEGORY_SYSTEM_WATCHDOG = "HWWATCHDOG";
48 constexpr const char* const CATEGORY_SYSTEM_HUNGTASK = "HUNGTASK";
49 constexpr const char* const CATEGORY_SUBSYSTEM_CUSTOM = "CUSTOM";
50 
51 /* top category type */
52 constexpr const char* const TOP_CATEGORY_SYSTEM_RESET = "System Reset";
53 constexpr const char* const TOP_CATEGORY_FREEZE = "System Freeze";
54 constexpr const char* const TOP_CATEGORY_SYSTEM_POWEROFF = "POWEROFF";
55 constexpr const char* const TOP_CATEGORY_SUBSYSTEM_CRASH = "Subsystem Crash";
56 
57 /* module type */
58 constexpr const char* const MODULE_SYSTEM = "SYSTEM";
59 
60 /* fault event type */
61 constexpr const char* const EVENT_SYSREBOOT = "SYSREBOOT";
62 constexpr const char* const EVENT_LONGPRESS = "LONGPRESS";
63 constexpr const char* const EVENT_COMBINATIONKEY = "COMBINATIONKEY";
64 constexpr const char* const EVENT_SUBSYSREBOOT = "SUBSYSREBOOT";
65 constexpr const char* const EVENT_POWEROFF = "POWEROFF";
66 constexpr const char* const EVENT_PANIC = "PANIC";
67 constexpr const char* const EVENT_OOPS = "OOPS";
68 constexpr const char* const EVENT_SYS_WATCHDOG = "SYSWATCHDOG";
69 constexpr const char* const EVENT_HUNGTASK = "HUNGTASK";
70 }
71 
72 struct ErrorInfo {
73     char event[EVENT_MAX_LEN];
74     char category[CATEGORY_MAX_LEN];
75     char module[MODULE_MAX_LEN];
76     char errorTime[TIMESTAMP_MAX_LEN];
77     char errorDesc[ERROR_DESC_MAX_LEN];
78 };
79 
80 
81 struct ErrorInfoToCategory {
82     const char *module;
83     struct {
84         const char *event;
85         const char *category;
86         const char *topCategory;
87     } map;
88 };
89 
90 struct ErrorInfoToCategory g_errorInfoCategories[] = {
91     {
92         MODULE_SYSTEM,
93         {EVENT_SYSREBOOT, CATEGORY_SYSTEM_REBOOT, TOP_CATEGORY_SYSTEM_RESET}
94     },
95     {
96         MODULE_SYSTEM,
97         {EVENT_LONGPRESS, CATEGORY_SYSTEM_REBOOT, TOP_CATEGORY_SYSTEM_RESET}
98     },
99     {
100         MODULE_SYSTEM,
101         {EVENT_COMBINATIONKEY, CATEGORY_SYSTEM_REBOOT, TOP_CATEGORY_SYSTEM_RESET}
102     },
103     {
104         MODULE_SYSTEM,
105         {EVENT_SUBSYSREBOOT, CATEGORY_SYSTEM_REBOOT, TOP_CATEGORY_SYSTEM_RESET}
106     },
107     {
108         MODULE_SYSTEM,
109         {EVENT_POWEROFF, CATEGORY_SYSTEM_POWEROFF, TOP_CATEGORY_SYSTEM_POWEROFF}
110     },
111     {
112         MODULE_SYSTEM,
113         {EVENT_PANIC, CATEGORY_SYSTEM_PANIC, TOP_CATEGORY_SYSTEM_RESET}
114     },
115     {
116         MODULE_SYSTEM,
117         {EVENT_OOPS, CATEGORY_SYSTEM_OOPS, TOP_CATEGORY_SYSTEM_RESET}
118     },
119     {
120         MODULE_SYSTEM,
121         {EVENT_SYS_WATCHDOG, CATEGORY_SYSTEM_WATCHDOG, TOP_CATEGORY_FREEZE}
122     },
123     {
124         MODULE_SYSTEM,
125         {EVENT_HUNGTASK, CATEGORY_SYSTEM_HUNGTASK, TOP_CATEGORY_FREEZE}
126     },
127 };
128 
GetTopCategory(const char * module,const char * event)129 static const char *GetTopCategory(const char *module, const char *event)
130 {
131     if ((!module || !event)) {
132         HIVIEW_LOGE("module: %{public}s, event: %{public}s\n", module ? module : "NULL", event ? event : "NULL");
133         return TOP_CATEGORY_SUBSYSTEM_CRASH;
134     }
135     int i;
136     int count = sizeof(g_errorInfoCategories) / sizeof(ErrorInfoToCategory);
137     for (i = 0; i < count; i++) {
138         if (!strcmp(g_errorInfoCategories[i].module, module) &&
139             !strcmp(g_errorInfoCategories[i].map.event, event)) {
140                 return g_errorInfoCategories[i].map.topCategory;
141             }
142     }
143     if (!strcmp(module, MODULE_SYSTEM)) {
144         return TOP_CATEGORY_SYSTEM_RESET;
145     }
146     return TOP_CATEGORY_SUBSYSTEM_CRASH;
147 }
148 
GetCategory(const char * module,const char * event)149 static const char *GetCategory(const char *module, const char *event)
150 {
151     if ((!module || !event)) {
152         HIVIEW_LOGE("module: %{public}s, event: %{public}s\n", module ? module : "NULL", event ? event : "NULL");
153         return CATEGORY_SUBSYSTEM_CUSTOM;
154     }
155     int i;
156     int count = sizeof(g_errorInfoCategories) / sizeof(ErrorInfoToCategory);
157     for (i = 0; i < count; i++) {
158         if (!strcmp(g_errorInfoCategories[i].module, module) &&
159             !strcmp(g_errorInfoCategories[i].map.event, event)) {
160                 return g_errorInfoCategories[i].map.category;
161             }
162     }
163     if (!strcmp(module, MODULE_SYSTEM)) {
164         return CATEGORY_SYSTEM_CUSTOM;
165     }
166     return CATEGORY_SUBSYSTEM_CUSTOM;
167 }
168 
SaveHistoryLog(string bboxTime,string bboxSysreset,ErrorInfo * info)169 static void SaveHistoryLog(string bboxTime, string bboxSysreset, ErrorInfo* info)
170 {
171     ofstream fout;
172     fout.open(HISTORY_LOG_PATH, ios::out | ios::app);
173     if (!fout.is_open()) {
174         HIVIEW_LOGE("Failed to open file: %{public}s, error=%{public}d", HISTORY_LOG_PATH, errno);
175         return;
176     }
177     fout << "[" << GetTopCategory(info->module, info->event) << "],";
178     fout << "module[" << info->module << "],";
179     fout << "category[" << GetCategory(info->module, info->event) << "],";
180     fout << "event[" << info->event << "],";
181     fout << "time[" << bboxTime << "],";
182     fout << "sysreboot[" << bboxSysreset << "],";
183     fout << "errdesc[" << info->errorDesc << "],";
184     fout << "logpath[/data/log/bbox]";
185     fout << endl;
186     HIVIEW_LOGE("GetTopCategory: %{public}s, module: %{public}s",
187         GetTopCategory(info->module, info->event), info->module);
188     HIVIEW_LOGE("category: %{public}s, event: %{public}s",
189         GetCategory(info->module, info->event), info->event);
190     HIVIEW_LOGE("time: %{public}s, sysreboot: %{public}s, errorDesc: %{public}s",
191         bboxTime.c_str(), bboxSysreset.c_str(), info->errorDesc);
192 }
193 
TryCreateDir(const string & dir)194 static bool TryCreateDir(const string &dir)
195 {
196     struct stat info;
197 
198     if (stat(dir.c_str(), &info) != 0) {
199         constexpr mode_t defaultLogDirMode = 0770;
200         if (mkdir(dir.c_str(), defaultLogDirMode) != 0) {
201             HIVIEW_LOGE("dir: %{public}s create failed", dir.c_str());
202             return false;
203         }
204         HIVIEW_LOGI("dir: %{public}s create success", dir.c_str());
205         return true;
206     }
207 
208     if (info.st_mode & S_IFDIR) {
209         HIVIEW_LOGI("dir:%{public}s already existed", dir.c_str());
210         return true;
211     }
212     HIVIEW_LOGE("path: %{public}s is file not dir", dir.c_str());
213     return false;
214 }
215 
CopyPstoreFileToHistoryLog(ifstream & fin)216 static void CopyPstoreFileToHistoryLog(ifstream &fin)
217 {
218     uint64_t startTime = TimeUtil::GetMilliseconds() / TimeUtil::SEC_TO_MILLISEC;
219     string dirPath = "/data/log/bbox/" +
220         TimeUtil::TimestampFormatToDate(startTime, "%Y%m%d-%H%M%S") + "/";
221     if (!TryCreateDir(dirPath)) {
222         HIVIEW_LOGE("TryCreateDir failed. path: %{public}s", dirPath.c_str());
223         return;
224     }
225     string targetPath = dirPath + "last_kmsg";
226     ofstream fout;
227     fout.open(targetPath, ios::in | ios::out | ios::trunc);
228     if (!fout.is_open()) {
229         HIVIEW_LOGE("Failed to open file: %{public}s error=%{public}d", targetPath.c_str(), errno);
230         return;
231     }
232     fout << fin.rdbuf();
233     fout << endl;
234 }
235 
RKTransData(std::string bboxTime,std::string bboxSysreset)236 void RKTransData(std::string bboxTime, std::string bboxSysreset)
237 {
238     string deviceInfo = system::GetParameter("const.product.devicetype", "");
239     if (deviceInfo != "default") {
240         return;
241     }
242     ifstream fin(SYS_FS_PSTORE_PATH);
243     if (!fin.is_open()) {
244         HIVIEW_LOGE("Failed to open file: %{public}s, error=%{public}d", SYS_FS_PSTORE_PATH, errno);
245         return;
246     }
247     ErrorInfo info = {};
248     fin.read(reinterpret_cast<char* >(&info), sizeof(ErrorInfo));
249     if (!fin) {
250         HIVIEW_LOGE("Read error_info failed");
251         return;
252     }
253     SaveHistoryLog(bboxTime, bboxSysreset, &info);
254     CopyPstoreFileToHistoryLog(fin);
255 }
256 }
257 }
258 }
259