[PATCH v2] Add read diagnostics to crash

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

 



Re-posting the patch as an attachment. I'm sorry for the mess on the first pass.

--
David.
I have been shown several alleged crash bugs that much effort revealed to be 
actually just incomplete or corrupt dump files. This set of changes adds a 
debug level 8 set of messages that allows for an easier optional diagnosis of 
faulty crash dumps through identification of the runtime read_mem() instance 
(crash dump type) and tracing of it's behavior (structure parsing). It also 
adds some optional messages for identifiable error cases that currently only 
use error codes.

This patch is based on crash-6.0.2

Signed-off-by: David Mair <dmair@xxxxxxxx>
---
diff --git a/a/diskdump.c b/b/diskdump.c
index 5519af7..7cad9dc 100644
--- a/a/diskdump.c
+++ b/b/diskdump.c
@@ -432,6 +432,8 @@ restart:
 
 	dd->dumpable_bitmap = calloc(bitmap_len, 1);
 
+	if (CRASHDEBUG(8))
+		error(INFO, "     memory bitmap: %llx\n", offset);
 	if (FLAT_FORMAT()) {
 		if (!read_flattened_format(dd->dfd, offset, dd->bitmap, bitmap_len)) {
 			error(INFO, "%s: cannot read memory bitmap\n",
@@ -829,6 +831,9 @@ read_diskdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
 
 	pfn = paddr_to_pfn(paddr);
 
+	if (CRASHDEBUG(8))
+		error(INFO, "read_diskdump(%d, %llx, %d, %lx, %llx), pfn=%lx\n",
+			fd, (ulonglong)bufptr, cnt, addr, (ulonglong)paddr, pfn);
 	if (KDUMP_SPLIT()) {
 		/* Find proper dd */
 		int i;
@@ -844,27 +849,54 @@ read_diskdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
 			}
 		}
 
-		if (i == num_dumpfiles)
+		if (i == num_dumpfiles) {
+			if (CRASHDEBUG(8))
+				error(INFO, "Address is beyond last dumpfile.\n");
 			return SEEK_ERROR;
+		}
 	}
 
 	curpaddr = paddr & ~((physaddr_t)(dd->block_size-1));
 	page_offset = paddr & ((physaddr_t)(dd->block_size-1));
 
-	if ((pfn >= dd->header->max_mapnr) || !page_is_ram(pfn))
+	if ((pfn >= dd->header->max_mapnr) || !page_is_ram(pfn)) {
+		if (CRASHDEBUG(8) && (pfn >= dd->header->max_mapnr))
+			error(INFO, "pfn (%lx) is >= maximum map number (%lx)\n",
+				pfn, dd->header->max_mapnr);
+		if (CRASHDEBUG(8) && !page_is_ram(pfn))
+			error(INFO, "pfn (%lx) is not in ram\n", pfn);
 		return SEEK_ERROR;
+	}
 	if (!page_is_dumpable(pfn)) {
 		if ((dd->flags & (ZERO_EXCLUDED|ERROR_EXCLUDED)) ==
-		    ERROR_EXCLUDED)
+		    ERROR_EXCLUDED) {
+			if (CRASHDEBUG(8))
+				error(INFO, "pfn (%lx) is excluded\n", pfn);
 			return PAGE_EXCLUDED;
+		}
+		if (CRASHDEBUG(8))
+			error(INFO, "Zero-filling page with pfn=%lx\n", pfn);
 		memset(bufptr, 0, cnt);
 		return cnt;
 	}
 
-	if (!page_is_cached(curpaddr))
-		if ((ret = cache_page(curpaddr)) < 0)
+	if (!page_is_cached(curpaddr)) {
+		if (CRASHDEBUG(8))
+			error(INFO, "caching page with current physaddr=%llx\n", 
+			      curpaddr);
+		if ((ret = cache_page(curpaddr)) < 0) {
+			if (CRASHDEBUG(8))
+				error(INFO, "Failed with err=%d to cache page "
+					"with current physaddr=%llx\n", 
+						ret, curpaddr);
 			return ret;
+		}
+	}
 	
