Chromium Code Reviews| Index: src/processor/minidump.cc |
| diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc |
| index 753c6df72e66a72662cf5b2edbc4c10b0d91a805..fb583c17be12a3ec23905893111f9a8a60c2e72f 100644 |
| --- a/src/processor/minidump.cc |
| +++ b/src/processor/minidump.cc |
| @@ -1853,11 +1853,30 @@ string MinidumpModule::code_identifier() const { |
| break; |
| } |
| + case MD_OS_ANDROID: |
| + case MD_OS_LINUX: { |
| + // If ELF CodeView data is present, return the debug id. |
| + if (cv_record_ && cv_record_signature_ == MD_CVINFOELF_SIGNATURE) { |
| + const MDCVInfoELF* cv_record_elf = |
| + reinterpret_cast<const MDCVInfoELF*>(&(*cv_record_)[0]); |
| + assert(cv_record_elf->cv_signature == MD_CVINFOELF_SIGNATURE); |
| + |
| + for (unsigned int build_id_index = 0; |
| + build_id_index < (cv_record_->size() - MDCVInfoELF_minsize); |
| + ++build_id_index) { |
| + char byte[3]; |
|
Mark Mentovai
2016/02/09 19:27:05
build_id[build_id_index] is the byte, this is a st
|
| + snprintf(byte, sizeof(byte), "%02x", |
| + cv_record_elf->build_id[build_id_index]); |
| + identifier += byte; |
| + } |
| + break; |
| + } |
| + // Otherwise fall through to the case below. |
| + } |
| + |
| case MD_OS_MAC_OS_X: |
| case MD_OS_IOS: |
| case MD_OS_SOLARIS: |
| - case MD_OS_ANDROID: |
| - case MD_OS_LINUX: |
| case MD_OS_NACL: |
| case MD_OS_PS3: { |
| // TODO(mmentovai): support uuid extension if present, otherwise fall |
| @@ -1908,6 +1927,14 @@ string MinidumpModule::debug_file() const { |
| // GetCVRecord guarantees pdb_file_name is null-terminated. |
| file = reinterpret_cast<const char*>(cv_record_20->pdb_file_name); |
| + } else if (cv_record_signature_ == MD_CVINFOELF_SIGNATURE) { |
| + // It's actually an MDCVInfoELF structure. |
| + const MDCVInfoELF* cv_record_elf = |
| + reinterpret_cast<const MDCVInfoELF*>(&(*cv_record_)[0]); |
| + assert(cv_record_elf->cv_signature == MD_CVINFOELF_SIGNATURE); |
| + |
| + // For MDCVInfoELF, the debug file is the code file. |
| + file = *name_; |
| } |
| // If there's a CodeView record but it doesn't match a known signature, |
| @@ -1959,6 +1986,25 @@ string MinidumpModule::debug_file() const { |
| return file; |
| } |
| +static string guid_and_age_to_debug_id(const MDGUID& guid, |
| + uint32_t age) { |
| + char identifier_string[41]; |
| + snprintf(identifier_string, sizeof(identifier_string), |
| + "%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X%x", |
| + guid.data1, |
| + guid.data2, |
| + guid.data3, |
| + guid.data4[0], |
| + guid.data4[1], |
| + guid.data4[2], |
| + guid.data4[3], |
| + guid.data4[4], |
| + guid.data4[5], |
| + guid.data4[6], |
| + guid.data4[7], |
| + age); |
| + return identifier_string; |
| +} |
| string MinidumpModule::debug_identifier() const { |
| if (!valid_) { |
| @@ -1981,22 +2027,8 @@ string MinidumpModule::debug_identifier() const { |
| // Use the same format that the MS symbol server uses in filesystem |
| // hierarchies. |
| - char identifier_string[41]; |
| - snprintf(identifier_string, sizeof(identifier_string), |
| - "%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X%x", |
| - cv_record_70->signature.data1, |
| - cv_record_70->signature.data2, |
| - cv_record_70->signature.data3, |
| - cv_record_70->signature.data4[0], |
| - cv_record_70->signature.data4[1], |
| - cv_record_70->signature.data4[2], |
| - cv_record_70->signature.data4[3], |
| - cv_record_70->signature.data4[4], |
| - cv_record_70->signature.data4[5], |
| - cv_record_70->signature.data4[6], |
| - cv_record_70->signature.data4[7], |
| - cv_record_70->age); |
| - identifier = identifier_string; |
| + identifier = guid_and_age_to_debug_id(cv_record_70->signature, |
| + cv_record_70->age); |
| } else if (cv_record_signature_ == MD_CVINFOPDB20_SIGNATURE) { |
| // It's actually an MDCVInfoPDB20 structure. |
| const MDCVInfoPDB20* cv_record_20 = |
| @@ -2009,6 +2041,21 @@ string MinidumpModule::debug_identifier() const { |
| snprintf(identifier_string, sizeof(identifier_string), |
| "%08X%x", cv_record_20->signature, cv_record_20->age); |
| identifier = identifier_string; |
| + } else if (cv_record_signature_ == MD_CVINFOELF_SIGNATURE) { |
| + // It's actually an MDCVInfoELF structure. |
| + const MDCVInfoELF* cv_record_elf = |
| + reinterpret_cast<const MDCVInfoELF*>(&(*cv_record_)[0]); |
| + assert(cv_record_elf->cv_signature == MD_CVINFOELF_SIGNATURE); |
| + |
| + // For backwards-compatibility, stuff as many bytes as will fit into |
| + // a MDGUID and use the MS symbol server format as MDCVInfoPDB70 does |
| + // with age = 0. Historically Breakpad would do this during dump |
| + // writing to fit the build id data into a MDCVInfoPDB70 struct. |
| + // The full build id is available by calling code_identifier. |
| + MDGUID guid = {0}; |
| + memcpy(&guid, &cv_record_elf->build_id, |
| + cv_record_->size() - MDCVInfoELF_minsize); |
| + identifier = guid_and_age_to_debug_id(guid, 0); |
| } |
| } |
| @@ -2167,6 +2214,15 @@ const uint8_t* MinidumpModule::GetCVRecord(uint32_t* size) { |
| "0-terminated"; |
| return NULL; |
| } |
| + } else if (signature == MD_CVINFOELF_SIGNATURE) { |
| + // Now that the structure type is known, recheck the size. |
| + if (MDCVInfoELF_minsize > module_.cv_record.data_size) { |
| + BPLOG(ERROR) << "MinidumpModule CodeViewELF record size mismatch, " << |
| + MDCVInfoELF_minsize << " > " << |
| + module_.cv_record.data_size; |
| + return NULL; |
| + } |
| + // There's nothing to swap in CVInfoELF, it's just raw bytes. |
| } |
| // If the signature doesn't match something above, it's not something |
| @@ -2367,6 +2423,20 @@ void MinidumpModule::Print() { |
| cv_record_20->age); |
| printf(" (cv_record).pdb_file_name = \"%s\"\n", |
| cv_record_20->pdb_file_name); |
| + } else if (cv_record_signature_ == MD_CVINFOELF_SIGNATURE) { |
| + const MDCVInfoELF* cv_record_elf = |
| + reinterpret_cast<const MDCVInfoELF*>(cv_record); |
| + assert(cv_record_elf->cv_signature == MD_CVINFOELF_SIGNATURE); |
| + |
| + printf(" (cv_record).cv_signature = 0x%x\n", |
| + cv_record_elf->cv_signature); |
| + printf(" (cv_record).build_id = "); |
| + for (unsigned int build_id_index = 0; |
| + build_id_index < (cv_record_size - MDCVInfoELF_minsize); |
| + ++build_id_index) { |
| + printf("%02x", cv_record_elf->build_id[build_id_index]); |
| + } |
| + printf("\n"); |
| } else { |
| printf(" (cv_record) = "); |
| for (unsigned int cv_byte_index = 0; |