Skip to content

Commit c1f2ba3

Browse files
lauxinwlijinxia
authored andcommitted
tools: acrn-crashlog: crash reclassify operations for acrnprobe
Reclassify an event according to its trigger file's content. Signed-off-by: Liu Xinwu <xinwu.liu@intel.com> Reviewed-by: Zhang Yanmin <yanmin.zhang@intel.com> Reviewed-by: Liu Chuansheng <chuansheng.liu@intel.com> Reviewed-by: Zhao Yakui <yakui.zhao@intel.com> Reviewed-by: Geoffroy Van Cutsem <geoffroy.vancutsem@intel.com> Acked-by: Eddie Dong <Eddie.dong@intel.com>
1 parent 168d3ea commit c1f2ba3

File tree

1 file changed

+284
-0
lines changed

1 file changed

+284
-0
lines changed

tools/acrn-crashlog/acrnprobe/crash_reclassify.c

Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,292 @@
33
* SPDX-License-Identifier: BSD-3-Clause
44
*/
55

6+
#include <string.h>
7+
#include <stdio.h>
8+
#include <malloc.h>
9+
#include <sys/mman.h>
10+
#include <sys/types.h>
11+
#include <sys/stat.h>
12+
#include <fcntl.h>
13+
#include <unistd.h>
14+
#include <errno.h>
15+
#include "load_conf.h"
16+
#include "fsutils.h"
17+
#include "strutils.h"
18+
#include "log_sys.h"
619
#include "crash_reclassify.h"
720

