[minicoredumper] [PATCH 11/14] minicoredumper: Fix checking if memory regions can be merged

Mateusz Moscicki m.moscicki2 at partner.samsung.com
Tue May 21 14:52:47 CEST 2019


By default the coredump doesn't contain a file-backed private or shared
mappings, so it is sometimes impossible to merge two theoretically
neighboring regions. In this case:

  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  [...]
  LOAD           0x4f77000 0xb2a94000 0x00000000 0x0a000 0x0a000 RW  0x1000
  LOAD           0x4f81000 0xb2a9e000 0x00000000 0x01000 0x01000 RWE 0x1000 [A]
  LOAD           0x4f82000 0xb2a9f000 0x00000000 0x00000 0x02000     0x1000
  LOAD           0x4f82000 0xb2aa1000 0x00000000 0x03000 0x03000 RW  0x1000 [B]
  LOAD           0x4f85000 0xb2aa4000 0x00000000 0x01000 0x01000 RWE 0x1000
  LOAD           0x4f86000 0xb2aa5000 0x00000000 0x00000 0x02000     0x1000
  [...]

we can not merge regions A and B by simply expanding the region A,
because the final minicoredump will contain memory region
0xb2a9e000-0xb2aa2000 at offset 0x4f81000 instead of
0xb2a9e000-0xb2a9f000 at offset 0x4f81000 and 0xb2aa1000-0xb2aa4000 at
offset 0x4f82000

Change-Id: I550446b1ac308d2372545b37127dedf412d7bcb6
---
 src/minicoredumper/corestripper.c | 51 +++++++++++++++++++++++++--------------
 1 file changed, 33 insertions(+), 18 deletions(-)

diff --git a/src/minicoredumper/corestripper.c b/src/minicoredumper/corestripper.c
index 564c1fa..cb0bc2a 100644
--- a/src/minicoredumper/corestripper.c
+++ b/src/minicoredumper/corestripper.c
@@ -1494,10 +1494,15 @@ int add_core_data(struct dump_info *di, off64_t dest_offset, size_t len,
 	struct core_data *cur;
 	struct core_data *tmp;
 	int done = 0;
-	off64_t end;
+	off64_t end, mem_end;
 
 	end = start + len;
+	mem_end = src_offset + len;
 
+	/* By default the coredump doesn't contain a file-backed private or shared
+	 * mappings, so it is sometimes impossible to merge two theoretically
+	 * neighboring regions, so below is checking if we can merge regions or if
+	 * we have to insert new block. */
 	for (cur = di->core_file; cur && !done; cur = cur->next) {
 		if (end < cur->start) {
 			/* insert new block */
@@ -1518,7 +1523,8 @@ int add_core_data(struct dump_info *di, off64_t dest_offset, size_t len,
 			done = 1;
 
 		} else if (end == cur->start) {
-			if ((src_offset + len) == cur->mem_start &&
+			if (mem_end == cur->mem_start &&
+				(src_offset + len) == cur->mem_start &&
 			    src_fd == cur->mem_fd) {
 				/* adjacent block, expand existing block */
 				cur->start = start;
@@ -1545,15 +1551,22 @@ int add_core_data(struct dump_info *di, off64_t dest_offset, size_t len,
 		} else if (start < cur->end) {
 			/* overlapping block, expand existing block */
 			if (start < cur->start) {
-				cur->start = start;
-				cur->mem_start = src_offset;
+				if (cur->start - start == cur->mem_start - src_offset) {
+					cur->start = start;
+					cur->mem_start = src_offset;
+					done = 1;
+				}
 			}
-			if (end > cur->end)
-				cur->end = end;
-			done = 1;
-
+			if (end > cur->end) {
+				if (end - cur->end == mem_end - (cur->mem_start + cur->end - cur->start)) {
+					cur->end = end;
+					done = 1;
+				}
+			}
+			if (end <= cur->end)
+				done = 1;
 		} else if (start == cur->end) {
-			if (src_offset == (cur->mem_start + len)) {
+			if (src_offset == (cur->mem_start + (cur->end - cur->start))) {
 				/* adjacent block, expand existing block */
 				cur->end = end;
 				done = 1;
@@ -1562,13 +1575,15 @@ int add_core_data(struct dump_info *di, off64_t dest_offset, size_t len,
 
 		while (cur->next) {
 			if (cur->next->start < cur->end) {
-				/* consolidate overlapping block */
-				tmp = cur->next;
-				if (tmp->end > cur->end)
-					cur->end = tmp->end;
-				cur->next = tmp->next;
-				free(tmp);
-				continue;
+				if (cur->end - cur->next->start == cur->mem_start + (cur->end - cur->start) - cur->next->mem_start) {
+					/* consolidate overlapping block */
+					tmp = cur->next;
+					if (tmp->end > cur->end)
+						cur->end = tmp->end;
+					cur->next = tmp->next;
+					free(tmp);
+					continue;
+				}
 
 			} else if (cur->next->start == cur->end) {
 				if (((cur->mem_start + (cur->end - cur->start))
@@ -2003,7 +2018,7 @@ static int dump_vma(struct dump_info *di, unsigned long start, size_t len,
 			dump_end = tmp->mem_end;
 
 		/* make sure we have something to dump */
-		if (dump_start < dump_end) {
+		if (dump_start < dump_end && dump_start < tmp->file_end) {
 			len = dump_end - dump_start;
 
 			info("dump: %s: %zu bytes @ 0x%lx", desc ? desc : "",
@@ -2703,7 +2718,7 @@ static int dump_data_content_file(struct dump_info *di,
 	char *tmp_path;
 	FILE *file;
 	int len;
-	int ret;
+	int ret = 0;
 
 	len = strlen(di->dst_dir) + strlen("/dumps/") + 32 +
 	      strlen(dd->ident) + 1;
-- 
2.7.4




More information about the minicoredumper mailing list