mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-26 23:36:51 +00:00
tools: acrn-crashlog: update string operation in acrnprobe
Remove unsafe api strlen except the parameter is a static string. Tracked-On: #1254 Signed-off-by: Liu, Xinwu <xinwu.liu@intel.com> Reviewed-by: Yonghua Huang <yonghua.huang@intel.com> Acked-by: Chen Gang <gang.c.chen@intel.com>
This commit is contained in:
parent
6938caa25f
commit
f25bc50e68
@ -55,19 +55,20 @@ static struct channel_t channels[] = {
|
||||
* @param private The corresponding configuration info to the event.
|
||||
* @param watchfd For watch channel, so far, only used by inotify.
|
||||
* @param path File which trigger this event.
|
||||
* @param plen The length of path.
|
||||
*
|
||||
* @return a pointer to the filled event if successful,
|
||||
* or NULL on error.
|
||||
*/
|
||||
static struct event_t *create_event(enum event_type_t event_type,
|
||||
const char *channel, void *private,
|
||||
int watchfd, const char *path)
|
||||
int watchfd, const char *path, size_t plen)
|
||||
{
|
||||
struct event_t *e;
|
||||
int path_len = 0;
|
||||
size_t path_len = 0;
|
||||
|
||||
if (path) {
|
||||
path_len = strlen(path);
|
||||
path_len = plen;
|
||||
if (path_len > PATH_MAX) {
|
||||
LOGE("invalid path, drop event.\n");
|
||||
return NULL;
|
||||
@ -83,7 +84,7 @@ static struct event_t *create_event(enum event_type_t event_type,
|
||||
e->event_type = event_type;
|
||||
if (path_len > 0) {
|
||||
e->len = path_len;
|
||||
memcpy(e->path, path, path_len + 1);
|
||||
*(char *)(mempcpy(e->path, path, path_len)) = '\0';
|
||||
}
|
||||
} else {
|
||||
LOGE("malloc failed, error (%s)\n", strerror(errno));
|
||||
@ -110,7 +111,7 @@ static void channel_oneshot(struct channel_t *cnl)
|
||||
if (!is_boot_id_changed())
|
||||
return;
|
||||
|
||||
e = create_event(REBOOT, cname, NULL, 0, NULL);
|
||||
e = create_event(REBOOT, cname, NULL, 0, NULL, 0);
|
||||
if (e)
|
||||
event_enqueue(e);
|
||||
|
||||
@ -127,7 +128,8 @@ static void channel_oneshot(struct channel_t *cnl)
|
||||
if (!strcmp("file", crash->trigger->type)) {
|
||||
if (file_exists(crash->trigger->path)) {
|
||||
e = create_event(CRASH, cname, (void *)crash,
|
||||
0, crash->trigger->path);
|
||||
0, crash->trigger->path,
|
||||
crash->trigger->path_len);
|
||||
if (e)
|
||||
event_enqueue(e);
|
||||
}
|
||||
@ -137,7 +139,8 @@ static void channel_oneshot(struct channel_t *cnl)
|
||||
read_startupreason(rreason, sizeof(rreason));
|
||||
if (!strcmp(rreason, crash->content[0])) {
|
||||
e = create_event(CRASH, cname, (void *)crash,
|
||||
0, crash->trigger->path);
|
||||
0, crash->trigger->path,
|
||||
crash->trigger->path_len);
|
||||
if (e)
|
||||
event_enqueue(e);
|
||||
}
|
||||
@ -155,7 +158,7 @@ static void channel_oneshot(struct channel_t *cnl)
|
||||
!strcmp("file", info->trigger->type) &&
|
||||
file_exists(info->trigger->path)) {
|
||||
e = create_event(INFO, cname, (void *)info,
|
||||
0, NULL);
|
||||
0, NULL, 0);
|
||||
if (e)
|
||||
event_enqueue(e);
|
||||
}
|
||||
@ -177,7 +180,7 @@ static struct polling_job_t {
|
||||
static void polling_vm(union sigval v __attribute__((unused)))
|
||||
{
|
||||
|
||||
struct event_t *e = create_event(VM, "polling", NULL, 0, NULL);
|
||||
struct event_t *e = create_event(VM, "polling", NULL, 0, NULL, 0);
|
||||
|
||||
if (e)
|
||||
event_enqueue(e);
|
||||
@ -238,7 +241,7 @@ static void channel_polling(struct channel_t *cnl)
|
||||
if (!vm)
|
||||
continue;
|
||||
|
||||
if (strncmp(vm->channel, "polling", strlen(vm->channel)))
|
||||
if (strcmp(vm->channel, "polling"))
|
||||
continue;
|
||||
|
||||
vm_job.timer_val = atoi(vm->interval);
|
||||
@ -340,7 +343,6 @@ static int receive_inotify_events(struct channel_t *channel)
|
||||
int read_left;
|
||||
char buf[256];
|
||||
char *p;
|
||||
char *name;
|
||||
struct event_t *e;
|
||||
struct inotify_event *ievent;
|
||||
enum event_type_t event_type;
|
||||
@ -382,14 +384,9 @@ static int receive_inotify_events(struct channel_t *channel)
|
||||
if (event_type == UNKNOWN) {
|
||||
LOGE("get a unknown event\n");
|
||||
} else {
|
||||
if (!ievent->len)
|
||||
name = NULL;
|
||||
else
|
||||
name = ievent->name;
|
||||
|
||||
e = create_event(event_type, channel->name,
|
||||
private, channel->fd,
|
||||
name);
|
||||
ievent->name, ievent->len);
|
||||
if (e)
|
||||
event_enqueue(e);
|
||||
}
|
||||
@ -411,7 +408,7 @@ static int receive_inotify_events(struct channel_t *channel)
|
||||
*/
|
||||
static void heart_beat(void)
|
||||
{
|
||||
struct event_t *e = create_event(HEART_BEAT, NULL, NULL, 0, NULL);
|
||||
struct event_t *e = create_event(HEART_BEAT, NULL, NULL, 0, NULL, 0);
|
||||
|
||||
if (e)
|
||||
event_enqueue(e);
|
||||
|
@ -125,19 +125,14 @@ static int crash_match_content(const struct crash_t *crash, const char *file)
|
||||
crash_has_mightcontents(crash, file);
|
||||
}
|
||||
|
||||
static int _get_data(const char *file, const struct crash_t *crash,
|
||||
static ssize_t _get_data(const char *file, const struct crash_t *crash,
|
||||
char **data, const int index)
|
||||
{
|
||||
const char *search_key;
|
||||
char *value;
|
||||
char *end;
|
||||
int size;
|
||||
int max_size = 255;
|
||||
|
||||
if (!data)
|
||||
return 0;
|
||||
|
||||
*data = NULL;
|
||||
ssize_t size;
|
||||
const size_t max_size = 255;
|
||||
|
||||
search_key = crash->data[index];
|
||||
if (!search_key)
|
||||
@ -151,8 +146,11 @@ static int _get_data(const char *file, const struct crash_t *crash,
|
||||
if (!end)
|
||||
return 0;
|
||||
|
||||
size = MIN(max_size, end - value);
|
||||
*data = malloc(size + 1);
|
||||
size = MIN(max_size, (size_t)(end - value));
|
||||
if (!size)
|
||||
return 0;
|
||||
|
||||
*data = malloc(size + 1);
|
||||
if (*data == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -171,35 +169,45 @@ static int _get_data(const char *file, const struct crash_t *crash,
|
||||
* @param[out] data1 Searched result, according to 'data1' configuread in crash.
|
||||
* @param[out] data2 Searched result, according to 'data2' configuread in crash.
|
||||
*
|
||||
* @return 0 if successful, or errno if not.
|
||||
* @return 0 if successful, or -1 if not.
|
||||
*/
|
||||
static int get_data(const char *file, const struct crash_t *crash,
|
||||
char **data0, char **data1, char **data2)
|
||||
char **data0, size_t *d0len, char **data1,
|
||||
size_t *d1len, char **data2, size_t *d2len)
|
||||
{
|
||||
int res;
|
||||
ssize_t res;
|
||||
|
||||
/* to find strings which match conf words */
|
||||
res = _get_data(file, crash, data0, 0);
|
||||
if (res < 0)
|
||||
goto fail;
|
||||
*d0len = (size_t)res;
|
||||
|
||||
res = _get_data(file, crash, data1, 1);
|
||||
if (res < 0)
|
||||
goto free_data0;
|
||||
*d1len = (size_t)res;
|
||||
|
||||
res = _get_data(file, crash, data2, 2);
|
||||
if (res < 0)
|
||||
goto free_data1;
|
||||
*d2len = (size_t)res;
|
||||
|
||||
return 0;
|
||||
free_data1:
|
||||
if (data1 && *data1)
|
||||
if (*data1)
|
||||
free(*data1);
|
||||
free_data0:
|
||||
if (data0 && *data0)
|
||||
if (*data0)
|
||||
free(*data0);
|
||||
fail:
|
||||
return res;
|
||||
*data0 = NULL;
|
||||
*data1 = NULL;
|
||||
*data2 = NULL;
|
||||
*d0len = 0;
|
||||
*d1len = 0;
|
||||
*d2len = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct crash_t *crash_find_matched_child(const struct crash_t *crash,
|
||||
@ -276,8 +284,10 @@ static struct crash_t *crash_find_matched_child(const struct crash_t *crash,
|
||||
* or NULL if not.
|
||||
*/
|
||||
static struct crash_t *crash_reclassify_by_content(const struct crash_t *rcrash,
|
||||
const char *rtrfile_fmt, char **data0,
|
||||
char **data1, char **data2)
|
||||
const char *rtrfile_fmt,
|
||||
char **data0, size_t *d0len,
|
||||
char **data1, size_t *d1len,
|
||||
char **data2, size_t *d2len)
|
||||
{
|
||||
int count;
|
||||
const struct crash_t *crash;
|
||||
@ -286,12 +296,17 @@ static struct crash_t *crash_reclassify_by_content(const struct crash_t *rcrash,
|
||||
char **trfiles;
|
||||
void *content;
|
||||
unsigned long size;
|
||||
int res;
|
||||
int i;
|
||||
|
||||
if (!rcrash)
|
||||
if (!rcrash || !data0 || !d0len || !data1 || !d1len || !data2 || !d2len)
|
||||
return NULL;
|
||||
|
||||
*data0 = NULL;
|
||||
*data1 = NULL;
|
||||
*data2 = NULL;
|
||||
*d0len = 0;
|
||||
*d1len = 0;
|
||||
*d2len = 0;
|
||||
crash = rcrash;
|
||||
|
||||
while (1) {
|
||||
@ -307,25 +322,26 @@ static struct crash_t *crash_reclassify_by_content(const struct crash_t *rcrash,
|
||||
else
|
||||
trfile_fmt = ret_crash->trigger->path;
|
||||
|
||||
/* trfile may not be specified */
|
||||
if (!trfile_fmt)
|
||||
return (struct crash_t *)ret_crash;
|
||||
|
||||
count = config_fmt_to_files(trfile_fmt, &trfiles);
|
||||
if (count <= 0)
|
||||
return (struct crash_t *)ret_crash;
|
||||
|
||||
/* get data from last file */
|
||||
res = read_file(trfiles[count - 1], &size, &content);
|
||||
if (res == -1) {
|
||||
LOGE("read %s failed, error (%s)\n",
|
||||
if (read_file(trfiles[count - 1], &size, &content) == -1) {
|
||||
LOGE("failed to read %s, error (%s)\n",
|
||||
trfiles[count - 1], strerror(errno));
|
||||
goto free_files;
|
||||
}
|
||||
if (!size)
|
||||
goto free_files;
|
||||
|
||||
res = get_data(content, ret_crash, data0, data1, data2);
|
||||
if (res < 0) {
|
||||
LOGE("get data error, error (%s)\n",
|
||||
strerror(res));
|
||||
}
|
||||
if (get_data(content, ret_crash, data0, d0len, data1, d1len,
|
||||
data2, d2len) == -1)
|
||||
LOGE("failed to get data\n");
|
||||
|
||||
free(content);
|
||||
|
||||
|
@ -199,7 +199,8 @@ void hist_raise_uptime(char *lastuptime)
|
||||
loop_uptime_event = (hours / uptime_hours) + 1;
|
||||
|
||||
key = generate_event_id((const char *)uptime->name,
|
||||
NULL, KEY_SHORT);
|
||||
uptime->name_len,
|
||||
NULL, 0, KEY_SHORT);
|
||||
if (key == NULL) {
|
||||
LOGE("generate event id failed, error (%s)\n",
|
||||
strerror(errno));
|
||||
@ -213,11 +214,11 @@ void hist_raise_uptime(char *lastuptime)
|
||||
}
|
||||
}
|
||||
|
||||
void hist_raise_infoerror(char *type)
|
||||
void hist_raise_infoerror(const char *type, size_t tlen)
|
||||
{
|
||||
char *key;
|
||||
|
||||
key = generate_event_id("ERROR", (const char *)type, KEY_SHORT);
|
||||
key = generate_event_id("ERROR", 5, type, tlen, KEY_SHORT);
|
||||
if (key == NULL) {
|
||||
LOGE("generate event id failed, error (%s)\n",
|
||||
strerror(errno));
|
||||
|
@ -27,7 +27,7 @@
|
||||
extern char *history_file;
|
||||
|
||||
int prepare_history(void);
|
||||
void hist_raise_infoerror(char *type);
|
||||
void hist_raise_infoerror(const char *type, size_t tlen);
|
||||
void hist_raise_uptime(char *lastuptime);
|
||||
void hist_raise_event(const char *event, const char *type, const char *log,
|
||||
const char *lastuptime, const char *key);
|
||||
|
@ -85,7 +85,8 @@ struct crash_t {
|
||||
int wd;
|
||||
int level;
|
||||
struct crash_t *(*reclassify)(const struct crash_t *, const char*,
|
||||
char**, char**, char**);
|
||||
char**, size_t *, char**, size_t *,
|
||||
char**, size_t *);
|
||||
};
|
||||
|
||||
struct info_t {
|
||||
|
@ -41,11 +41,13 @@ enum key_type {
|
||||
int get_uptime_string(char newuptime[24], int *hours);
|
||||
int get_current_time_long(char buf[32]);
|
||||
unsigned long long get_uptime(void);
|
||||
char *generate_event_id(const char *seed1, const char *seed2,
|
||||
enum key_type type);
|
||||
void generate_crashfile(const char *dir, const char *event, const char *hashkey,
|
||||
const char *type, const char *data0,
|
||||
const char *data1, const char *data2);
|
||||
char *generate_event_id(const char *seed1, size_t slen1, const char *seed2,
|
||||
size_t slen2, enum key_type type);
|
||||
void generate_crashfile(const char *dir, const char *event, size_t elen,
|
||||
const char *hashkey, size_t hlen,
|
||||
const char *type, size_t tlen, const char *data0,
|
||||
size_t d0len, const char *data1, size_t d1len,
|
||||
const char *data2, size_t d2len);
|
||||
char *generate_log_dir(enum e_dir_mode mode, char *hashkey);
|
||||
int is_boot_id_changed(void);
|
||||
|
||||
|
@ -95,7 +95,8 @@ int get_current_time_long(char *buf)
|
||||
return strftime(buf, LONG_TIME_SIZE, "%Y-%m-%d/%H:%M:%S ", time_val);
|
||||
}
|
||||
|
||||
static int compute_key(char *key, size_t key_len, const char *seed)
|
||||
static int compute_key(char *key, size_t klen, const char *seed,
|
||||
const size_t slen)
|
||||
{
|
||||
SHA256_CTX sha;
|
||||
char buf[VERSION_SIZE];
|
||||
@ -105,9 +106,9 @@ static int compute_key(char *key, size_t key_len, const char *seed)
|
||||
unsigned char results[SHA256_DIGEST_LENGTH];
|
||||
size_t i;
|
||||
|
||||
if (!key || !seed)
|
||||
if (!key || !seed || !slen)
|
||||
return -1;
|
||||
if (key_len > SHA256_DIGEST_LENGTH * 2 || !key_len)
|
||||
if (klen > SHA256_DIGEST_LENGTH * 2 || !klen)
|
||||
return -1;
|
||||
|
||||
SHA256_Init(&sha);
|
||||
@ -117,12 +118,12 @@ static int compute_key(char *key, size_t key_len, const char *seed)
|
||||
if (s_not_expect(len , VERSION_SIZE))
|
||||
return -1;
|
||||
|
||||
SHA256_Update(&sha, (unsigned char *)buf, strlen(buf));
|
||||
SHA256_Update(&sha, (unsigned char *)seed, strlen(seed));
|
||||
SHA256_Update(&sha, (unsigned char *)buf, strnlen(buf, VERSION_SIZE));
|
||||
SHA256_Update(&sha, (unsigned char *)seed, strnlen(seed, slen));
|
||||
|
||||
SHA256_Final(results, &sha);
|
||||
|
||||
for (i = 0; i < key_len / 2; i++) {
|
||||
for (i = 0; i < klen / 2; i++) {
|
||||
len = snprintf(tmp_key, 3, "%02x", results[i]);
|
||||
if (s_not_expect(len, 3))
|
||||
return -1;
|
||||
@ -144,15 +145,15 @@ static int compute_key(char *key, size_t key_len, const char *seed)
|
||||
*
|
||||
* @return a pointer to result haskkey if successful, or NULL if not.
|
||||
*/
|
||||
char *generate_event_id(const char *seed1, const char *seed2,
|
||||
enum key_type type)
|
||||
char *generate_event_id(const char *seed1, size_t slen1, const char *seed2,
|
||||
size_t slen2, enum key_type type)
|
||||
{
|
||||
int ret;
|
||||
char *buf;
|
||||
char *key;
|
||||
size_t klen;
|
||||
|
||||
if (!seed1)
|
||||
if (!seed1 || !slen1)
|
||||
return NULL;
|
||||
|
||||
if (type == KEY_SHORT)
|
||||
@ -174,10 +175,10 @@ char *generate_event_id(const char *seed1, const char *seed2,
|
||||
free(key);
|
||||
return NULL;
|
||||
}
|
||||
ret = compute_key(key, klen, (const char *)buf);
|
||||
ret = compute_key(key, klen, (const char *)buf, slen1 + slen2);
|
||||
free(buf);
|
||||
} else {
|
||||
ret = compute_key(key, klen, seed1);
|
||||
ret = compute_key(key, klen, seed1, slen1);
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
@ -255,14 +256,15 @@ static int reserve_log_folder(enum e_dir_mode mode, char *dir,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define strcat_fmt(buf, fmt, ...) \
|
||||
(__extension__ \
|
||||
({ \
|
||||
char __buf[1024] = {'\0',}; \
|
||||
snprintf(__buf, sizeof(__buf), fmt, ##__VA_ARGS__); \
|
||||
strcat(buf, __buf); \
|
||||
}) \
|
||||
)
|
||||
static char *cf_line(char *dest, const char *k, size_t klen, const char *v,
|
||||
size_t vlen)
|
||||
{
|
||||
char *t;
|
||||
|
||||
t = mempcpy(dest, k, klen);
|
||||
t = mempcpy(t, v, vlen);
|
||||
return mempcpy(t, "\n", 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a crashfile with given params.
|
||||
@ -273,69 +275,78 @@ static int reserve_log_folder(enum e_dir_mode mode, char *dir,
|
||||
* @param type Subtype of this event.
|
||||
* @param data* String obtained by get_data.
|
||||
*/
|
||||
void generate_crashfile(const char *dir, const char *event, const char *hashkey,
|
||||
const char *type, const char *data0,
|
||||
const char *data1, const char *data2)
|
||||
void generate_crashfile(const char *dir,
|
||||
const char *event, size_t elen,
|
||||
const char *hashkey, size_t hlen,
|
||||
const char *type, size_t tlen,
|
||||
const char *data0, size_t d0len,
|
||||
const char *data1, size_t d1len,
|
||||
const char *data2, size_t d2len)
|
||||
{
|
||||
char *buf;
|
||||
char *path;
|
||||
char *tail;
|
||||
char datetime[LONG_TIME_SIZE];
|
||||
char uptime[UPTIME_SIZE];
|
||||
int hours;
|
||||
int ret;
|
||||
const int fmtsize = 128;
|
||||
size_t ltlen;
|
||||
int n;
|
||||
int filesize;
|
||||
|
||||
datetime[0] = 0;
|
||||
ret = get_current_time_long(datetime);
|
||||
if (ret <= 0)
|
||||
if (!dir || !event || !elen || !hashkey || !hlen ||
|
||||
!type || !tlen)
|
||||
return;
|
||||
if (d0len > 0 && !data0)
|
||||
return;
|
||||
if (d1len > 0 && !data1)
|
||||
return;
|
||||
if (d2len > 0 && !data2)
|
||||
return;
|
||||
uptime[0] = 0;
|
||||
get_uptime_string(uptime, &hours);
|
||||
|
||||
filesize = fmtsize + strlen(event) +
|
||||
strlen(hashkey) + strlen(guuid) +
|
||||
strlen(datetime) + strlen(uptime) +
|
||||
strlen(gbuildversion) + strlen(type);
|
||||
if (data0)
|
||||
filesize += strlen(data0);
|
||||
if (data1)
|
||||
filesize += strlen(data1);
|
||||
if (data2)
|
||||
filesize += strlen(data2);
|
||||
ltlen = get_current_time_long(datetime);
|
||||
if (!ltlen)
|
||||
return;
|
||||
n = get_uptime_string(uptime, &hours);
|
||||
if (n < 0)
|
||||
return;
|
||||
|
||||
filesize = fmtsize + ltlen + n + elen + hlen + tlen + d0len + d1len +
|
||||
d2len + strnlen(guuid, UUID_SIZE) +
|
||||
strnlen(gbuildversion, BUILD_VERSION_SIZE);
|
||||
|
||||
buf = malloc(filesize);
|
||||
if (buf == NULL) {
|
||||
LOGE("compute string failed, out of memory\n");
|
||||
LOGE("out of memory\n");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(buf, 0, filesize);
|
||||
strcat_fmt(buf, "EVENT=%s\n", event);
|
||||
strcat_fmt(buf, "ID=%s\n", hashkey);
|
||||
strcat_fmt(buf, "DEVICEID=%s\n", guuid);
|
||||
strcat_fmt(buf, "DATE=%s\n", datetime);
|
||||
strcat_fmt(buf, "UPTIME=%s\n", uptime);
|
||||
strcat_fmt(buf, "BUILD=%s\n", gbuildversion);
|
||||
strcat_fmt(buf, "TYPE=%s\n", type);
|
||||
if (data0)
|
||||
strcat_fmt(buf, "DATA0=%s\n", data0);
|
||||
if (data1)
|
||||
strcat_fmt(buf, "DATA1=%s\n", data1);
|
||||
if (data2)
|
||||
strcat_fmt(buf, "DATA2=%s\n", data2);
|
||||
strcat(buf, "_END\n");
|
||||
tail = cf_line(buf, "EVENT=", 6, event, elen);
|
||||
tail = cf_line(tail, "ID=", 3, hashkey, hlen);
|
||||
tail = cf_line(tail, "DEVICEID=", 9, guuid, strnlen(guuid, UUID_SIZE));
|
||||
tail = cf_line(tail, "DATE=", 5, datetime, ltlen);
|
||||
tail = cf_line(tail, "UPTIME=", 7, uptime, n);
|
||||
tail = cf_line(tail, "BUILD=", 6, gbuildversion,
|
||||
strnlen(gbuildversion, BUILD_VERSION_SIZE));
|
||||
tail = cf_line(tail, "TYPE=", 5, type, tlen);
|
||||
|
||||
ret = asprintf(&path, "%s/%s", dir, "crashfile");
|
||||
if (ret < 0) {
|
||||
LOGE("compute string failed, out of memory\n");
|
||||
if (d0len)
|
||||
tail = cf_line(tail, "DATA0=", 6, data0, d0len);
|
||||
if (d1len)
|
||||
tail = cf_line(tail, "DATA1=", 6, data1, d1len);
|
||||
if (d2len)
|
||||
tail = cf_line(tail, "DATA2=", 6, data2, d2len);
|
||||
tail = mempcpy(tail, "_END\n", 5);
|
||||
*tail = '\0';
|
||||
|
||||
if (asprintf(&path, "%s/crashfile", dir) == -1) {
|
||||
LOGE("out of memory\n");
|
||||
free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = overwrite_file(path, buf);
|
||||
if (ret)
|
||||
LOGE("new crashfile (%s) fail, error (%s)\n", path,
|
||||
if (overwrite_file(path, buf) != 0)
|
||||
LOGE("failed to new crashfile (%s), error (%s)\n", path,
|
||||
strerror(errno));
|
||||
|
||||
free(buf);
|
||||
@ -364,14 +375,14 @@ char *generate_log_dir(enum e_dir_mode mode, char *hashkey)
|
||||
ret = asprintf(&path, "%s%d_%s", dir, current, hashkey);
|
||||
if (ret == -1) {
|
||||
LOGE("construct log path failed, out of memory\n");
|
||||
hist_raise_infoerror("DIR CREATE");
|
||||
hist_raise_infoerror("DIR CREATE", 10);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = mkdir(path, 0777);
|
||||
if (ret == -1) {
|
||||
LOGE("Cannot create dir %s\n", path);
|
||||
hist_raise_infoerror("DIR CREATE");
|
||||
hist_raise_infoerror("DIR CREATE", 10);
|
||||
free(path);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -275,7 +275,7 @@ static void crashlog_get_log(struct log_t *log, void *data)
|
||||
|
||||
quota = atoi(crashlog->spacequota);
|
||||
if (!space_available(crashlog->outdir, quota)) {
|
||||
hist_raise_infoerror("SPACE_FULL");
|
||||
hist_raise_infoerror("SPACE_FULL", 10);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -357,7 +357,8 @@ static void telemd_send_crash(struct event_t *e)
|
||||
return;
|
||||
}
|
||||
|
||||
eventid = generate_event_id((const char *)class, NULL, KEY_LONG);
|
||||
eventid = generate_event_id((const char *)class, ret, NULL, 0,
|
||||
KEY_LONG);
|
||||
if (eventid == NULL) {
|
||||
LOGE("generate eventid failed, error (%s)\n", strerror(errno));
|
||||
goto free_class;
|
||||
@ -436,7 +437,8 @@ static void telemd_send_info(struct event_t *e)
|
||||
return;
|
||||
}
|
||||
|
||||
eventid = generate_event_id((const char *)class, NULL, KEY_LONG);
|
||||
eventid = generate_event_id((const char *)class, ret, NULL, 0,
|
||||
KEY_LONG);
|
||||
if (eventid == NULL) {
|
||||
LOGE("generate eventid failed, error (%s)\n", strerror(errno));
|
||||
goto free_class;
|
||||
@ -611,7 +613,8 @@ static int telemd_new_vmevent(const char *line_to_sync,
|
||||
goto free_vmlogpath;
|
||||
}
|
||||
|
||||
eventid = generate_event_id((const char *)class, NULL, KEY_LONG);
|
||||
eventid = generate_event_id((const char *)class, res, NULL, 0,
|
||||
KEY_LONG);
|
||||
if (eventid == NULL) {
|
||||
LOGE("generate eventid failed, error (%s)\n", strerror(errno));
|
||||
ret = VMEVT_DEFER;
|
||||
@ -713,53 +716,67 @@ static void telemd_send(struct event_t *e)
|
||||
static void crashlog_send_crash(struct event_t *e)
|
||||
{
|
||||
struct crash_t *crash;
|
||||
struct log_t *log;
|
||||
struct sender_t *crashlog;
|
||||
char *key = NULL;
|
||||
char *key;
|
||||
char *data0;
|
||||
char *data1;
|
||||
char *data2;
|
||||
size_t d0len;
|
||||
size_t d1len;
|
||||
size_t d2len;
|
||||
char *trfile = NULL;
|
||||
char *data0 = NULL;
|
||||
char *data1 = NULL;
|
||||
char *data2 = NULL;
|
||||
int id;
|
||||
int ret = 0;
|
||||
int quota;
|
||||
struct sender_t *crashlog = get_sender_by_name("crashlog");
|
||||
struct crash_t *rcrash = (struct crash_t *)e->private;
|
||||
|
||||
if (!crashlog)
|
||||
return;
|
||||
|
||||
if (!strcmp(rcrash->trigger->type, "dir")) {
|
||||
ret = asprintf(&trfile, "%s/%s", rcrash->trigger->path,
|
||||
e->path);
|
||||
if (ret < 0) {
|
||||
LOGE("compute string failed, out of memory\n");
|
||||
if (asprintf(&trfile, "%s/%s", rcrash->trigger->path,
|
||||
e->path) == -1) {
|
||||
LOGE("out of memory\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
crash = rcrash->reclassify(rcrash, trfile, &data0, &data1, &data2);
|
||||
crash = rcrash->reclassify(rcrash, trfile, &data0, &d0len, &data1,
|
||||
&d1len, &data2, &d2len);
|
||||
if (trfile)
|
||||
free(trfile);
|
||||
if (crash == NULL) {
|
||||
LOGE("reclassify crash (%s) failed\n", rcrash->name);
|
||||
goto free_trfile;
|
||||
LOGE("failed to reclassify rcrash (%s)\n", rcrash->name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* change the class for other senders */
|
||||
e->private = (void *)crash;
|
||||
key = generate_event_id("CRASH", (const char *)crash->name, KEY_SHORT);
|
||||
|
||||
key = generate_event_id("CRASH", 5, (const char *)crash->name,
|
||||
crash->name_len, KEY_SHORT);
|
||||
if (key == NULL) {
|
||||
LOGE("generate event id failed, error (%s)\n",
|
||||
LOGE("failed to generate event id, error (%s)\n",
|
||||
strerror(errno));
|
||||
goto free_data;
|
||||
}
|
||||
|
||||
if (to_collect_logs(crash) ||
|
||||
!strcmp(e->channel, "inotify")) {
|
||||
/* check space before collecting logs */
|
||||
if (!space_available(crashlog->outdir, atoi(crashlog->spacequota))) {
|
||||
hist_raise_infoerror("SPACE_FULL", 10);
|
||||
hist_raise_event("CRASH", crash->name, NULL, "", key);
|
||||
goto free_key;
|
||||
}
|
||||
|
||||
if (to_collect_logs(crash) || !strcmp(e->channel, "inotify")) {
|
||||
struct log_t *log;
|
||||
int id;
|
||||
|
||||
e->dir = generate_log_dir(MODE_CRASH, key);
|
||||
if (e->dir == NULL) {
|
||||
LOGE("generate crashlog dir failed\n");
|
||||
LOGE("failed to generate crashlog dir\n");
|
||||
goto free_key;
|
||||
}
|
||||
|
||||
generate_crashfile(e->dir, "CRASH", key,
|
||||
crash->name,
|
||||
data0, data1, data2);
|
||||
generate_crashfile(e->dir, "CRASH", 5, key, SHORT_KEY_LENGTH,
|
||||
crash->name, crash->name_len,
|
||||
data0, d0len, data1, d1len, data2, d2len);
|
||||
for_each_log_collect(id, log, crash) {
|
||||
if (!log)
|
||||
continue;
|
||||
@ -769,36 +786,25 @@ static void crashlog_send_crash(struct event_t *e)
|
||||
|
||||
}
|
||||
|
||||
crashlog = get_sender_by_name("crashlog");
|
||||
if (!crashlog)
|
||||
goto free_key;
|
||||
|
||||
quota = atoi(crashlog->spacequota);
|
||||
if (!space_available(crashlog->outdir, quota)) {
|
||||
hist_raise_infoerror("SPACE_FULL");
|
||||
} else if (!strcmp(e->channel, "inotify")) {
|
||||
if (!strcmp(e->channel, "inotify")) {
|
||||
/* get the trigger file */
|
||||
char *src;
|
||||
char *des;
|
||||
|
||||
ret = asprintf(&des, "%s/%s", e->dir, e->path);
|
||||
if (ret < 0) {
|
||||
LOGE("compute string failed, out of memory\n");
|
||||
if (asprintf(&des, "%s/%s", e->dir, e->path) == -1) {
|
||||
LOGE("out of memory\n");
|
||||
goto free_key;
|
||||
}
|
||||
|
||||
ret = asprintf(&src, "%s/%s", crash->trigger->path, e->path);
|
||||
if (ret < 0) {
|
||||
LOGE("compute string failed, out of memory\n");
|
||||
if (asprintf(&src, "%s/%s", crash->trigger->path,
|
||||
e->path) == -1) {
|
||||
LOGE("out of memory\n");
|
||||
free(des);
|
||||
goto free_key;
|
||||
}
|
||||
|
||||
ret = do_copy_tail(src, des, 0);
|
||||
if (ret < 0) {
|
||||
LOGE("copy (%s) to (%s) failed, error (%s)\n",
|
||||
src, des, strerror(-ret));
|
||||
}
|
||||
if (do_copy_tail(src, des, 0) < 0)
|
||||
LOGE("failed to copy (%s) to (%s)\n", src, des);
|
||||
|
||||
free(src);
|
||||
free(des);
|
||||
@ -809,11 +815,12 @@ static void crashlog_send_crash(struct event_t *e)
|
||||
free_key:
|
||||
free(key);
|
||||
free_data:
|
||||
free(data0);
|
||||
free(data1);
|
||||
free(data2);
|
||||
free_trfile:
|
||||
free(trfile);
|
||||
if (data0)
|
||||
free(data0);
|
||||
if (data1)
|
||||
free(data1);
|
||||
if (data2)
|
||||
free(data2);
|
||||
}
|
||||
|
||||
static void crashlog_send_info(struct event_t *e)
|
||||
@ -821,8 +828,8 @@ static void crashlog_send_info(struct event_t *e)
|
||||
int id;
|
||||
struct info_t *info = (struct info_t *)e->private;
|
||||
struct log_t *log;
|
||||
char *key = generate_event_id("INFO", (const char *)info->name,
|
||||
KEY_SHORT);
|
||||
char *key = generate_event_id("INFO", 4, (const char *)info->name,
|
||||
info->name_len, KEY_SHORT);
|
||||
|
||||
if (key == NULL) {
|
||||
LOGE("generate event id failed, error (%s)\n",
|
||||
@ -866,7 +873,7 @@ static void crashlog_send_reboot(void)
|
||||
return;
|
||||
|
||||
if (swupdated(crashlog)) {
|
||||
key = generate_event_id("INFO", "SWUPDATE", KEY_SHORT);
|
||||
key = generate_event_id("INFO", 4, "SWUPDATE", 8, KEY_SHORT);
|
||||
if (key == NULL) {
|
||||
LOGE("generate event id failed, error (%s)\n",
|
||||
strerror(errno));
|
||||
@ -878,7 +885,8 @@ static void crashlog_send_reboot(void)
|
||||
}
|
||||
|
||||
read_startupreason(reason, sizeof(reason));
|
||||
key = generate_event_id("REBOOT", (const char *)reason, KEY_SHORT);
|
||||
key = generate_event_id("REBOOT", 6, (const char *)reason,
|
||||
strnlen(reason, REBOOT_REASON_SIZE), KEY_SHORT);
|
||||
if (key == NULL) {
|
||||
LOGE("generate event id failed, error (%s)\n",
|
||||
strerror(errno));
|
||||
@ -934,11 +942,12 @@ static int crashlog_new_vmevent(const char *line_to_sync,
|
||||
|
||||
quota = atoi(crashlog->spacequota);
|
||||
if (!space_available(crashlog->outdir, quota)) {
|
||||
hist_raise_infoerror("SPACE_FULL");
|
||||
hist_raise_infoerror("SPACE_FULL", 10);
|
||||
return ret;
|
||||
}
|
||||
|
||||
key = generate_event_id("SOS", (const char *)vmkey, KEY_SHORT);
|
||||
key = generate_event_id("SOS", 3, (const char *)vmkey,
|
||||
strnlen(vmkey, ANDROID_WORD_LEN), KEY_SHORT);
|
||||
if (key == NULL) {
|
||||
LOGE("generate event id failed, error (%s)\n",
|
||||
strerror(errno));
|
||||
@ -952,6 +961,12 @@ static int crashlog_new_vmevent(const char *line_to_sync,
|
||||
goto free_key;
|
||||
}
|
||||
|
||||
generate_crashfile(dir, event, strnlen(event, ANDROID_WORD_LEN),
|
||||
key, SHORT_KEY_LENGTH,
|
||||
type, strnlen(type, ANDROID_WORD_LEN),
|
||||
vm->name, vm->name_len,
|
||||
vmkey, strnlen(vmkey, ANDROID_WORD_LEN), NULL, 0);
|
||||
|
||||
/* if line contains log, we need dump each file in the logdir
|
||||
*/
|
||||
log = strstr(rest, "/logs/");
|
||||
@ -969,14 +984,12 @@ static int crashlog_new_vmevent(const char *line_to_sync,
|
||||
}
|
||||
res = remove(dir);
|
||||
if (res == -1 && errno != ENOENT)
|
||||
LOGE("remove %s faield (%d)\n", dir, -errno);
|
||||
LOGE("failed to remove %s (%d)\n", dir, -errno);
|
||||
|
||||
goto free_dir;
|
||||
}
|
||||
}
|
||||
|
||||
generate_crashfile(dir, event, key, type, vm->name,
|
||||
vmkey, NULL);
|
||||
hist_raise_event(vm->name, type, dir, "", key);
|
||||
|
||||
free_dir:
|
||||
@ -1066,15 +1079,13 @@ int init_sender(void)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
if (!strncmp(sender->name, "crashlog",
|
||||
strlen(sender->name))) {
|
||||
if (!strcmp(sender->name, "crashlog")) {
|
||||
sender->send = crashlog_send;
|
||||
ret = prepare_history();
|
||||
if (ret)
|
||||
return -1;
|
||||
#ifdef HAVE_TELEMETRICS_CLIENT
|
||||
} else if (!strncmp(sender->name, "telemd",
|
||||
strlen(sender->name))) {
|
||||
} else if (!strcmp(sender->name, "telemd")) {
|
||||
sender->send = telemd_send;
|
||||
#endif
|
||||
}
|
||||
|
@ -35,10 +35,10 @@ static int get_cmdline_bootreason(char *bootreason, const size_t limit)
|
||||
int res;
|
||||
unsigned long size;
|
||||
char *start, *p1, *p2, *end;
|
||||
void *cmdline;
|
||||
const char key[] = "ABL.reset=";
|
||||
char *cmdline;
|
||||
const char *key = "ABL.reset=";
|
||||
|
||||
res = read_file(CURRENT_KERNEL_CMDLINE, &size, &cmdline);
|
||||
res = read_file(CURRENT_KERNEL_CMDLINE, &size, (void *)&cmdline);
|
||||
if (res < 0) {
|
||||
LOGE("failed to read file %s - %s\n",
|
||||
CURRENT_KERNEL_CMDLINE, strerror(errno));
|
||||
@ -66,13 +66,15 @@ static int get_cmdline_bootreason(char *bootreason, const size_t limit)
|
||||
else
|
||||
end = MAX(p1, p2);
|
||||
|
||||
if (end)
|
||||
*end = 0;
|
||||
if (!end)
|
||||
end = cmdline + size;
|
||||
|
||||
const size_t len = MIN(strlen(start), limit - 1);
|
||||
const size_t len = MIN((size_t)(end - start), (size_t)(limit - 1));
|
||||
|
||||
if (len > 0)
|
||||
memcpy(bootreason, start, len + 1);
|
||||
if (len > 0) {
|
||||
memcpy(bootreason, start, len);
|
||||
*(bootreason + len) = 0;
|
||||
}
|
||||
|
||||
free(cmdline);
|
||||
return len;
|
||||
@ -99,6 +101,9 @@ void read_startupreason(char *startupreason, const size_t limit)
|
||||
int res;
|
||||
static char reboot_reason_cache[REBOOT_REASON_SIZE];
|
||||
|
||||
if (!startupreason || !limit)
|
||||
return;
|
||||
|
||||
if (!reboot_reason_cache[0]) {
|
||||
/* fill cache */
|
||||
res = get_default_bootreason(reboot_reason_cache,
|
||||
@ -108,7 +113,8 @@ void read_startupreason(char *startupreason, const size_t limit)
|
||||
sizeof(reboot_reason_cache));
|
||||
}
|
||||
|
||||
const size_t len = MIN(strlen(reboot_reason_cache), limit - 1);
|
||||
const size_t len = MIN(strnlen(reboot_reason_cache, REBOOT_REASON_SIZE),
|
||||
limit - 1);
|
||||
|
||||
memcpy(startupreason, reboot_reason_cache, len);
|
||||
*(startupreason + len) = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user