+	if (CRASHDEBUG(8))
+		error(INFO, "Buffering page with pfn=%lx and current "
+			"physaddr=%llx\n", 
+				pfn, curpaddr);
 	memcpy(bufptr, dd->curbufptr + page_offset, cnt);
 
 	return cnt;
diff --git a/a/filesys.c b/b/filesys.c
index 6994fb0..7a8ec3d 100755
--- a/a/filesys.c
+++ b/b/filesys.c
@@ -163,6 +163,8 @@ memory_source_init(void)
 			error(INFO, "using /dev/mem\n\n");
 			pc->flags &= ~MEMMOD;
 			pc->flags |= DEVMEM;
+			if (CRASHDEBUG(8))
+				error(INFO, "Setting readmem to read_dev_mem\n");
 			pc->readmem = read_dev_mem;
 			pc->writemem = write_dev_mem;
 			pc->live_memsrc = "/dev/mem";
@@ -3382,6 +3384,8 @@ get_live_memory_source(void)
 	if (use_module) {
 		pc->flags &= ~DEVMEM;
 		pc->flags |= MEMMOD;
+		if (CRASHDEBUG(8))
+			error(INFO, "Setting readmem to read_memory_device\n");
 		pc->readmem = read_memory_device;
 		pc->writemem = write_memory_device;
 		pc->live_memsrc = pc->memory_device;
@@ -3390,6 +3394,9 @@ get_live_memory_source(void)
 	if (crashbuiltin) {
 		pc->flags &= ~DEVMEM;
 		pc->flags |= CRASHBUILTIN;
+		if (CRASHDEBUG(8))
+			error(INFO, "Setting readmem to "
+				"read_memory_device/builtin\n");
 		pc->readmem = read_memory_device;
 		pc->writemem = write_memory_device;
 		pc->live_memsrc = pc->memory_device;
diff --git a/a/main.c b/b/main.c
index ae8d933..5440c72 100755
--- a/a/main.c
+++ b/b/main.c
@@ -431,6 +431,9 @@ main(int argc, char **argv)
                         	}
 				pc->flags |= DEVMEM;
 				pc->dumpfile = NULL;
+				if (CRASHDEBUG(8))
+					error(INFO, "Setting readmem to "
+							"read_dev_mem\n");
 				pc->readmem = read_dev_mem;
 				pc->writemem = write_dev_mem;
 				pc->live_memsrc = argv[optind];
@@ -443,6 +446,9 @@ main(int argc, char **argv)
 				}
 				pc->flags |= PROC_KCORE;
 				pc->dumpfile = NULL;
+				if (CRASHDEBUG(8))
+					error(INFO, "Setting readmem to "
+							"read_proc_kcore\n");
 				pc->readmem = read_proc_kcore;
 				pc->writemem = write_proc_kcore;
 				pc->live_memsrc = argv[optind];
@@ -457,9 +463,15 @@ main(int argc, char **argv)
                                 pc->dumpfile = argv[optind];
 
 				if (is_sadump_xen()) {
+					if (CRASHDEBUG(8))
+						error(INFO, "Setting readmem to "
+								"read_kdump\n");
 					pc->readmem = read_kdump;
 					pc->writemem = write_kdump;
 				} else {
+					if (CRASHDEBUG(8))
+						error(INFO, "Setting readmem to "
+								"read_netdump\n");
 					pc->readmem = read_netdump;
 					pc->writemem = write_netdump;
 				}
@@ -472,6 +484,9 @@ main(int argc, char **argv)
                                 }
                                 pc->flags |= KDUMP;
                                 pc->dumpfile = argv[optind];
+				if (CRASHDEBUG(8))
+					error(INFO, "Setting readmem to "
+						"read_kdump for KDUMP_LOCAL\n");
                                 pc->readmem = read_kdump;
                                 pc->writemem = write_kdump;
 
@@ -483,6 +498,9 @@ main(int argc, char **argv)
                                 }
                                 pc->flags |= KVMDUMP;
                                 pc->dumpfile = argv[optind];
+				if (CRASHDEBUG(8))
+					error(INFO, "Setting readmem to "
+							"read_kvmdump\n");
                                 pc->readmem = read_kvmdump;
                                 pc->writemem = write_kvmdump;
 
@@ -502,6 +520,9 @@ main(int argc, char **argv)
                                 }
                                 pc->flags |= XENDUMP;
                                 pc->dumpfile = argv[optind];
+				if (CRASHDEBUG(8))
+					error(INFO, "Setting readmem to "
+							"read_xendump\n");
                                 pc->readmem = read_xendump;
                                 pc->writemem = write_xendump;
 
@@ -518,6 +539,9 @@ main(int argc, char **argv)
                                 }
                                 pc->flags |= DISKDUMP;
                                 pc->dumpfile = argv[optind];
+				if (CRASHDEBUG(8))
+					error(INFO, "Setting readmem to "
+							"read_diskdump\n");
                                 pc->readmem = read_diskdump;
                                 pc->writemem = write_diskdump;
 
@@ -529,6 +553,9 @@ main(int argc, char **argv)
                                 }
                                 pc->flags |= LKCD;
                                 pc->dumpfile = argv[optind];
+				if (CRASHDEBUG(8))
+					error(INFO, "Setting readmem to "
+							"read_lkcddump\n");
 				pc->readmem = read_lkcd_dumpfile;
 				pc->writemem = write_lkcd_dumpfile;
 
@@ -540,6 +567,9 @@ main(int argc, char **argv)
                                 }
 				pc->flags |= MCLXCD;
 				pc->dumpfile = argv[optind];
+				if (CRASHDEBUG(8))
+					error(INFO, "Setting readmem to "
+							"read_mclxdump\n");
 				pc->readmem = read_mclx_dumpfile;
 				pc->writemem = write_mclx_dumpfile;
 
@@ -551,6 +581,9 @@ main(int argc, char **argv)
                                 }
                                 pc->flags |= S390D;
                                 pc->dumpfile = argv[optind];
+				if (CRASHDEBUG(8))
+					error(INFO, "Setting readmem to "
+							"read_s390_dumpfile\n");
                                 pc->readmem = read_s390_dumpfile;
                                 pc->writemem = write_s390_dumpfile;
 
@@ -563,6 +596,9 @@ main(int argc, char **argv)
 				}
 				pc->flags |= SADUMP;
 				pc->dumpfile = argv[optind];
+				if (CRASHDEBUG(8))
+					error(INFO, "Setting readmem to "
+							"read_sadump\n");
 				pc->readmem = read_sadump;
 				pc->writemem = write_sadump;
 
@@ -950,6 +986,8 @@ setup_environment(int argc, char **argv)
 	pc->flags |= DATADEBUG;          /* default until unnecessary */
 	pc->confd = -2;
 	pc->machine_type = MACHINE_TYPE;
+	if (CRASHDEBUG(8))
+		error(INFO, "Setting readmem to default read_dev_mem\n");
 	pc->readmem = read_dev_mem;      /* defaults until argv[] is parsed */
 	pc->writemem = write_dev_mem;
 	pc->memory_module = NULL;
@@ -1600,8 +1638,11 @@ check_xen_hyper(void)
 
 #ifdef XEN_HYPERVISOR_ARCH
 	pc->cmd_table = xen_hyper_command_table;
-	if (pc->flags & XENDUMP)
+	if (pc->flags & XENDUMP) {
+		if (CRASHDEBUG(8))
+			error(INFO, "Setting readmem to read_xendump_hyper\n");
 		pc->readmem = read_xendump_hyper;
+	}
 #else
 	error(FATAL, XEN_HYPERVISOR_NOT_SUPPORTED);
 #endif
