If a module has a trace_printk() and it is optimized to be a trace_bprintk() then we want to save the format for that as well. The trace_bprintk() just saves the pointer of the format in the ftrace ring buffer, thus trace-cmd requires the mapping of that address to the format. Signed-off-by: Steven Rostedt <rostedt@xxxxxxxxxxx> Index: crash-5.1.3/extensions/trace.c =================================================================== --- crash-5.1.3.orig/extensions/trace.c +++ crash-5.1.3/extensions/trace.c @@ -3341,11 +3341,46 @@ static int save_proc_kallsyms(int fd) return tmp_file_flush(fd); } +static int add_print_address(long address) +{ + char string[4096]; + size_t len; + int i; + + len = read_string(address, string, sizeof(string)); + if (!len) + return -1; + + tmp_fprintf("0x%lx : \"", address); + + for (i = 0; string[i]; i++) { + switch (string[i]) { + case '\n': + tmp_fprintf("\\n"); + break; + case '\t': + tmp_fprintf("\\t"); + break; + case '\\': + tmp_fprintf("\\\\"); + break; + case '"': + tmp_fprintf("\\\""); + break; + default: + tmp_fprintf("%c", string[i]); + } + } + tmp_fprintf("\"\n"); + + return 0; +} + static int save_ftrace_printk(int fd) { - struct syment *s, *e; + struct kernel_list_head *mod_fmt; + struct syment *s, *e, *b; long bprintk_fmt_s, bprintk_fmt_e; - char string[4096]; long *address; size_t i, count; @@ -3358,10 +3393,8 @@ static int save_ftrace_printk(int fd) bprintk_fmt_e = e->value; count = (bprintk_fmt_e - bprintk_fmt_s) / sizeof(long); - if (count == 0) { - unsigned int size = 0; - return write_and_check(fd, &size, 4); - } + if (count == 0) + goto do_mods; address = malloc(count * sizeof(long)); if (address == NULL) @@ -3374,37 +3407,49 @@ static int save_ftrace_printk(int fd) } for (i = 0; i < count; i++) { - size_t len = read_string(address[i], string, sizeof(string)); - if (!len) { + if (add_print_address(address[i]) < 0) { free(address); return -1; } - - tmp_fprintf("0x%lx : \"", address[i]); - - for (i = 0; string[i]; i++) { - switch (string[i]) { - case '\n': - tmp_fprintf("\\n"); - break; - case '\t': - tmp_fprintf("\\t"); - break; - case '\\': - tmp_fprintf("\\\\"); - break; - case '"': - tmp_fprintf("\\\""); - break; - default: - tmp_fprintf("%c", string[i]); - } - } - tmp_fprintf("\"\n"); } free(address); + do_mods: + + /* Add modules */ + b = symbol_search("trace_bprintk_fmt_list"); + if (!b) + goto out; + + mod_fmt = (struct kernel_list_head *)GETBUF(SIZE(list_head)); + if (!readmem(b->value, KVADDR, mod_fmt, + SIZE(list_head), "trace_bprintk_fmt_list contents", + RETURN_ON_ERROR)) + goto out_free; + + while ((unsigned long)mod_fmt->next != b->value) { + unsigned long addr; + + addr = (unsigned long)mod_fmt->next + SIZE(list_head); + + if (!readmem((unsigned long)mod_fmt->next, KVADDR, mod_fmt, + SIZE(list_head), "trace_bprintk_fmt_list contents", + RETURN_ON_ERROR)) + goto out_free; + + if (add_print_address(addr) < 0) + goto out_free; + count++; + } + + out_free: + FREEBUF(mod_fmt); + out: + if (count == 0) { + unsigned int size = 0; + return write_and_check(fd, &size, 4); + } if (tmp_file_record_size4(fd)) return -1; return tmp_file_flush(fd); -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility