From 4af3e83b10b17bbd31099d55c2e272d56fb0ef13 Mon Sep 17 00:00:00 2001 From: Yunlian Jiang Date: Wed, 20 Dec 2017 12:16:34 -0800 Subject: [PATCH] Fix minidump on ChromeOS Chrome somehow changed the memory mapping with hugepage enabled. This makes the hack in CrOSPostProcessMappings more general. BUG=chromium:793452 TEST=with this patch on Chromium, minidump_dump *dmp shows the right information on chrome Change-Id: Iff58bf1a712a6e66cbd2d813422db7549a3080a5 Reviewed-on: https://chromium-review.googlesource.com/837963 Reviewed-by: Mark Mentovai --- .../linux/minidump_writer/linux_dumper.cc | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/client/linux/minidump_writer/linux_dumper.cc b/src/client/linux/minidump_writer/linux_dumper.cc index 9a7a8542..515af3ff 100644 --- a/src/client/linux/minidump_writer/linux_dumper.cc +++ b/src/client/linux/minidump_writer/linux_dumper.cc @@ -230,20 +230,21 @@ void CrOSPostProcessMappings(wasteful_vector& mappings) { l = m + 1; } - // Try to merge segments into the first. - if (next < mappings.size()) { - TryRecoverMappings(mappings[0], mappings[next]); - if (next - 1 > 0) - TryRecoverMappings(mappings[next - 1], mappings[0], mappings[next]); - } + // Shows the range that contains the entry point is + // [first_start_addr, first_end_addr) + size_t first_start_addr = mappings[0]->start_addr; + size_t first_end_addr = mappings[0]->start_addr + mappings[0]->size; + + // Put the out-of-order segment in order. + std::rotate(mappings.begin(), mappings.begin() + 1, mappings.begin() + next); // Iterate through normal, sorted cases. // Normal case 1. - for (size_t i = 1; i < mappings.size() - 1; i++) + for (size_t i = 0; i < mappings.size() - 1; i++) TryRecoverMappings(mappings[i], mappings[i + 1]); // Normal case 2. - for (size_t i = 1; i < mappings.size() - 2; i++) + for (size_t i = 0; i < mappings.size() - 2; i++) TryRecoverMappings(mappings[i], mappings[i + 1], mappings[i + 2]); // Collect merged (size == 0) segments. @@ -252,6 +253,22 @@ void CrOSPostProcessMappings(wasteful_vector& mappings) { if (mappings[e]->size > 0) mappings[f++] = mappings[e]; mappings.resize(f); + + // The entry point is in the first mapping. We want to find the location + // of the entry point after merging segment. To do this, we want to find + // the mapping that covers the first mapping from the original mapping list. + // If the mapping is not in the beginning, we move it to the begining via + // a right rotate by using reverse iterators. + for (l = 0; l < mappings.size(); l++) { + if (mappings[l]->start_addr <= first_start_addr + && (mappings[l]->start_addr + mappings[l]->size >= first_end_addr)) + break; + } + if (l > 0) { + r = mappings.size(); + std::rotate(mappings.rbegin() + r - l - 1, mappings.rbegin() + r - l, + mappings.rend()); + } } #endif // __CHROMEOS__