Index: breakpad/linux/minidump_writer.cc |
diff --git a/breakpad/linux/minidump_writer.cc b/breakpad/linux/minidump_writer.cc |
index 5a1d6c64914dc11c896e24c06c533e0a1e42bf5b..4a9a8a95f775ce00d57db326eda1392d434b9599 100644 |
--- a/breakpad/linux/minidump_writer.cc |
+++ b/breakpad/linux/minidump_writer.cc |
@@ -325,7 +325,7 @@ class MinidumpWriter { |
bool Dump() { |
// A minidump file contains a number of tagged streams. This is the number |
// of stream which we write. |
- static const unsigned kNumWriters = 10; |
+ static const unsigned kNumWriters = 11; |
TypedMDRVA<MDRawHeader> header(&minidump_writer_); |
TypedMDRVA<MDRawDirectory> dir(&minidump_writer_); |
@@ -356,6 +356,10 @@ class MinidumpWriter { |
return false; |
dir.CopyIndex(dir_index++, &dirent); |
+ if (!WriteSystemInfoStream(&dirent)) |
+ return false; |
+ dir.CopyIndex(dir_index++, &dirent); |
+ |
dirent.stream_type = MD_LINUX_CPU_INFO; |
if (!WriteFile(&dirent.location, "/proc/cpuinfo")) |
NullifyDirectoryEntry(&dirent); |
@@ -467,23 +471,43 @@ class MinidumpWriter { |
return true; |
} |
+ static bool ShouldIncludeMapping(const MappingInfo& mapping) { |
+ if (mapping.name[0] == 0 || // we only want modules with filenames. |
+ mapping.offset || // we only want to include one mapping per shared lib. |
+ mapping.size < 4096) { // too small to get a signature for. |
Lei Zhang
2009/05/27 07:10:55
style nit: two space before //
|
+ return false; |
+ } |
+ |
+ return true; |
+ } |
+ |
// Write information about the mappings in effect. Because we are using the |
// minidump format, the information about the mappings is pretty limited. |
// Because of this, we also include the full, unparsed, /proc/$x/maps file in |
// another stream in the file. |
bool WriteMappings(MDRawDirectory* dirent) { |
const unsigned num_mappings = dumper_.mappings().size(); |
+ unsigned num_output_mappings = 0; |
+ |
+ for (unsigned i = 0; i < dumper_.mappings().size(); ++i) { |
+ const MappingInfo& mapping = *dumper_.mappings()[i]; |
+ if (ShouldIncludeMapping(mapping)) |
+ num_output_mappings++; |
+ } |
TypedMDRVA<uint32_t> list(&minidump_writer_); |
- if (!list.AllocateObjectAndArray(num_mappings, sizeof(MDRawModule))) |
+ if (!list.AllocateObjectAndArray(num_output_mappings, sizeof(MDRawModule))) |
return false; |
dirent->stream_type = MD_MODULE_LIST_STREAM; |
dirent->location = list.location(); |
- *list.get() = num_mappings; |
+ *list.get() = num_output_mappings; |
- for (unsigned i = 0; i < num_mappings; ++i) { |
+ for (unsigned i = 0, j = 0; i < num_mappings; ++i) { |
const MappingInfo& mapping = *dumper_.mappings()[i]; |
+ if (!ShouldIncludeMapping(mapping)) |
+ continue; |
+ |
MDRawModule mod; |
my_memset(&mod, 0, sizeof(mod)); |
mod.base_of_image = mapping.start_addr; |
@@ -491,6 +515,30 @@ class MinidumpWriter { |
UntypedMDRVA memory(&minidump_writer_); |
const size_t filename_len = my_strlen(mapping.name); |
+ TypedMDRVA<MDCVInfoPDB70> cv(&minidump_writer_); |
+ if (!cv.Allocate()) |
+ return false; |
+ my_memset(cv.get(), 0, sizeof(MDCVInfoPDB70)); |
+ cv.get()->cv_signature = MD_CVINFOPDB70_SIGNATURE; |
+ |
+ { |
+ // We XOR the first page of the file to get a signature for it. |
+ uint8_t xor_buf[sizeof(MDGUID)]; |
+ size_t done = 0; |
+ uint8_t* const signature = (uint8_t*) &cv.get()->signature; |
+ |
+ while (done < 4096) { |
+ dumper_.CopyFromProcess(xor_buf, crashing_tid_, |
+ (void *) (mod.base_of_image + done), |
+ sizeof(xor_buf)); |
+ for (unsigned i = 0; i < sizeof(xor_buf); ++i) |
+ signature[i] ^= xor_buf[i]; |
+ done += sizeof(xor_buf); |
+ } |
+ } |
+ |
+ mod.cv_record = cv.location(); |
+ |
if (filename_len) { |
MDLocationDescriptor ld; |
if (!minidump_writer_.WriteString(mapping.name, filename_len, &ld)) |
@@ -498,7 +546,7 @@ class MinidumpWriter { |
mod.module_name_rva = ld.rva; |
} |
- list.CopyIndexAfterObject(i, &mod, sizeof(mod)); |
+ list.CopyIndexAfterObject(j++, &mod, sizeof(mod)); |
} |
return true; |
@@ -522,6 +570,25 @@ class MinidumpWriter { |
return true; |
} |
+ bool WriteSystemInfoStream(MDRawDirectory* dirent) { |
+ TypedMDRVA<MDRawSystemInfo> si(&minidump_writer_); |
+ if (!si.Allocate()) |
+ return false; |
+ my_memset(si.get(), 0, sizeof(MDRawSystemInfo)); |
+ |
+ dirent->stream_type = MD_SYSTEM_INFO_STREAM; |
+ dirent->location = si.location(); |
+ |
+ si.get()->processor_architecture = |
+#if defined(__i386) |
+ MD_CPU_ARCHITECTURE_X86; |
+#elif defined(__x86_64) |
+ MD_CPU_ARCHITECTURE_AMD64; |
+#endif |
+ |
+ return true; |
+ } |
+ |
private: |
#if defined(__i386) |
uintptr_t GetStackPointer() { |