diff --git a/a/memory.c b/b/memory.c
index 95eefc9..ac64767 100755
--- a/a/memory.c
+++ b/b/memory.c
@@ -2215,6 +2215,8 @@ switch_to_proc_kcore(void)
 
 	pc->flags &= ~DEVMEM;
 	pc->flags |= PROC_KCORE;
+	if (CRASHDEBUG(8))
+		error(INFO, "Setting readmem to read_proc_kcore for memory.c\n");
 	pc->readmem = read_proc_kcore;
 	pc->writemem = write_proc_kcore;
 	pc->live_memsrc = "/proc/kcore";
diff --git a/a/netdump.c b/b/netdump.c
index 4011f36..28989c9 100644
--- a/a/netdump.c
+++ b/b/netdump.c
@@ -495,6 +495,10 @@ read_netdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
 	off_t offset;
 	struct pt_load_segment *pls;
 	int i;
+	
+	if (CRASHDEBUG(8))
+		error(INFO, "read_netdump(%d, %llx, %d, %lx, %llx)\n",
+			fd, (ulonglong)bufptr, cnt, addr, (ulonglong)paddr);
 
 	offset = 0;
 
@@ -509,6 +513,9 @@ read_netdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
 	{
 	case NETDUMP_ELF32:
 		offset = (off_t)paddr + (off_t)nd->header_size;
+		if (CRASHDEBUG(8))
+			error(INFO, "read NETDUMP_ELF32 for offset: %llx\n",
+				(ulonglong)offset);
 		break;
 
 	case NETDUMP_ELF64:
@@ -517,6 +524,10 @@ read_netdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
 		if (nd->num_pt_load_segments == 1) {
 			offset = (off_t)paddr + (off_t)nd->header_size -
 				(off_t)nd->pt_load_segments[0].phys_start;
+			if (CRASHDEBUG(8))
+				error(INFO, "read KDUMP or NETDUMP_ELF64 for "
+						"single segment: %llx\n",
+							(ulonglong)offset);
 			break;
 		}
 
@@ -526,11 +537,18 @@ read_netdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
 			    (paddr < pls->phys_end)) {
 				offset = (off_t)(paddr - pls->phys_start) +
 					pls->file_offset;
+				if (CRASHDEBUG(8))
+					error(INFO, "read KDUMP or NETDUMP_ELF64 "
+						"for multi-segment: %llx\n",
+							(ulonglong)offset);
 				break;
 			}
 			if (pls->zero_fill && (paddr >= pls->phys_end) &&
 			    (paddr < pls->zero_fill)) {
 				memset(bufptr, 0, cnt);
+				if (CRASHDEBUG(8))
+					error(INFO, "read KDUMP or NETDUMP_ELF64 "
+							"for zero-fill\n");
                 		return cnt;
 			}
 		}
