aboutsummaryrefslogtreecommitdiff
path: root/src/client/linux/minidump_writer/minidump_writer.cc
diff options
context:
space:
mode:
authorrmcilroy@chromium.org <rmcilroy@chromium.org@4c0a9323-5329-0410-9bdc-e9ce6186880e>2014-07-22 11:34:11 +0000
committerrmcilroy@chromium.org <rmcilroy@chromium.org@4c0a9323-5329-0410-9bdc-e9ce6186880e>2014-07-22 11:34:11 +0000
commit561f81873562d407ac1c39144b30e26163e0045d (patch)
tree7f2c072ddac47a40a34e46a36784dfcdd4fc411e /src/client/linux/minidump_writer/minidump_writer.cc
parentBoth std::tr1::unordered_set and std::unordered_set are not allowed in (diff)
downloadbreakpad-561f81873562d407ac1c39144b30e26163e0045d.tar.xz
Chrome on Android now supports loading the shared library directly from the APK file.
This patch makes two changes to breakpad to enable crash reporting to work correctly when the library is inside another file (an archive): - Do not filter mappings which map an executable at a non-zero offset. - If such an executable is mapped look in the ELF information for the shared object name and use that name in the minidump. Note this change doesn't care about the archive format and isn't Android specific (though loading the shared library this way is currently only done on Android). BUG=390618 R=thestig@chromium.org Review URL: https://breakpad.appspot.com/7684002 Patch from Anton Carver <anton@chromium.org>. git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1355 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/client/linux/minidump_writer/minidump_writer.cc')
-rw-r--r--src/client/linux/minidump_writer/minidump_writer.cc35
1 files changed, 31 insertions, 4 deletions
diff --git a/src/client/linux/minidump_writer/minidump_writer.cc b/src/client/linux/minidump_writer/minidump_writer.cc
index fa2ad9e1..86cec55b 100644
--- a/src/client/linux/minidump_writer/minidump_writer.cc
+++ b/src/client/linux/minidump_writer/minidump_writer.cc
@@ -938,7 +938,9 @@ class MinidumpWriter {
static bool ShouldIncludeMapping(const MappingInfo& mapping) {
if (mapping.name[0] == 0 || // only want modules with filenames.
- mapping.offset || // only want to include one mapping per shared lib.
+ // Only want to include one mapping per shared lib.
+ // Avoid filtering executable mappings.
+ (mapping.offset != 0 && !mapping.exec) ||
mapping.size < 4096) { // too small to get a signature for.
return false;
}
@@ -1029,7 +1031,8 @@ class MinidumpWriter {
mod.base_of_image = mapping.start_addr;
mod.size_of_image = mapping.size;
- const size_t filepath_len = my_strlen(mapping.name);
+ const char* filepath_ptr = mapping.name;
+ size_t filepath_len = my_strlen(mapping.name);
// Figure out file name from path
const char* filename_ptr = mapping.name + filepath_len - 1;
@@ -1040,7 +1043,31 @@ class MinidumpWriter {
}
filename_ptr++;
- const size_t filename_len = mapping.name + filepath_len - filename_ptr;
+ size_t filename_len = mapping.name + filepath_len - filename_ptr;
+
+ // If an executable is mapped from a non-zero offset, this is likely
+ // because the executable was loaded directly from inside an archive
+ // file. We try to find the name of the shared object (SONAME) by
+ // looking in the file for ELF sections.
+
+ char soname[NAME_MAX];
+ char pathname[NAME_MAX];
+ if (mapping.exec && mapping.offset != 0 &&
+ LinuxDumper::ElfFileSoName(mapping, soname, sizeof(soname))) {
+ filename_ptr = soname;
+ filename_len = my_strlen(soname);
+
+ if (filepath_len + filename_len + 1 < NAME_MAX) {
+ // It doesn't have a real pathname, but tools such as stackwalk
+ // extract the basename, so simulating a pathname is helpful.
+ my_memcpy(pathname, filepath_ptr, filepath_len);
+ pathname[filepath_len] = '/';
+ my_memcpy(pathname + filepath_len + 1, filename_ptr, filename_len);
+ pathname[filepath_len + filename_len + 1] = '\0';
+ filepath_ptr = pathname;
+ filepath_len = filepath_len + filename_len + 1;
+ }
+ }
uint8_t cv_buf[MDCVInfoPDB70_minsize + NAME_MAX];
uint8_t* cv_ptr = cv_buf;
@@ -1070,7 +1097,7 @@ class MinidumpWriter {
mod.cv_record = cv.location();
MDLocationDescriptor ld;
- if (!minidump_writer_.WriteString(mapping.name, filepath_len, &ld))
+ if (!minidump_writer_.WriteString(filepath_ptr, filepath_len, &ld))
return false;
mod.module_name_rva = ld.rva;
return true;