[Crash-utility] [PATCH 09/10] teach crash to accept raw:MEMORY-IMAGE[@ADDRESS]

Oleg Nesterov oleg at redhat.com
Mon Apr 25 14:49:06 UTC 2016


With this change /usr/bin/crash will try to work with ramdump files without
creating the temporary KDUMP elf header if MEMORY-IMAGE starts with the "raw:"
prefix. This looks useful to me, especially because ramdump_to_elf() doesn't
support x86-64.

For example, I am running qemu with

	-object memory-backend-file,id=MEM,size=128m,mem-path=/tmp/MEM,share=on
	-numa node,memdev=MEM

options and after I crash the kernel (/bin/bash running as "init" exits)

	$ ./crash ../VMLINUX raw:/tmp/MEM at 0

reports:

	      KERNEL: ../VMLINUX
	   DUMPFILES: ramdump [raw]
		      /tmp/MEM
		CPUS: 2 [OFFLINE: 1]
		DATE: Mon Apr 25 11:47:26 2016
	      UPTIME: 00:00:07
	LOAD AVERAGE: 0.00, 0.00, 0.00
	       TASKS: 45
	    NODENAME: (none)
	     RELEASE: 3.10.0+
	     VERSION: #42 SMP Sun Apr 3 17:09:09 CEST 2016
	     MACHINE: x86_64  (2593 Mhz)
	      MEMORY: 127.5 MB
	       PANIC: "Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000"
		 PID: 1
	     COMMAND: "bash"
		TASK: ffff880007150000  [THREAD_INFO: ffff880007158000]
		 CPU: 0
	       STATE: TASK_RUNNING (PANIC)

	crash> bt
	PID: 1      TASK: ffff880007150000  CPU: 0   COMMAND: "bash"
	 #0 [ffff88000715bc28] __schedule at ffffffff816801c0
	 #1 [ffff88000715bc40] __module_text_address at ffffffff810ef782
	 #2 [ffff88000715bc58] is_module_text_address at ffffffff810f625e
	 #3 [ffff88000715bc68] __kernel_text_address at ffffffff810a85ad
	 #4 [ffff88000715bc80] print_context_stack at ffffffff810174e3
	 #5 [ffff88000715bce0] dump_trace at ffffffff81016391
	 #6 [ffff88000715bd60] show_trace_log_lvl at ffffffff810176ad
	 #7 [ffff88000715bda8] up at ffffffff810b1cf2
	 #8 [ffff88000715bdc8] console_unlock at ffffffff8108137e
	 #9 [ffff88000715be08] i8042_panic_blink at ffffffff814c362d
	#10 [ffff88000715be28] panic at ffffffff81679de0
	#11 [ffff88000715beb0] do_exit at ffffffff810870ff
	#12 [ffff88000715bf40] do_group_exit at ffffffff81087183
	#13 [ffff88000715bf70] sys_exit_group at ffffffff81087204
	#14 [ffff88000715bf80] system_call_fastpath at ffffffff8168ba89
	    RIP: 00007f2493bdaaf8  RSP: 00007fff2ae49ee8  RFLAGS: 00010206
	    RAX: 00000000000000e7  RBX: ffffffff8168ba89  RCX: 0000000000000000
	    RDX: 0000000000000000  RSI: 000000000000003c  RDI: 0000000000000000
	    RBP: 00007f2493ec98b8   R8: 00000000000000e7   R9: ffffffffffffff98
	    R10: 00007f24934dcd98  R11: 0000000000000246  R12: ffffffff81087204
	    R13: ffff88000715bf78  R14: 0000000000000000  R15: 00007f2493ecec60
	    ORIG_RAX: 00000000000000e7  CS: 0033  SS: 002b

and everything else seems to work too.

