[PATCH 2/3 v2] crash-trace-command: Include trace_printk() formats for modules

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux