[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