@@ -542,9 +560,15 @@ read_netdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
 	}	
 
 	if (FLAT_FORMAT()) {
+		if (CRASHDEBUG(8))
+			error(INFO, "read flat-format offset: %llx\n", 
+				(ulonglong)offset);
 		if (!read_flattened_format(nd->ndfd, offset, bufptr, cnt))
 			return READ_ERROR;
 	} else {
+		if (CRASHDEBUG(8))
+			error(INFO, "seek and read offset: %llx\n", 
+				(ulonglong)offset);
 		if (lseek(nd->ndfd, offset, SEEK_SET) == -1)
 			return SEEK_ERROR;
 		if (read(nd->ndfd, bufptr, cnt) != cnt)
@@ -2618,6 +2642,9 @@ get_kdump_panic_task(void)
 int
 read_kdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
 {
+	if (CRASHDEBUG(8))
+		error(INFO, "read_kdump for: virt=%lx phys=%llx\n", 
+				addr, (ulonglong)paddr);
 	if (XEN_CORE_DUMPFILE() && !XEN_HYPER_MODE()) {
 	    	if (!(nd->xen_kdump_data->flags & KDUMP_P2M_INIT)) {
         		if (!machdep->xen_kdump_p2m_create)
@@ -2640,6 +2667,10 @@ read_kdump(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
 			return READ_ERROR;
 	}
 
+	if (CRASHDEBUG(8))
+		error(INFO, "read_kdump trying read_netdump for: virt=%lx "
+					"phys=%llx\n", 
+				addr, (ulonglong)paddr);
 	return read_netdump(fd, bufptr, cnt, addr, paddr);
 }
 
diff --git a/a/remote.c b/b/remote.c
index a06c14b..d84d556 100755
--- a/a/remote.c
+++ b/b/remote.c
@@ -2244,6 +2244,8 @@ remote_fd_init(void)
          	 *  if no remote dumpfile name was entered.  If it is /dev/mem,
          	 *  then also go get the remote /proc/version.
          	 */
+		if (CRASHDEBUG(8))
+			error(INFO, "Setting readmem to read_daemon\n");
 		pc->readmem = read_daemon;
 
 		if (!pc->server_memsrc) 
diff --git a/a/x86.c b/b/x86.c
index df91110..f166a02 100755
--- a/a/x86.c
+++ b/b/x86.c
@@ -4390,6 +4390,8 @@ x86_xen_kdump_p2m_create(struct xen_kdump_data *xkd)
 	 *  Temporarily read physical (machine) addresses from vmcore by
 	 *  going directly to read_netdump() instead of via read_kdump().
 	 */ 
+	if (CRASHDEBUG(8))
+		error(INFO, "Setting readmem to read_netdump for x86\n");
 	pc->readmem = read_netdump;
 
 	if (xkd->flags & KDUMP_CR3)
@@ -4467,6 +4469,8 @@ x86_xen_kdump_p2m_create(struct xen_kdump_data *xkd)
                 fprintf(fp, "\n");
         }
 
+	if (CRASHDEBUG(8))
+		error(INFO, "Setting readmem to read_kdump for x86\n");
 	pc->readmem = read_kdump;
 	return TRUE;
 
@@ -4553,6 +4557,9 @@ use_cr3:
 
         machdep->last_ptbl_read = 0;
         machdep->last_pmd_read = 0;
+	if (CRASHDEBUG(8))
+		error(INFO, "Setting readmem to read_kdump for x86 and "
+					"use cr3\n");
 	pc->readmem = read_kdump;
 
 	return TRUE;
diff --git a/a/x86_64.c b/b/x86_64.c
index 689317f..26fb397 100755
--- a/a/x86_64.c
+++ b/b/x86_64.c
@@ -5398,6 +5398,8 @@ x86_64_xen_kdump_p2m_create(struct xen_kdump_data *xkd)
          *  Temporarily read physical (machine) addresses from vmcore by
          *  going directly to read_netdump() instead of via read_kdump().
          */
+	if (CRASHDEBUG(8))
+		error(INFO, "Setting readmem to read_netdump for x86_64\n");
         pc->readmem = read_netdump;
 
         if (xkd->flags & KDUMP_CR3)
@@ -5458,6 +5460,8 @@ x86_64_xen_kdump_p2m_create(struct xen_kdump_data *xkd)
 		fprintf(fp, "\n");
 	}
 
+	if (CRASHDEBUG(8))
+		error(INFO, "Setting readmem to read_kdump for x86_64\n");
         pc->readmem = read_kdump;
 	return TRUE;
 
@@ -5524,6 +5528,9 @@ use_cr3:
 	machdep->last_pgd_read = 0;
         machdep->last_ptbl_read = 0;
         machdep->last_pmd_read = 0;
+	if (CRASHDEBUG(8))
+		error(INFO, "Setting readmem to read_kdump for x86_64 and "
+				"using cr3\n");
         pc->readmem = read_kdump;
 
         return TRUE;
--
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