21+
/**
22+
* Check if file contains content or not.
23+
* This function couldn't use for binary file.
24+
*
25+
* @param file Starting address of file cache.
26+
* @param content String to be searched.
27+
*
28+
* @return 1 if find the same string, or 0 if not.
29+
*/
30+
static int has_content(char *file, char *content)
31+
{
32+
if (content && strstr(file, content))
33+
return 1;
34+
35+
return 0;
36+
}
37+
38+
/**
39+
* Check if file contains all configured contents or not.
40+
* This function couldn't use for binary file.
41+
*
42+
* @param crash Crash need checking.
43+
* @param file Starting address of file cache.
44+
*
45+
* @return 1 if all configured strings were found, or 0 if not.
46+
*/
47+
static int crash_has_all_contents(struct crash_t *crash,
48+
char *file)
49+
{
50+
int id;
51+
int ret = 1;
52+
char *content;
53+
54+
for_each_content_crash(id, content, crash) {
55+
if (!content)
56+
continue;
57+
58+
if (!has_content(file, content)) {
59+
ret = 0;
60+
break;
61+
}
62+
}
63+
64+
return ret;
65+
}
66+
67+
/**
68+
* Might content is a 2-D array, write as mc[exp][cnt]
69+
* This function implements the following algorithm:
70+
*
71+
* r_mc[exp] = has_content(mc[exp][0]) || has_content(mc[exp][1]) || ...
72+
* result = r_mc[0] && r_mc[1] && ...
73+
*
74+
* This function couldn't use for binary file.
75+
*
76+
* @param crash Crash need checking.
77+
* @param file Starting address of file cache.
78+
*
79+
* @return 1 if result is true, or 0 if false.
80+
*/
81+
static int crash_has_mightcontents(struct crash_t *crash,
82+
char *file)
83+
{
84+
int ret = 1;
85+
int ret_exp;
86+
int expid, cntid;
87+
char **exp;
88+
char *content;
89+
90+
for_each_expression_crash(expid, exp, crash) {
91+
if (!exp || !exp_valid(exp))
92+
continue;
93+
94+
ret_exp = 0;
95+
for_each_content_expression(cntid, content, exp) {
96+
if (!content)
97+
continue;
98+
99+
if (has_content(file, content)) {
100+
ret_exp = 1;
101+
break;
102+
}
103+
}
104+
if (ret_exp == 0) {
105+
ret = 0;
106+
break;
107+
}
108+
}
109+
110+
return ret;
111+
}
112+
113+
/**
114+
* Judge the type of crash, according to configured content/mightcontent.
115+
* This function couldn't use for binary file.
116+
*
117+
* @param crash Crash need checking.
118+
* @param file Starting address of file cache.
119+
*
120+
* @return 1 if file matches these strings configured in crash, or 0 if not.
121+
*/
122+
static int crash_reclassify(struct crash_t *crash, char *file)
123+
{
124+
return crash_has_all_contents(crash, file) &&
125+
crash_has_mightcontents(crash, file);
126+
}
127+
128+
static int _get_data(char *file, struct crash_t *crash, char **data, int index)
129+
{
130+
char *search_key;
131+
char *value;
132+
char *end;
133+
int size;
134+
int max_size = 255;
135+
136+
if (!data)
137+
return 0;
138+
139+
*data = NULL;
140+
141+
search_key = crash->data[index];
142+
if (!search_key)
143+
return 0;
144+
145+
value = strrstr(file, search_key);
146+
if (!value)
147+
return 0;
148+
149+
end = strchr(value, '\n');
150+
if (!end)
151+
return 0;
152+
153+
size = MIN(max_size, end - value);
154+
*data = malloc(size + 1);
155+
if (*data == NULL)
156+
return -ENOMEM;
157+
158+
strncpy(*data, value, size);
159+
*(*data + size) = 0;
160+
return size;
161+
}
162+
163+
/**
164+
* Get segment from file, according to 'data' configuread in crash.
165+
* This function couldn't use for binary file.
166+
*
167+
* @param file Starting address of file cache.
168+
* @param crash Crash need checking.
169+
* @param[out] data0 Searched result, according to 'data0' configuread in crash.
170+
* @param[out] data1 Searched result, according to 'data1' configuread in crash.
171+
* @param[out] data2 Searched result, according to 'data2' configuread in crash.
172+
*
173+
* @return 0 if successful, or errno if not.
174+
*/
175+
static int get_data(char *file, struct crash_t *crash,
176+
char **data0, char **data1, char **data2)
177+
{
178+
int res;
179+
180+
/* to find strings which match conf words */
181+
res = _get_data(file, crash, data0, 0);
182+
if (res < 0)
183+
goto fail;
184+
185+
res = _get_data(file, crash, data1, 1);
186+
if (res < 0)
187+
goto free_data0;
188+
189+
res = _get_data(file, crash, data2, 2);
190+
if (res < 0)
191+
goto free_data1;
192+
193+
return 0;
194+
free_data1:
195+
if (data1 && *data1)
196+
free(*data1);
197+
free_data0:
198+
if (data0 && *data0)
199+
free(*data0);
200+
fail:
201+
return res;
202+
}
203+
204+
/**
205+
* Judge the crash type. We only got a root crash from channel, sometimes,
206+
* we need to calculate a more specific type.
207+
* This function reclassify the crash type by searching trigger file's content.
208+
* This function couldn't use for binary file.
209+
*
210+
* @param rcrash Root crash obtained from channel.
211+
* @param trfile Path of trigger file.
212+
* @param[out] data0 Searched result, according to 'data0' configuread in crash.
213+
* @param[out] data1 Searched result, according to 'data1' configuread in crash.
214+
* @param[out] data2 Searched result, according to 'data2' configuread in crash.
215+
*
216+
* @return a pointer to the calculated crash structure if successful,
217+
* or NULL if not.
218+
*/
219+
static struct crash_t *crash_reclassify_by_content(struct crash_t *rcrash,
220+
char *trfile, char **data0,
221+
char **data1, char **data2)
222+
{
223+
int depth;
224+
int level;
225+
int ret;
226+
struct crash_t *crash;
227+
struct crash_t *ret_crash = NULL;
228+
void *file;
229+
unsigned long size;
230+
int id;
231+
232+
if (!rcrash)
233+
return NULL;
234+
235+
if (trfile) {
236+
ret = read_full_binary_file(trfile, &size, &file);
237+
if (ret == -1) {
238+
LOGE("read %s failed, error (%s)\n",
239+
trfile, strerror(errno));
240+
return NULL;
241+
}
242+
} else
243+
return rcrash;
244+
245+
/* traverse every crash from leaf, return the first crash we find
246+
* consider that we have few CRASH TYPE, so just using this simple
247+
* implementation.
248+
*/
249+
depth = crash_depth(rcrash);
250+
for (level = depth; level >= 0; level--) {
251+
for_each_crash(id, crash, conf) {
252+
if (!crash ||
253+
crash->trigger != rcrash->trigger ||
254+
crash->channel != rcrash->channel ||
255+
crash->level != level)
256+
continue;
257+
258+
if (crash_reclassify(crash, file)) {
259+
ret = get_data(file, crash, data0, data1,
260+
data2);
261+
if (ret < 0) {
262+
LOGE("get data error, error (%s)\n",
263+
strerror(-ret));
264+
goto fail_data;
265+
} else {
266+
ret_crash = crash;
267+
goto fail_data;
268+
}
269+
}
270+
}
271+
}
272+
273+
fail_data:
274+
free(file);
275+
276+
return ret_crash;
277+
}
278+
279+
/**
280+
* Initailize crash reclassify, we only got a root crash from channel,
281+
* sometimes, we need to get a more specific type.
282+
*/
8283
void init_crash_reclassify(void)
9284
{
285+
int id;
286+
struct crash_t *crash;
287+
288+
for_each_crash(id, crash, conf) {
289+
if (!crash || !is_root_crash(crash))
290+
continue;
291+
292+
crash->reclassify = crash_reclassify_by_content;
293+
}
10294
}

0 commit comments

Comments
 (0)