From 47527e48e58f5c7d80144f1ecda274e6b89923b2 Mon Sep 17 00:00:00 2001 From: "ivanpe@chromium.org" Date: Mon, 10 Aug 2015 17:03:29 +0000 Subject: Workaround for range map overlaps caused by Android package relocation. If there is a range overlap, the cause may be the client correction applied for Android packed relocations. If this is the case, back out the client correction and retry. Patch from Simon Baldwin . https://code.google.com/p/chromium/issues/detail?id=509110 R=simonb@chromium.org Review URL: https://codereview.chromium.org/1275173005 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1480 4c0a9323-5329-0410-9bdc-e9ce6186880e --- src/processor/minidump.cc | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc index f6f642be..8042f014 100644 --- a/src/processor/minidump.cc +++ b/src/processor/minidump.cc @@ -2517,6 +2517,7 @@ bool MinidumpModuleList::Read(uint32_t expected_size) { // MinidumpModule::ReadAuxiliaryData seeks around, and if it were // included in the loop above, additional seeks would be needed where // none are now to read contiguous data. + uint64_t last_end_address = 0; for (unsigned int module_index = 0; module_index < module_count; ++module_index) { @@ -2554,12 +2555,29 @@ bool MinidumpModuleList::Read(uint32_t expected_size) { const string kDevAshmem("/dev/ashmem/"); if (module->code_file().compare( 0, kDevAshmem.length(), kDevAshmem) != 0) { - BPLOG(ERROR) << "MinidumpModuleList could not store module " << - module_index << "/" << module_count << ", " << - module->code_file() << ", " << - HexString(base_address) << "+" << - HexString(module_size); - return false; + if (base_address < last_end_address) { + // If failed due to apparent range overlap the cause may be + // the client correction applied for Android packed relocations. + // If this is the case, back out the client correction and retry. + module_size -= last_end_address - base_address; + base_address = last_end_address; + if (!range_map_->StoreRange(base_address, + module_size, module_index)) { + BPLOG(ERROR) << "MinidumpModuleList could not store module " << + module_index << "/" << module_count << ", " << + module->code_file() << ", " << + HexString(base_address) << "+" << + HexString(module_size) << ", after adjusting"; + return false; + } + } else { + BPLOG(ERROR) << "MinidumpModuleList could not store module " << + module_index << "/" << module_count << ", " << + module->code_file() << ", " << + HexString(base_address) << "+" << + HexString(module_size); + return false; + } } else { BPLOG(INFO) << "MinidumpModuleList ignoring overlapping module " << module_index << "/" << module_count << ", " << @@ -2568,6 +2586,7 @@ bool MinidumpModuleList::Read(uint32_t expected_size) { HexString(module_size); } } + last_end_address = base_address + module_size; } modules_ = modules.release(); -- cgit v1.2.1