[minicoredumper] [PATCH 10/14] minicoredumper: Ignore errors during data copy

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


Despite checking, copying of some memory regions may fail (e.g. [vvar]).
In this case we want to ignore errors and copy a remaining data, to save
as much as possible the data in the target core (or fatcore) file.

Change-Id: I0b027113fbfd1a9def88174f94eb20916d10eda2
---
 src/minicoredumper/corestripper.c | 65 +++++++++++++++++++++++++++------------
 1 file changed, 45 insertions(+), 20 deletions(-)

diff --git a/src/minicoredumper/corestripper.c b/src/minicoredumper/corestripper.c
index ed2fd97..564c1fa 100644
--- a/src/minicoredumper/corestripper.c
+++ b/src/minicoredumper/corestripper.c
@@ -922,7 +922,7 @@ static bool is_file(int fd) {
  * Copy data from a source core to (optionally) multiple destination cores.
  * Assumes all files are already positioned correctly to begin.
  */
-static int copy_data(int src, int dest, int dest2, size_t len, char *pagebuf)
+static size_t copy_data(int src, int dest, int dest2, size_t len, char *pagebuf)
 {
 	size_t chunk;
 	int ret;
@@ -940,16 +940,16 @@ static int copy_data(int src, int dest, int dest2, size_t len, char *pagebuf)
 
 		ret = read_file_fd(src, pagebuf, chunk);
 		if (ret < 0) {
-			info("read core failed at 0x%lx",
+			info("Couldn't read data at 0x%lx",
 			     lseek64(src, 0, SEEK_CUR));
-			return -1;
+			break;
 		}
 
 		ret = write_func(dest, pagebuf, chunk);
 		if (ret < 0) {
 			info("write core failed at 0x%lx",
 			     lseek64(dest, 0, SEEK_CUR));
-			return -1;
+			break;
 		}
 
 		if (dest2 >= 0) {
@@ -957,14 +957,14 @@ static int copy_data(int src, int dest, int dest2, size_t len, char *pagebuf)
 			if (ret < 0) {
 				info("write core2 failed at 0x%lx",
 				     lseek64(dest2, 0, SEEK_CUR));
-				return -1;
+				break;
 			}
 		}
 
 		len -= chunk;
 	}
 
-	return 0;
+	return len;
 }
 
 struct sparse {
@@ -1174,6 +1174,41 @@ static void close_compressor(int fd)
 	signal(SIGPIPE, SIG_DFL);
 }
 
+// In case some memory regions could not be read, minicoredumper will jump
+// to the next page instead of return an error code. This situation can
+// take place for example on x86 if one of registers points to around
+// [vvar] memory region.
+static void force_copy_data(int src, int dst, size_t len, char *pagebuf)
+{
+	while (len > 0) {
+		off64_t prev_src_offset = lseek64(src, 0, SEEK_CUR);
+		off64_t prev_dst_offset = lseek64(dst, 0, SEEK_CUR);
+
+		size_t remaining = copy_data(src, dst, -1, len, pagebuf);
+
+		if (remaining != 0) {
+			off64_t next_page_start = (prev_src_offset + (len - remaining) + (size_t)PAGESZ) & ~(PAGESZ - 1);
+			off64_t skip = next_page_start - prev_src_offset;
+
+			if (skip > len)
+				skip = len;
+			len -= skip;
+
+			info("Skip 0x%" PRIx64 " bytes, read from: 0x%" PRIx64, skip, next_page_start);
+			if (lseek64(src, prev_src_offset + skip, SEEK_SET) < 0) {
+				info("lseek64 src to 0x%"  PRIx64 " error: %m", prev_src_offset + skip);
+				break;
+			}
+			if (lseek64(dst, prev_dst_offset + skip, SEEK_SET) < 0) {
+				info("lseek64 dst to 0x%" PRIx64 " error: %m", prev_dst_offset + skip);
+				break;
+			}
+		} else {
+			len = 0;
+		}
+	}
+}
+
 static int dump_compressed_tar(struct dump_info *di)
 {
 	struct core_data *extended_data = NULL;
@@ -1325,10 +1360,7 @@ static int dump_compressed_tar(struct dump_info *di)
 			block_bytes_written += cur->start - offset;
 		}
 
-		if (copy_data(cur->mem_fd, fd, -1,
-		    cur->end - cur->start, buf) < 0) {
-			goto out;
-		}
+		force_copy_data(cur->mem_fd, fd, cur->end - cur->start, buf);
 		block_bytes_written += cur->end - cur->start;
 		offset = cur->end;
 	}
@@ -1393,10 +1425,7 @@ static int dump_compressed_core(struct dump_info *di)
 
 		dump_zero(fd, cur->start - pos);
 
-		if (copy_data(cur->mem_fd, fd, -1,
-			      cur->end - cur->start, buf) < 0) {
-			goto out;
-		}
+		force_copy_data(cur->mem_fd, fd, cur->end - cur->start, buf);
 
 		pos = cur->end;
 	}
@@ -1449,10 +1478,7 @@ static void dump_mini_core(struct dump_info *di)
 			goto out;
 		}
 
-		if (copy_data(cur->mem_fd, di->core_fd, -1,
-			      cur->end - cur->start, buf) < 0) {
-			goto out;
-		}
+		force_copy_data(cur->mem_fd, di->core_fd, cur->end - cur->start, buf);
 	}
 
 	info("core path: %s", di->core_path);
@@ -2848,8 +2874,7 @@ static void dump_fat_core(struct dump_info *di)
 			goto out;
 		}
 
-		if (copy_data(di->mem_fd, di->fatcore_fd, -1, len, buf) < 0)
-			break;
+		copy_data(di->mem_fd, di->fatcore_fd, -1, len, buf);
 	}
 
 out:
-- 
2.7.4




More information about the minicoredumper mailing list