Microdumps: support aarch64 and lib mapping from APK

- Filter modules by prot flags (only +x) not extensions. It wouldn't
  otherwise catch the case of Chrome mapping the library from the
  apk (which is mapped r-x but doesn't end in .so).
- Use compile-time detection of target arch, in order to cope with
  multilib OSes, where uname() doesn't reflect the run-time arch.
- Add OS information and CPU arch / count.
- Add support for aarch64.
- Add tests and stackwalk expectations for aarch64.
- Fix a potential overflow bug in the processor.
- Rebaseline the tests using smaller symbols.
- Fix microdump_writer_unittest.cc on 32-bit host.

BUG=chromium:410294

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1407 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
primiano@chromium.org 2014-12-02 15:31:25 +00:00
parent 63919583ba
commit 0b6cc95246
21 changed files with 148960 additions and 777 deletions

View file

@ -143,21 +143,42 @@ class MicrodumpWriter {
struct utsname uts;
if (uname(&uts))
return false;
const uint8_t n_cpus = static_cast<uint8_t>(sysconf(_SC_NPROCESSORS_CONF));
#if defined(__ANDROID__)
const char kOSId[] = "A";
#else
const char kOSId[] = "L";
#endif
// We cannot depend on uts.machine. On multiarch devices it always returns the
// primary arch, not the one that match the executable being run.
#if defined(__aarch64__)
const char kArch[] = "arm64";
#elif defined(__ARMEL__)
const char kArch[] = "arm";
#elif defined(__x86_64__)
const char kArch[] = "x86_64";
#elif defined(__i386__)
const char kArch[] = "x86";
#elif defined(__mips__)
const char kArch[] = "mips";
#else
#error "This code has not been ported to your platform yet"
#endif
LogAppend("O ");
LogAppend(kOSId);
LogAppend(" \"");
LogAppend(" ");
LogAppend(kArch);
LogAppend(" ");
LogAppend(n_cpus);
LogAppend(" ");
LogAppend(uts.machine);
LogAppend("\" \"");
LogAppend(" ");
LogAppend(uts.release);
LogAppend(" \"");
LogAppend(" ");
LogAppend(uts.version);
LogAppend("\"");
LogCommitLine();
return true;
}
@ -316,15 +337,13 @@ class MicrodumpWriter {
// First write all the mappings from the dumper
for (unsigned i = 0; i < dumper_->mappings().size(); ++i) {
const MappingInfo& mapping = *dumper_->mappings()[i];
// Skip mappings which don't look like libraries.
if (!strstr(mapping.name, ".so") || // dump only libs (skip fonts, apks).
mapping.size < 4096) { // too small to get a signature for.
if (mapping.name[0] == 0 || // only want modules with filenames.
!mapping.exec || // only want executable mappings.
mapping.size < 4096 || // too small to get a signature for.
HaveMappingInfo(mapping)) {
continue;
}
if (HaveMappingInfo(mapping))
continue;
DumpModule(mapping, true, i, NULL);
}
// Next write all the mappings provided by the caller

View file

@ -119,9 +119,16 @@ TEST(MicrodumpWriterTest, Setup) {
buf.get(), "-----BEGIN BREAKPAD MICRODUMP-----"));
ASSERT_NE(static_cast<char*>(0), strstr(
buf.get(), "-----END BREAKPAD MICRODUMP-----"));
#ifdef __LP64__
ASSERT_NE(static_cast<char*>(0), strstr(
buf.get(), "M 0000000000001000 000000000000002A 0000000000001000 "
"33221100554477668899AABBCCDDEEFF0 libfoo.so"));
#else
ASSERT_NE(static_cast<char*>(0), strstr(
buf.get(), "M 00001000 0000002A 00001000 "
"33221100554477668899AABBCCDDEEFF0 libfoo.so"));
#endif
close(err_fd);
close(fds[1]);