Note:

	- The usage of CRASHBUILTIN doesn't look nice, we need to cleanup
	  this logic. I hope we can do this later, and it seems to me that
	  the usage of MEMORY_SOURCES/DUMPFILE_TYPES needs some cleanups in
	  any case.

	- I can't verify this because x86-64 is not supported, but afaics
	  the current usage of RAMDUMP/is_ramdump_image/read_ramdump is not
	  right. RAMDUMP should be always set if is_ramdump() returns true,
	  and read_ramdump() should not be used if we set KDUMP.

	  But I can't test this, so the patch adds another is_ramdump_image()
	  block before ramdump_to_elf(). Which obviously asks for cleanup too.

Signed-off-by: Oleg Nesterov <oleg at redhat.com>
---
 filesys.c |  2 +-
 main.c    | 11 +++++++++++
 ramdump.c | 21 ++++++++++++++++++++-
 3 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/filesys.c b/filesys.c
index de04486..a1d1d1e 100644
--- a/filesys.c
+++ b/filesys.c
@@ -207,7 +207,7 @@ memory_source_init(void)
 		return;
         } 
 
-	if (pc->dumpfile) {
+	if (pc->dumpfile && !(pc->flags & CRASHBUILTIN)) {
 	        if (!file_exists(pc->dumpfile, NULL))
 	        	error(FATAL, "%s: %s\n", pc->dumpfile, 
 				strerror(ENOENT));
diff --git a/main.c b/main.c
index 821bb4e..9b72c7e 100644
--- a/main.c
+++ b/main.c
@@ -428,6 +428,17 @@ main(int argc, char **argv)
 					"too many dumpfile arguments\n");
 					program_usage(SHORT_FORM);
 			}
+
+			if (is_ramdump_image()) {
+				/*
+				 * FIXME: we set CRASHBUILTIN to tell memory_source_init()
+				 * it should ignore pc->dumpfile and for memory_page_size().
+				 */
+				pc->flags |= CRASHBUILTIN;
+				optind++;
+				continue;
+			}
+
 			pc->dumpfile = ramdump_to_elf();
 			if (is_kdump(pc->dumpfile, KDUMP_LOCAL)) {
 				pc->flags |= KDUMP;
diff --git a/ramdump.c b/ramdump.c
index c6a8a85..e9716ae 100644
--- a/ramdump.c
+++ b/ramdump.c
@@ -232,14 +232,22 @@ end:
 	return e_file;
 }
 
+#define PREFIX(ptr, pat)				\
+	(strncmp((ptr), (pat), sizeof(pat)-1) ?	 0 :	\
+			((ptr) += sizeof(pat)-1, 1))
+
 int is_ramdump(char *p)
 {
 	char *x = NULL, *y = NULL, *pat;
 	size_t len;
 	char *pattern;
 	struct stat64 st;
+	int is_raw = 0;
 	int err = 0;
 
+	if (PREFIX(p, "raw:"))
+		is_raw = 1;
+
 	if (nodes || !strchr(p, '@'))
 		return 0;
 
@@ -276,6 +284,13 @@ int is_ramdump(char *p)
 		pat = NULL;
 	}
 
+	if (nodes && is_raw) {
+		pc->flags2 |= RAMDUMP;
+		/* also disables get_live_memory_source() logic in fd_init() */
+		pc->dumpfile = "ramdump";
+		pc->readmem = read_ramdump;
+		pc->writemem = NULL;
+	}
 	return nodes;
 }
 
@@ -345,7 +360,11 @@ show_ramdump_files(void)
 {
 	int i;
 
-	fprintf(fp, "%s [temporary ELF header]\n", elf_default);
+	if (pc->flags & KDUMP)
+		fprintf(fp, "%s [temporary ELF header]\n", elf_default);
+	else
+		fprintf(fp, "%s [raw]\n", pc->dumpfile);
+
 	for (i = 0; i < nodes; i++) {
 		fprintf(fp, "%s              %s", 
 			i ? "\n" : "", ramdump[i].path);
-- 
2.5.0




More information about the Crash-utility mailing list