• 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     int i;
132     int count = sizeof(g_errorInfoCategories) / sizeof(ErrorInfoToCategory);
133     if ((!module || !event)) {
134         HIVIEW_LOGE("module: %{public}p, event: %{public}p\n", module, event);
135         return TOP_CATEGORY_SUBSYSTEM_CRASH;
136     }
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     int i;
152     int count = sizeof(g_errorInfoCategories) / sizeof(ErrorInfoToCategory);
153 
154     if ((!module || !event)) {
155         HIVIEW_LOGE("module: %{public}p, event: %{public}p\n", module, event);
156         return CATEGORY_SUBSYSTEM_CUSTOM;
157     }
158     for (i = 0; i < count; i++) {
159         if (!strcmp(g_errorInfoCategories[i].module, module) &&
160             !strcmp(g_errorInfoCategories[i].map.event, event)) {
161                 return g_errorInfoCategories[i].map.category;
162             }
163     }
164     if (!strcmp(module, MODULE_SYSTEM)) {
165         return CATEGORY_SYSTEM_CUSTOM;
166     }
167     return CATEGORY_SUBSYSTEM_CUSTOM;
168 }
169 
SaveHistoryLog(string bboxTime,string bboxSysreset,ErrorInfo * info)170 static void SaveHistoryLog(string bboxTime, string bboxSysreset, ErrorInfo* info)
171 {
172     ofstream fout;
173     fout.open(HISTORY_LOG_PATH, ios::out | ios::app);
174     if (!fout.is_open()) {
175         HIVIEW_LOGE("Failed to open file: %{public}s, error=%{public}d", HISTORY_LOG_PATH, errno);
176         return;
177     }
178     fout << "[" << GetTopCategory(info->module, info->event) << "],";
179     fout << "module[" << info->module << "],";
180     fout << "category[" << GetCategory(info->module, info->event) << "],";
181     fout << "event[" << info->event << "],";
182     fout << "time[" << bboxTime << "],";
183     fout << "sysreboot[" << bboxSysreset << "],";
184     fout << "errdesc[" << info->errorDesc << "],";
185     fout << "logpath[/data/log/bbox]";
186     fout << endl;
187     HIVIEW_LOGE("GetTopCategory: %{public}s, module: %{public}s",
188         GetTopCategory(info->module, info->event), info->module);
189     HIVIEW_LOGE("category: %{public}s, event: %{public}s",
190         GetCategory(info->module, info->event), info->event);
191     HIVIEW_LOGE("time: %{public}s, sysreboot: %{public}s, errorDesc: %{public}s",
192         bboxTime.c_str(), bboxSysreset.c_str(), info->errorDesc);
193 }
194 
TryCreateDir(const string & dir)195 static bool TryCreateDir(const string &dir)
196 {
197     struct stat info;
198 
199     if (stat(dir.c_str(), &info) != 0) {
200         constexpr mode_t defaultLogDirMode = 0770;
201         if (mkdir(dir.c_str(), defaultLogDirMode) != 0) {
202             HIVIEW_LOGE("dir: %{public}s create failed", dir.c_str());
203             return false;
204         }
205         HIVIEW_LOGI("dir: %{public}s create success", dir.c_str());
206         return true;
207     }
208 
209     if (info.st_mode & S_IFDIR) {
210         HIVIEW_LOGI("dir:%{public}s already existed", dir.c_str());
211         return true;
212     }
213     HIVIEW_LOGE("path: %{public}s is file not dir", dir.c_str());
214     return false;
215 }
216 
CopyPstoreFileToHistoryLog(ifstream & fin)217 static void CopyPstoreFileToHistoryLog(ifstream &fin)
218 {
219     uint64_t startTime = TimeUtil::GetMilliseconds() / TimeUtil::SEC_TO_MILLISEC;
220     string dirPath = "/data/log/bbox/" +
221         TimeUtil::TimestampFormatToDate(startTime, "%Y%m%d-%H%M%S") + "/";
222     if (!TryCreateDir(dirPath)) {
223         HIVIEW_LOGE("TryCreateDir failed. path: %{public}s", dirPath.c_str());
224         return;
225     }
226     string targetPath = dirPath + "last_kmsg";
227     ofstream fout;
228     fout.open(targetPath, ios::in | ios::out | ios::trunc);
229     if (!fout.is_open()) {
230         HIVIEW_LOGE("Failed to open file: %{public}s error=%{public}d", targetPath.c_str(), errno);
231         return;
232     }
233     fout << fin.rdbuf();
234     fout << endl;
235 }
236 
RKTransData(std::string bboxTime,std::string bboxSysreset)237 void RKTransData(std::string bboxTime, std::string bboxSysreset)
238 {
239     string deviceInfo = system::GetParameter("const.product.devicetype", "");
240     if (deviceInfo != "default") {
241         return;
242     }
243     ifstream fin(SYS_FS_PSTORE_PATH);
244     if (!fin.is_open()) {
245         HIVIEW_LOGE("Failed to open file: %{public}s, error=%{public}d", SYS_FS_PSTORE_PATH, errno);
246         return;
247     }
248     ErrorInfo info = {};
249     fin.read(reinterpret_cast<char* >(&info), sizeof(ErrorInfo));
250     if (!fin) {
251         HIVIEW_LOGE("Read error_info failed");
252         return;
253     }
254     SaveHistoryLog(bboxTime, bboxSysreset, &info);
255     CopyPstoreFileToHistoryLog(fin);
256 }
257 }
258 }
259 }
260