diff options
author | ivanpe@chromium.org <ivanpe@chromium.org> | 2015-08-10 17:03:29 +0000 |
---|---|---|
committer | ivanpe@chromium.org <ivanpe@chromium.org> | 2015-08-10 17:03:29 +0000 |
commit | 47527e48e58f5c7d80144f1ecda274e6b89923b2 (patch) | |
tree | 8ca2cb7f4bd0e952d5020cdfd0e641458978476a | |
parent | Fix breakpad for arm on arm64 (diff) | |
download | breakpad-47527e48e58f5c7d80144f1ecda274e6b89923b2.tar.xz |
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 <simonb@chromium.org>.
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
-rw-r--r-- | src/processor/minidump.cc | 31 |
1 files changed, 25 insertions, 6 deletions
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(); |