The read_string() of crash can not read strings with len>MIN_PAGE_SIZE(otherwise we will get segment fault) but some print_fmt 's size is larger than MIN_PAGE_SIZE, so we have to add read_long_string() for it. Signed-off-by: Lai Jiangshan <laijs@xxxxxxxxxxxxxx> --- diff --git a/extensions/trace.c b/extensions/trace.c index b07f739..4b6144f 100755 --- a/extensions/trace.c +++ b/extensions/trace.c @@ -995,8 +995,48 @@ work: return 0; } +static int read_long_string(ulong kvaddr, char **buf) +{ + char strbuf[MIN_PAGE_SIZE], *ret_buf = NULL; + ulong kp; + int cnt1, cnt2, size; + +again: + kp = kvaddr; + size = 0; + + for (;;) { + cnt1 = MIN_PAGE_SIZE - (kp & (MIN_PAGE_SIZE-1)); + + if (!readmem(kp, KVADDR, strbuf, cnt1, + "readstring characters", QUIET|RETURN_ON_ERROR)) + return -1; + + cnt2 = strnlen(strbuf, cnt1); + if (ret_buf) + memcpy(ret_buf + size, strbuf, cnt2); + kp += cnt2; + size += cnt2; + + if (cnt2 < cnt1) { + if (ret_buf) { + break; + } else { + ret_buf = malloc(size + 1); + if (!ret_buf) + return -1; + goto again; + } + } + } + + ret_buf[size] = '\0'; + *buf = ret_buf; + return size; +} + static -int ftrace_get_event_type_print_fmt(ulong call, char *print_fmt, int len) +int ftrace_get_event_type_print_fmt(ulong call, char **print_fmt) { static int inited; static int fmt_offset; @@ -1015,10 +1055,7 @@ int ftrace_get_event_type_print_fmt(ulong call, char *print_fmt, int len) "read ftrace_event_call fmt_addr", RETURN_ON_ERROR)) return -1; - if (!read_string(fmt_addr, print_fmt, len)) - return -1; - - return 0; + return read_long_string(fmt_addr, print_fmt); } static @@ -1064,7 +1101,7 @@ static int ftrace_init_event_types(void) read_value(event, ftrace_events, list_head, next); while (event != ftrace_events) { ulong call; - char name[128], system[128], print_fmt[4096]; + char name[128], system[128], *print_fmt; int id; call = event - koffset(ftrace_event_call, list); @@ -1073,7 +1110,7 @@ static int ftrace_init_event_types(void) if (ftrace_get_event_type_id(call, &id) < 0 || ftrace_get_event_type_name(call, name, 128) < 0 || ftrace_get_event_type_system(call, system, 128) < 0 || - ftrace_get_event_type_print_fmt(call, print_fmt, 4096) < 0) + ftrace_get_event_type_print_fmt(call, &print_fmt) < 0) goto out_fail; /* Enlarge event types array when need */ @@ -1083,20 +1120,24 @@ static int ftrace_init_event_types(void) max_types = 2 * nr_event_types; tmp = realloc(event_types, sizeof(*event_types) * max_types); - if (tmp == NULL) + if (tmp == NULL) { + free(print_fmt); goto out_fail; + } event_types = tmp; } /* Create a event type */ aevent_type = malloc(sizeof(*aevent_type)); - if (aevent_type == NULL) + if (aevent_type == NULL) { + free(print_fmt); goto out_fail; + } aevent_type->system = strdup(system); aevent_type->name = strdup(name); - aevent_type->print_fmt = strdup(print_fmt); + aevent_type->print_fmt = print_fmt; aevent_type->id = id; aevent_type->nfields = 0; aevent_type->fields = NULL; -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility