[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