aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/google_breakpad/processor/minidump.h5
-rw-r--r--src/processor/minidump.cc103
2 files changed, 60 insertions, 48 deletions
diff --git a/src/google_breakpad/processor/minidump.h b/src/google_breakpad/processor/minidump.h
index 26b8b8da..785428b8 100644
--- a/src/google_breakpad/processor/minidump.h
+++ b/src/google_breakpad/processor/minidump.h
@@ -541,6 +541,11 @@ class MinidumpModuleList : public MinidumpStream,
bool Read(uint32_t expected_size);
+ bool StoreRange(const MinidumpModule& module,
+ uint64_t base_address,
+ uint32_t module_index,
+ uint32_t module_count);
+
// The largest number of modules that will be read from a minidump. The
// default is 1024.
static uint32_t max_modules_;
diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc
index ea44c509..fa21f273 100644
--- a/src/processor/minidump.cc
+++ b/src/processor/minidump.cc
@@ -416,6 +416,11 @@ string MDGUIDToString(const MDGUID& uuid) {
return std::string(buf);
}
+bool IsDevAshmem(const string& filename) {
+ const string kDevAshmem("/dev/ashmem/");
+ return filename.compare(0, kDevAshmem.length(), kDevAshmem) == 0;
+}
+
} // namespace
//
@@ -2674,8 +2679,7 @@ bool MinidumpModuleList::Read(uint32_t expected_size) {
scoped_ptr<MinidumpModules> modules(
new MinidumpModules(module_count, MinidumpModule(minidump_)));
- for (unsigned int module_index = 0;
- module_index < module_count;
+ for (uint32_t module_index = 0; module_index < module_count;
++module_index) {
MinidumpModule* module = &(*modules)[module_index];
@@ -2693,17 +2697,16 @@ bool MinidumpModuleList::Read(uint32_t expected_size) {
// 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;
+ for (uint32_t module_index = 0; module_index < module_count;
++module_index) {
- MinidumpModule* module = &(*modules)[module_index];
+ MinidumpModule& module = (*modules)[module_index];
// ReadAuxiliaryData fails if any data that the module indicates should
// exist is missing, but we treat some such cases as valid anyway. See
// issue #222: if a debugging record is of a format that's too large to
// handle, it shouldn't render the entire dump invalid. Check module
// validity before giving up.
- if (!module->ReadAuxiliaryData() && !module->valid()) {
+ if (!module.ReadAuxiliaryData() && !module.valid()) {
BPLOG(ERROR) << "MinidumpModuleList could not read required module "
"auxiliary data for module " <<
module_index << "/" << module_count;
@@ -2713,52 +2716,35 @@ bool MinidumpModuleList::Read(uint32_t expected_size) {
// It is safe to use module->code_file() after successfully calling
// module->ReadAuxiliaryData or noting that the module is valid.
- uint64_t base_address = module->base_address();
- uint64_t module_size = module->size();
+ uint64_t base_address = module.base_address();
+ uint64_t module_size = module.size();
if (base_address == static_cast<uint64_t>(-1)) {
- BPLOG(ERROR) << "MinidumpModuleList found bad base address "
- "for module " << module_index << "/" << module_count <<
- ", " << module->code_file();
+ BPLOG(ERROR) << "MinidumpModuleList found bad base address for module "
+ << module_index << "/" << module_count << ", "
+ << module.code_file();
return false;
}
- if (!range_map_->StoreRange(base_address, module_size, module_index)) {
- // Android's shared memory implementation /dev/ashmem can contain
- // duplicate entries for JITted code, so ignore these.
- // TODO(wfh): Remove this code when Android is fixed.
- // See https://crbug.com/439531
- const string kDevAshmem("/dev/ashmem/");
- if (module->code_file().compare(
- 0, kDevAshmem.length(), kDevAshmem) != 0) {
- 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 << ", " <<
- module->code_file() << ", " <<
- HexString(base_address) << "+" <<
- HexString(module_size);
+ if (!StoreRange(module, base_address, module_index, module_count)) {
+ if (base_address >= last_end_address) {
+ BPLOG(ERROR) << "MinidumpModuleList could not store module "
+ << module_index << "/" << module_count << ", "
+ << module.code_file() << ", " << HexString(base_address)
+ << "+" << HexString(module_size);
+ return false;
+ }
+
+ // 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;
}
}
last_end_address = base_address + module_size;
@@ -2773,6 +2759,27 @@ bool MinidumpModuleList::Read(uint32_t expected_size) {
return true;
}
+bool MinidumpModuleList::StoreRange(const MinidumpModule& module,
+ uint64_t base_address,
+ uint32_t module_index,
+ uint32_t module_count) {
+ if (range_map_->StoreRange(base_address, module.size(), module_index))
+ return true;
+
+ // Android's shared memory implementation /dev/ashmem can contain duplicate
+ // entries for JITted code, so ignore these.
+ // TODO(wfh): Remove this code when Android is fixed.
+ // See https://crbug.com/439531
+ if (IsDevAshmem(module.code_file())) {
+ BPLOG(INFO) << "MinidumpModuleList ignoring overlapping module "
+ << module_index << "/" << module_count << ", "
+ << module.code_file() << ", " << HexString(base_address) << "+"
+ << HexString(module.size());
+ return true;
+ }
+
+ return false;
+}
const MinidumpModule* MinidumpModuleList::GetModuleForAddress(
uint64_t address) const {