Compare commits

..

167 Commits

Author SHA1 Message Date
Maria Mandlis
8f7e09cf6d Handle multiple microdumps in system log.
Properly handle microdump processing, when the system_log file contains an incomplete microdump section at the top. The processor will process the first complete microdump section.

R=primiano@chromium.org

Review URL: https://codereview.chromium.org/1742843002 .
2016-02-26 16:40:40 -08:00
Maria Mandlis
344b79d61a Support processing microdumps for x86 architecture.
BUG=587536
R=primiano@chromium.org

Review URL: https://codereview.chromium.org/1704243002 .
2016-02-18 06:13:56 -08:00
Birunthan Mohanathas
1e24e66fbb Try loading msdiaNNN.dll if CoCreateInstance(CLSID_DiaSource) fails
Because tools/windows/symupload/symupload.cc uses `nullptr` (which
requires VS2010), the CLSID comparison is only performed for msdia100.dll
and later. When compiling with an older (or future) CLSID_DiaSource, we
retain the existing behaviour (i.e. fail if CoCreateInstance fails).

R=ivanpe@chromium.org
BUG=https://bugzilla.mozilla.org/show_bug.cgi?id=1236343
2016-02-17 11:36:19 -05:00
Ted Mielczarek
c05ee94604 Fix buffer overrun in MinidumpModule::debug_identifier with MDCVInfoELF 2016-02-17 06:20:58 -05:00
Mike Frysinger
108d705fdf linux_dumper_unittest_helper: move to a check-only binary
There's no need for this binary outside of local tests, so stop
building/installing it by default.

BUG=chromium:579384
TEST=`make check` passe
R=ivanpe@chromium.org

Review URL: https://codereview.chromium.org/1632933002 .
2016-02-17 00:48:38 -05:00
Ivan Penkov
12bd7fc52b Fixing a flaky Linux exploitability unittest.
BUG=https://code.google.com/p/chromium/issues/detail?id=584174
R=mmandlis@chromium.org

Review URL: https://codereview.chromium.org/1697963002 .
2016-02-16 11:46:04 -08:00
Ted Mielczarek
e5adfac03b Ensure Linux minidump writer flushes minidump header early.
If the Linux minidump writer crashes while writing a dump, the dump
might contain some useful information, but the header will be empty
because TypedMDRVA's destructor flushes the data, and the header var
doesn't go out of scope until the end of the `Dump` method. This
fixes that problem by putting the header in a shorter block scope.

We've seen this problem in some Android dumps in the wild, like:
https://crash-stats.mozilla.com/report/index/cef5b777-02d1-43c2-bf40-133ab2160209

R=thestig@chromium.org
BUG=https://bugzilla.mozilla.org/show_bug.cgi?id=1247978

Review URL: https://codereview.chromium.org/1696573003 .
2016-02-12 15:50:16 -05:00
Veljko Mihailovic
1ac4dcf6f5 Fix for linux make check build failure
Linux make check is failing for mips, mips64, arm, arm64
with error:
"fatal error: mach/arm/vm_types.h: No such file or directory" in case of arm,
"../src/third_party/mac_headers/mach/machine/vm_types.h:37:2: error: #error architecture not supported" in case of mips/mips64

This was partially fixed in https://codereview.chromium.org/1645673002/.

Here excluding src/common/mac/macho_reader_unittest for hosts other than x86/x86-64.

BUG=make check failure for linux mips
TEST=make check pass

Review URL: https://codereview.chromium.org/1692933002 .
2016-02-12 15:17:11 -05:00
Maria Mandlis
7b330814a4 Parse additional line introduced in the microdump format and containing the GPU infromation in the following format:
G GL_VERSION|GL_VENDOR|GL_RENDERER.

The GPU version, vendor and renderer are extracted during microdump parsing and populated in the appropriate fields in the SystemInfo struct.

This is to match the changes introduced in crrev.com/1343713002 and crrev.com/1334473003

BUG=chromium:536769
R=primiano@chromium.org

Review URL: https://codereview.chromium.org/1678463002 .
2016-02-11 10:04:04 -08:00
Lei Zhang
a1d84b2da9 Revert "Added a switch to dump minidump modules in minidump_stackwalk."
This reverts commit cb936a0243c97ae9cd2d4bb19d95dde0421fed6d.

A=dyen@chromium.org
Original Review: https://codereview.chromium.org/1672773002/

R=dyen@chromium.org

Review URL: https://codereview.chromium.org/1688493003 .
2016-02-10 13:11:20 -08:00
Ted Mielczarek
7a364b1262 Change MDCVInfoELF into something usable.
This patch changes MDCVInfoELF (which is currently unused, apparently
a vestigal bit of code landed as part of Solaris support) into a supported
CodeView format that simply contains a build id as raw bytes.

Modern ELF toolchains support build ids nicely:
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Developer_Guide/compiling-build-id.html

It would be useful to have the original build ids of loaded modules in
Linux minidumps, since tools like Fedora's darkserver allow querying by build
id and the current Breakpad code truncates the build id to the size of a GUID,
which loses information:
https://darkserver.fedoraproject.org/

A follow-up patch will change the Linux minidump generation code to produce
MDCVInfoELF in minidumps instead of MDCVInfoPDB70. This patch should be landed
first to ensure that crash processors are able to handle this format before
dumps are generated containing it.

The full build id is exposed as the return value of Minidump::code_identifier(),
which currently just returns "id" for modules in Linux dumps. For
backwards-compatibility, Minidump::debug_identifier() continues to treat
the build id as a GUID, so debug identifiers for existing modules will not
change.

BUG=
R=mark@chromium.org

Review URL: https://codereview.chromium.org/1675413002 .
2016-02-10 09:00:02 -05:00
Sylvain Defresne
4becb11709 Fix usage of deprecated method sendSynchronousRequest:returningResponse:error:.
The method -[NSURLConnection sendSynchronousRequest:returningResponse:error:]
has been deprecated in 10.11 OS X SDK and 9.0 iOS SDK without replacement. So
emulate a synchronous request by using an asynchronous request and waiting on
a semaphore for the request completion.

BUG=https://bugs.chromium.org/p/google-breakpad/issues/detail?id=675
BUG=569158
R=mark@chromium.org

Review URL: https://codereview.chromium.org/1675243002 .
2016-02-08 17:39:44 +01:00
Sylvain Defresne
450491f4f7 Fix usage of deprecated method stringByAddingPercentEscapesUsingEncoding:.
The method -[NSString stringByAddingPercentEscapesUsingEncoding:] has been
deprecated with 10.11 OS X SDK and 9.0 iOS SDK. The recommended method is
-[NSString stringByAddingPercentEncodingWithAllowedCharacters:] available
since 10.9 OS X SDK and 7.0 iOS SDK.

Use the new method when available using URLQueryAllowedCharacterSet to get
the same encoded string.

BUG=https://bugs.chromium.org/p/google-breakpad/issues/detail?id=675
BUG=569158
R=mark@chromium.org

Review URL: https://codereview.chromium.org/1680663002 .
2016-02-08 17:39:26 +01:00
Sylvain Defresne
cd891cd1ed Fix usage of deprecated function CFPropertyListCreateFromXMLData.
The function CFPropertyListCreateFromXMLData is deprecated in favor of
the function CFPropertyListCreateWithData that is available since the
10.6 OS X SDK and 4.0 iOS SDK.

BUG=https://bugs.chromium.org/p/google-breakpad/issues/detail?id=675
BUG=569158
R=mark@chromium.org

Review URL: https://codereview.chromium.org/1678063002 .
2016-02-08 17:38:33 +01:00
Mike Frysinger
79556b7ca8 [mips64] Support for mips n64
Adding remaining mips n64 support including stackwalker.

BUG=None
TEST=manually tested on Linux/Android
R=vapier@chromium.org

Review URL: https://codereview.chromium.org/1418453011 .
2016-02-06 18:58:39 -05:00
Ivan Penkov
11840d0ffd Remove use of deprecated CFURLCreateDataAndPropertiesFromResource function.
Original change (https://codereview.chromium.org/1527363003/) was failing
in CFReadStreamGetBuffer() call, so changed to CFReadStreamRead() to be
more conservative.

Patch provided by Scott Hancher.

BUG=
R=mark@chromium.org

Review URL: https://codereview.chromium.org/1637433003 .
2016-01-31 18:17:42 -08:00
Lei Zhang
cb936a0243 Added a switch to dump minidump modules in minidump_stackwalk.
In order to figure out what symbols we need associated to a minidump,
it is useful to be able to dump all the modules the minidump contains.

A=dyen@chromium.org
Original Review: https://codereview.chromium.org/1651593002/
BUG=563716
R=dyen@chromium.org

Review URL: https://codereview.chromium.org/1650713002 .
2016-01-29 13:59:17 -08:00
Pavel Labath
4003d20c70 Improvements to GYP build
This updates the GYP build for the processor component (on windows).
- adds/removes references to files which were added or removed from the
  repository
- includes build/common.gypi in the gyp files: needed to correctly
  detect the OS (I think, the generated MSVC solutions were broken
  without it)
- conditionally compiles code platform-specific code for the given
  platform

After this minidump processor nearly compiles with VS2013: the generated
project is correct, but some files still have compilation errors.

Disclaimer: I have not tested the GYP changes on non-windows platform,
as there does not seem to be anyone using it there.

BUG=
R=mark@chromium.org

Review URL: https://codereview.chromium.org/1643633004 .
2016-01-29 11:43:21 +00:00
Mike Frysinger
855ea963fb only build dump_syms_mac for x86 hosts
The dump_syms_mac tool only works for the system it is being built for
(it doesn't support running on ELFs for a diff target), and it builds
only for x86 currently.

If you look at the mac header:
	src/third_party/mac_headers/mach/machine/vm_types.h
it will #error for non x86/arm systems, and the arm header is not in
our source tree.

Tweak the build so it's only compiled when targetting x86 systems.

BUG=chromium:579384
TEST=`make check` pass
R=ted.mielczarek@gmail.com

Review URL: https://codereview.chromium.org/1645673002 .
2016-01-27 16:45:21 -05:00
Mike Frysinger
258591ed4c convert to uint8_t* for binary data to fix -Wnarrowing build errors
Newer gcc versions default to -Werror=narrowing when using newer C++
standards (which we do).  This causes issues when we try to stuff a
value like 0xea into a char -- the value is out of range for signed
char bytes.  That's when gcc throws an error:
.../bytereader_unittest.cc: In member function 'virtual void Reader_DW_EH_PE_absptr4_Test::TestBody()':
.../bytereader_unittest.cc:400:55: error: narrowing conversion of '234' from 'int' to 'char' inside { } [-Wnarrowing]

BUG=chromium:579384
TEST=`make check` passes
R=mark@chromium.org

Review URL: https://codereview.chromium.org/1605153004 .
2016-01-26 15:38:19 -05:00
Mike Frysinger
e8ddeff729 autotools: regen w/latest versions
Should have no real impact on the build.  Just pulling in the latest
versions from the latest autoconf/automake versions.

BUG=chromium:579384
TEST=`make && make install` still works
2016-01-25 19:29:06 -05:00
Mike Frysinger
de54eb133f test: allow use of system gmock/gtest libs
Some systems provide prebuilt copies of gmock/gtest (such as Chromium
OS).  Add a configure flag so they can take advantage of that.  This
allows for a smaller checkout as they don't need to include the full
testing/ tree.

BUG=chromium:579384
TEST=`make check` passes w/--enable-system-test-libs
TEST=`make check` passes w/--disable-system-test-libs
R=thestig@chromium.org

Review URL: https://codereview.chromium.org/1638653002 .
2016-01-25 19:27:56 -05:00
Mike Frysinger
0f0b0f367b build: clean up .dwo files
When building with -gsplit-dwarf, the generated dwo files are left behind
even when you `make clean`.  Fix that up.

BUG=chromium:579384
TEST=`./configure CXXFLAGS='-O -gsplit-dwarf' && make && make clean` removes dwo files now
R=mark@chromium.org

Review URL: https://codereview.chromium.org/1633893002 .
2016-01-25 18:40:56 -05:00
Mike Frysinger
83f0e6a31c test: stop building tons of copies of gtest/gmock objects
The current makefile ends up building ~17 copies of the gtest/gmock
objects -- every test that refers to the cc files directly will have
its own copy.  This is because the build doesn't know if CFLAGS and
such have changed between each target (and in some cases, they are).

Create a new libtesting.a target to hold a single copy of these files
and update all of the unittests to link that in.  This speeds up the
build a bit especially when you aren't using ccache.

This does mean we can no longer build gtest/gmock with unique flags,
but we haven't wanted that so far, so clearly no one wants that.

BUG=chromium:579384
TEST=`make check` passes
R=thestig@chromium.org

Review URL: https://codereview.chromium.org/1633903002 .
2016-01-25 17:41:53 -05:00
Mike Frysinger
b7033b3aa1 linux_client_unittest_shlib: fix cleaning
The EXTRA_PROGRAMS knob does not automatically trigger clean up of
targets listed in it.  Use CLEANFILES so we make sure `make clean`
will delete the linux_client_unittest_shlib lib.

BUG=chromium:579384
TEST=`make check` passes
R=mark@chromium.org

Review URL: https://codereview.chromium.org/1618593002 .
2016-01-25 16:53:16 -05:00
Mike Frysinger
72a02f6cbf tests: unify duplicate build settings
Rather than copy & paste the same set of -I flags many times over,
create a single varible to hold it.

BUG=chromium:579384
TEST=`make check` passes
R=thestig@chromium.org

Review URL: https://codereview.chromium.org/1613763002 .
2016-01-25 15:12:03 -05:00
Mike Frysinger
7f160dbfa2 DEPS: roll test libs up to the latest release
BUG=chromium:579384
TEST=`make check` passes
R=thestig@chromium.org

Review URL: https://codereview.chromium.org/1607413003 .
2016-01-25 15:10:38 -05:00
Olivier Robin
7da8acc8d4 Revert "Fix deprecatation warning when building for recent SDKs on iOS/OS X."
This reverts CL https://codereview.chromium.org/1563223004/
This reverts commit 7cc0d8562bf8b20b88cc941ba72593cb7230ecf6.

CL 1563223004 introduces two bugs on iOS.
- Encoding the minidump name with extra percent causing crash server to fail
  processing the file.
- Using a released pointer causing random crashes on upload. The
  data, resp, err pointers returned in the NSURLSession completion
  handler is released at the end of the block. When used later (to get
  the crash ID), it causes a crash.

BUG=569158
R=blundell@chromium.org, mark@chromium.org

Review URL: https://codereview.chromium.org/1619603002 .

Patch from Olivier Robin <olivierrobin@chromium.org>.
2016-01-21 11:34:12 -05:00
Mike Frysinger
585ba07db0 exploitability_unittest: fix warnings
The std::getline function always returns its first arg (which is an
iostream object) and cannot return anything else.  Thus, testing its
value is pointless, and even leads to build errors w/at least gcc-5
due to gtest ASSERT_TRUE funcs only taking bool types:

.../exploitability_unittest.cc: In member function 'virtual void {anonymous}::ExploitabilityLinuxUtilsTest_DisassembleBytesTest_Test::TestBody()':
.../exploitability_unittest.cc:200:136: error: no matching function for call to 'testing::AssertionResult::AssertionResult(std::basic_istream<char>&)'
In file included from .../breakpad_googletest_includes.h:33:0,
                 from .../exploitability_unittest.cc:35:
.../gtest.h:262:12: note: candidate: testing::AssertionResult::AssertionResult(bool)

Since we know this never fails, simply drop the ASSERT_TRUE usage.
The next line already checks the content of the buffer we read.

Further on in the file, we hit some signed warnings:
In file included from .../breakpad_googletest_includes.h:33:0,
                 from .../exploitability_unittest.cc:35:
.../gtest.h: In instantiation of 'testing::AssertionResult testing::internal::CmpHelperEQ(const char*, const char*, const T1&, const T2&) [with T1 = long unsigned int; T2 = int]':
.../gtest.h:1484:23:   required from 'static testing::AssertionResult testing::internal::EqHelper<lhs_is_null_literal>::Compare(const char*, const char*, const T1&, const T2&) [with T1 = long unsigned int; T2 = int; bool lhs_is_null_literal = false]'
.../exploitability_unittest.cc:241:289:   required from here
.../gtest.h:1448:16: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
   if (expected == actual) {

This is because we compare the register value (a uint64_t) directly to
an integer constant, and those are signed by default.  Stick a U suffix
on them to fix things up.

BUG=chromium:579384
TEST=`make check` passes
R=ivanpe@chromium.org

Review URL: https://codereview.chromium.org/1611763002 .
2016-01-21 00:50:28 -05:00
Pavel Labath
d5d13e605e Fix usage of snprintf for MSVC
Older versions of MSVC don't have a snprintf functions. Some files
were already working around that, but not all of them. Instead of
copying the logic into every file, I centralize it into a new
stdio.h wrapper file and make other files include that.

BUG=
R=mark@chromium.org

Review URL: https://codereview.chromium.org/1602563003 .

Patch from Pavel Labath <labath@google.com>.
2016-01-19 21:28:44 -05:00
Mike Frysinger
fc134c412a breakpad: fix unittest failure when building with clang.
In C/C++, the result of signed integer overflow is undefined.

The expression "base + size - 1" is parsed as "(base + size) - 1", and
"base + size" can overflow even if "base + (size - 1)" <= INT_MAX.

See http://g/c-compiler-chrome/461JohPKakE/JI3rEBg6FwAJ for more.

BUG=None
TEST='CC=clang CXX=clang++ ./configure && make check'
R=vapier@chromium.org

Review URL: https://codereview.chromium.org/1591793002 .
2016-01-15 13:29:32 -05:00
Mike Frysinger
d38ed334e7 README: add more links to breakpad sites
R=andybons@chromium.org

Review URL: https://codereview.chromium.org/1583163003 .
2016-01-14 13:32:20 -05:00
Mike Frysinger
e8dc9aab0c Move core2md objects to libbreakpad_client.a
This CL exports LinuxCoreDumper and ElfCoreDump in the client library. The ARC collector, which is an alternative to core2md optimized for large core dumps, needs these symbols for core dump parsing and conversion to minidump.

BUG=http://b/25773929
TEST=nm src/client/linux/libbreakpad_client.a | grep LinuxCoreDumper

Review URL: https://codereview.chromium.org/1576053002 .
2016-01-13 15:30:21 -05:00
Pavel Labath
2c03db146a libdisasm: Remove inclusion of windows.h
windows.h defines exception_code as a macro, which conflicts with our
use of the identifier in exception records. It appears that this
particular include of windows.h is not needed, so instead of undefining
the macro, I simply delete the include. Build tested with MSVC 2013.

BUG=
R=mark@chromium.org

Review URL: https://codereview.chromium.org/1579623004 .

Patch from Pavel Labath <labath@google.com>.
2016-01-12 10:43:06 -05:00
Pavel Labath
860d7f5da1 Define intptr and uintptr in a more generic way
MSVC does not have the __PTRDIFF_TYPE__ macro defined, so I use the
standard [u]intptr_t types instead. Compilation tested on windows, linux
and mac.

BUG=
R=mark@chromium.org

Review URL: https://codereview.chromium.org/1571293003 .

Patch from Pavel Labath <labath@google.com>.
2016-01-11 12:38:28 -05:00
Pavel Labath
104784d8e4 libdisasm: Don't depend on sizeof(void)
Due to operator precedence, the address was first cast to void*
and then incremented, which resulted in an error on windows, as
sizeof(void) is undefined and MSVC takes this seriously. Changing
the precedence to perform the addition first.

R=mark@chromium.org

Review URL: https://codereview.chromium.org/1570843002 .

Patch from Pavel Labath <labath@google.com>.
2016-01-08 12:52:04 -05:00
Pavel Labath
1979e59107 disassembler_x86: Remove unused include
This file is not present on windows, and it's causing build errors
there. As far as I can tell, nothing in this file actually uses
that include, so I just remove it.

BUG=
R=mark@chromium.org

Review URL: https://codereview.chromium.org/1475353002 .

Patch from Pavel Labath <labath@google.com>.
2016-01-08 10:07:04 -05:00
Sylvain Defresne
ae0fdf6f43 Fix compilation of breakpad on Linux.
Fix some copy/paste errors from commit 41440eaa.

BUG=None
R=thestig@chromium.org

Review URL: https://codereview.chromium.org/1564293002 .
2016-01-08 09:34:27 +01:00
Lei Zhang
cbda3193b1 Check for C++11 support in the configure script.
R=mark@chromium.org

Review URL: https://codereview.chromium.org/1570013002 .
2016-01-08 00:27:48 -08:00
Sylvain Defresne
7cc0d8562b Fix deprecatation warning when building for recent SDKs on iOS/OS X.
Fixes the following compilation warning when using recent version of
the iOS or OS X SDK by using the recommended new API:

../../breakpad/src/common/mac/HTTPMultipartUpload.m:56:10: error: 'stringByAddingPercentEscapesUsingEncoding:' is deprecated: first deprecated in iOS 9.0 - Use -stringByAddingPercentEncodingWithAllowedCharacters: instead, which always uses the recommended UTF-8 encoding, and which encodes for a specific URL component or subcomponent since each URL component or subcomponent has different rules for what characters are valid. [-Werror,-Wdeprecated-declarations]
    [key stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
         ^
CFURLCreateStringByAddingPercentEscapes

../../breakpad/src/common/mac/HTTPMultipartUpload.m:207:29: error: 'sendSynchronousRequest:returningResponse:error:' is deprecated: first deprecated in iOS 9.0 - Use [NSURLSession dataTaskWithRequest:completionHandler:] (see NSURLSession.h [-Werror,-Wdeprecated-declarations]
    data = [NSURLConnection sendSynchronousRequest:req
                            ^

../../breakpad/src/client/mac/handler/minidump_generator.cc:158:6: error: 'CFPropertyListCreateFromXMLData' is deprecated: first deprecated in iOS 8.0 - Use CFPropertyListCreateWithData instead. [-Werror,-Wdeprecated-declarations]
    (CFPropertyListCreateFromXMLData(NULL, data, kCFPropertyListImmutable,
     ^

BUG=https://bugs.chromium.org/p/google-breakpad/issues/detail?id=675
BUG=569158
R=mark@chromium.org

Review URL: https://codereview.chromium.org/1563223004 .
2016-01-07 19:48:21 +01:00
Lei Zhang
41440eaa17 Use range-based for loops in linux/minidump_writer/minidump_writer.cc.
Also fix lint errors.

R=mark@chromium.org

Review URL: https://codereview.chromium.org/1562273002 .
2016-01-07 00:53:06 -08:00
Mike Frysinger
0205a1526d switch to git for external projects
Now that all the projects we care about use git and have repos available,
switch to them and away from the old googlecode svn repos.

TEST=`gclient sync` migrated svn->git fine
TEST=`make check` still passes
TEST=manual `diff -ur` on the new/old repos shows same content
BUG=
R=thestig@chromium.org

Review URL: https://codereview.chromium.org/1560913002 .
2016-01-06 19:44:41 -05:00
Lei Zhang
400a1d9aa5 Avoid comparing size_t to be < 0 on AArch64.
cpu_features_entries is empty on AArch64 and causes tautological-compare
warning when compiling with Clang.

A=dskiba@google.com
Original Review: https://codereview.chromium.org/1562223002/

BUG=chromium:539781

Review URL: https://codereview.chromium.org/1566893002 .
2016-01-06 16:16:01 -08:00
Lei Zhang
863883f93f Make minidump-2-core.cc build with -Wformat.
A=thakis@chromium.org
BUG=chromium:574817
Original Review: https://codereview.chromium.org/1562983002/

R=thakis@chromium.org

Review URL: https://codereview.chromium.org/1563043002 .
2016-01-06 14:17:16 -08:00
Lei Zhang
be6ea5e82d Fix -Wunused-function warnings in ASAN builds.
A=thakis@chromium.org
BUG=chromium:573250
Original Review: https://codereview.chromium.org/1551963002/

Review URL: https://codereview.chromium.org/1551983002 .
2015-12-30 15:44:02 -08:00
Lei Zhang
a7ffb8c364 Let breakpad build with -Wall on OS X and Linux.
A=thakis@chromium.org
Original Review: https://codereview.chromium.org/1550933002/

R=thakis@chromium.org

Review URL: https://codereview.chromium.org/1554613002 .
2015-12-29 13:42:49 -08:00
Ivan Penkov
816f242158 Remove use of deprecated CFURLCreateDataAndPropertiesFromResource function.
Patch by Scott Hancher

BUG=
R=mark@chromium.org

Review URL: https://codereview.chromium.org/1527363003 .
2015-12-18 10:26:21 -08:00
Ted Mielczarek
86d5e9e7f9 Fix ExploitabilityLinuxUtilsTest::DisassembleBytesTest to not fail when temp file ends with 0
R=ivanpe@chromium.org
BUG=https://bugs.chromium.org/p/google-breakpad/issues/detail?id=668

Review URL: https://codereview.chromium.org/1482363003 .
2015-11-30 14:05:08 -05:00
Ted Mielczarek
fed9db3634 Rename src/tools/mac/dump_syms binary to dump_syms_mac in autotools build to fix make install
R=mark@chromium.org

Review URL: https://codereview.chromium.org/1474673004 .
2015-11-25 14:27:53 -05:00
Mike Frysinger
9e60a27911 dump_syms: add a -v flag
dump_syms generates a lot of warnings.
This CL puts logging behind a command line flag

URL=https://android-review.googlesource.com/181558
BUG=b:25460551
BUG=google-breakpad:441
R=mark@chromium.org

Review URL: https://codereview.chromium.org/1437763002 .
2015-11-11 13:52:03 -05:00
Mike Frysinger
ff49f92c36 build: detect the right ar tool
Use automake's AM_PROG_AR helper instead of the default of hardcoding
`ar` all the time.  When cross-compiling, this can often be the wrong
one to use.

BUG=google-breakpad:519
R=ted.mielczarek@gmail.com

Review URL: https://codereview.chromium.org/1435813002 .
2015-11-11 13:43:14 -05:00
Mike Frysinger
d4d65cfc36 gitignore: add mac/dump_syms
BUG=google-breakpad:670
2015-11-11 01:47:33 -05:00
Mike Frysinger
b1a39f985d autotools: refresh config.{sub,guess} 2015-11-11 01:38:23 -05:00
Mike Frysinger
27a2e317d7 Don't include libdisasm.a in libbreakpad.a
libbreakpad.a pointlessly contains libdisasm.a

This looks like a left-over from when libtool was used

Since this has no useful effect (as the linker doesn't recursively search
archive members which aren't objects), anything which requires the objects in
libdisasm.a must already be linking with it, so simply remove it.

BUG=https://code.google.com/p/google-breakpad/issues/detail?id=484

Review URL: https://codereview.chromium.org/1399003002 .
2015-11-11 01:17:45 -05:00
Mike Frysinger
8652b9eaed Fix file descriptor leaks in linux CrashGenerationServer
R=ted.mielczarek@gmail.com

Review URL: https://codereview.chromium.org/1137423004 .
2015-11-11 01:12:20 -05:00
Mike Frysinger
b9f9f4e840 Install headers under client/linux/dump_writer_common
Automake did not install headers under c/l/dwc, which caused
compile errors when building against an installed breakpad, since
other headers (e.g. client/linux/handler/exception_handler.h)
depended on it. This commit adds these headers to the list of
automake installed files.

R=vapier@chromium.org

Review URL: https://codereview.chromium.org/1127393006 .
2015-11-11 01:11:00 -05:00
Boris Vidolov
f20be6a6c0 Make dump_syms buildable under newer versions of Xcode.
R=mark@chromium.org
BUG=

Review URL: https://codereview.chromium.org/1438483002 .
2015-11-10 13:23:38 -08:00
Lei Zhang
fe64fd4aa2 Android: Workaround for ftruncate() issues.
This works around a bug in M that prevents Breakpad from using
ftruncate() in the renderer process.

To do this, skip the calls to ftruncate() when allocating bigger
minidump files and strictly depends on write() to append to the end.

It might be less efficient but this is probably less of an issue on
SD cards. It is much better than not getting crash reports.

BUG=542840

Original CL: https://codereview.appspot.com/273880044/
Original CL Author: acleung@chromium.org

Review URL: https://codereview.chromium.org/1407233016 .
2015-11-05 15:45:01 -08:00
Ivan Penkov
4da1cfbad2 Issue in StackwalkerAMD64::GetCallerByFramePointerRecovery.
There is an issue in StackwalkerAMD64::GetCallerByFramePointerRecovery.
Occasionally it produces invalid frames (instruction pointer == 0) which
prevents the AMD64 stack walker from proceeding to do stack scanning and
instead leads to premature termination of the stack walking process.

For more details: http://crbug/537444

BUG=
R=mark@chromium.org

Review URL: https://codereview.chromium.org/1408973002 .
2015-10-15 20:47:15 -07:00
Benjamin Lerman
95719f4b8c Only release current_breakpad_ if it is defined.
R=mark@chromium.org

Review URL: https://codereview.chromium.org/1402453006 .
2015-10-14 17:35:47 +02:00
Mike Frysinger
30fa644c27 Revert "[Docs] Add wiki content to Markdown docs"
This reverts commit 7ed2476eea2c2a50fd40ec3e711dcb311d472753.

This was supposed to be committed to the linux-syscall-support
project.  The two CLs landing at the sametime confused me.

Note: LSS has been updated via commit 08056836f2b4a5747daff75435d10d6.

Review URL: https://codereview.chromium.org/1395743002 .
2015-10-07 17:04:43 -04:00
Ted Mielczarek
c53ed14310 Fix Windows crash_generation_server for debug builds without -D_DEBUG
Debug Gecko builds don't build with -D_DEBUG, so the ifdef in
crash_generation_server doesn't work right. The MSDN documentation for
assert says that it's enabled based on the absence of the NDEBUG define,
so using that seems sensible.

R=thestig@chromium.org
BUG=

Review URL: https://codereview.chromium.org/1398453002 .
2015-10-07 14:19:23 -04:00
David Major
cf1087c403 Support for multiple upload files in CrashReportSender/HTTPUpload
A=David Major <dmajor@mozilla.com>
BUG=https://bugzilla.mozilla.org/show_bug.cgi?id=1048091
R=ted@mielczarek.org

Review URL: https://bugzilla.mozilla.org/show_bug.cgi?id=1048091 .
2015-10-06 11:05:12 -04:00
Ted Mielczarek
be849f0637 Fix MSVC build (including on 2015), drop some workarounds for MSVC older than 2013.
The Windows client gyp files were missing proc_maps_linux.cc for the
unittest build. Adding that revealed some build errors due to it
unconditionally including <inttypes.h>. Removing the workarounds in
breakpad_types.h (and a few other places) made that build, which means
that Visual C++ 2013 is now our minimum supported version of MSVC.

Additionally I tried building with VC++ 2015 and fixed a few warnings
(which were failing the build because we have /WX enabled) to ensure
that that builds as well.

BUG=https://code.google.com/p/google-breakpad/issues/detail?id=669
R=mark@chromium.org

Review URL: https://codereview.chromium.org/1353893002 .
2015-10-06 08:03:57 -04:00
Ivan Penkov
84d37160a7 Increasing the Breakpad stack walker max scan limit from 30 to 40.
Chrome started hitting some crashes in v8 jitted code which happens to be
non ABI compliant and debuggers (including WinDBG) are unable to produce
meaningful stack traces.

The Breakpad stack walker has some builtin heuristics to deal with such cases.
More specifically, when unable to find a good parent frame, it scans the raw
stack to find a suitable parent frame.  The max scan size was set at 30
pointers which was (apparently) not enough to recover in this case.

I'm increasing it to 40 pointers.  I confirmed that at 34 pointers it was able
to recover however I'm setting it to 40 in order to it some slack.

I needed to update two unittests which were expecting the previous scan limit.

BUG=
R=mark@chromium.org

Review URL: https://codereview.chromium.org/1379433005 .
2015-10-05 11:35:09 -07:00
Pavel Labath
cc7b69a8f2 [mac] Teach dump_syms to handle additional zerofill sections
This patch allows dump_syms to handle S_THREAD_LOCAL_ZEROFILL
and S_GB_ZEROFILL section in the same way as the more common
S_ZEROFILL section.  Previously, dump_syms would fail to dump
a binary containing a __DATA,__thread_bss section, because it
tried to look up its data (and failed).

R=mark@chromium.org

Review URL: https://codereview.chromium.org/1369233003 .

Patch from Pavel Labath <labath@google.com>.
2015-09-30 08:20:42 -04:00
Primiano Tucci
9d3e1f1c03 Fix automake files after README.md -> README rename
Minor followup to crrev.com/1357773004 and
crrev.com/1361993002 which moved the README and forgot
to update the automake files.
This is to make "./configure && make" work.

TBR=mark@chromium.org

Review URL: https://codereview.chromium.org/1368363002 .
2015-09-28 14:02:08 +01:00
Primiano Tucci
7ecc65758d Add GPU fingerprint information to breakpad microdumps.
Although strictly the GPU fingerprint is defined by the build fingerprint,
there is not currently a straightforward mapping from build fingerprint
to useful GPU / GL driver information.

In order to aid debugging of WebView crashes that occur in GL drivers,
and to better understand the range of drivers and versions for feature
blacklisting purposes, it is useful to have GPU fingerprints in breakpad
microdumps.

Landing this patch on behalf of Tobias Sargeant<tobiasjs@chromium.org>

BUG=chromium:536769
R=primiano@chromium.org, thestig@chromium.org

Review URL: https://codereview.chromium.org/1334473003 .
2015-09-28 13:52:54 +01:00
Mike Frysinger
7ed2476eea [Docs] Add wiki content to Markdown docs
BUG=none
R=vapier@chromium.org, mseaborn@chromium.org

Review URL: https://codereview.chromium.org/1356253003 .
2015-09-24 11:32:37 -04:00
Mark Mentovai
94b1ccb51f Update configure to look for README.md instead of README
This is required after daed3a43836e. configure won't run as-is, reported
in https://codereview.chromium.org/1357773004/.

R=andybons@chromium.org

Review URL: https://codereview.chromium.org/1361993002 .
2015-09-23 10:46:55 -04:00
Andy Bonventre
daed3a4383 [Docs] add markdown docs (converted from Wiki)
BUG=none
R=mark
CC=google-breakpad-dev@googlegroups.com

Review URL: https://codereview.chromium.org/1357773004 .

Patch from Andy Bonventre <andybons@chromium.org>.
2015-09-22 17:29:52 -04:00
Primiano Tucci
55ba26e520 Linux ExceptionHandler: don't allocate the CrashContext on the stack
On Android the size of the alternate stack can be very small (8k).
Even if breakpad uses sigaltstack to increase the size of the alternate
stack during initialization, that call affects only the main thread.
On Android, the libc's pthread initializer reset the sigaltstack to 8k.
When entering a signal handler, the kernel typically pushes the context
on the alternate stack. On arm64, sizeof(CrashContext) is ~5k, which
leaves 3k of usable stack for breakpad.
On top of that, breakpad allocates another struct CrashContext on the
stack. In the case of Android arm64, then, breakpad ends up using
5k + 5k > 8k of stack, which causes a stack overflow.
This got unnoticed in Android L, as the alternate stack didn't have
red-zones between them, so breakpad was often happily overflowing onto
the next thread's stack. This is not the case anymore [1].
This CL moves the CrashContext into a global variable. It should be
safe as the ExceptionHandlers are serialized on a mutex.

[1] 595752f623

BUG=374
R=mark@chromium.org

Review URL: https://codereview.chromium.org/1354923002 .
2015-09-22 09:11:24 +01:00
Ted Mielczarek
1be03d4e87 Fixup a bad strcmp call landed in previous commit 2015-09-16 19:25:35 -04:00
Ted Mielczarek
6cee755e09 Fix Mac Breakpad host tools to build in Linux cross-compile
We're working on building our Firefox Mac builds as a Linux cross-compile
(https://bugzilla.mozilla.org/show_bug.cgi?id=921040) and we need symbol
dumping to work. This change ports the Mac dump_syms tool to build and work
on Linux. I've tested it and it produces identical output to running the
tool on Mac.

The bulk of the work here was converting src/common/mac/dump_syms.mm and
src/tools/mac/dump_syms/dump_syms_tool.mm from ObjC++ to C++ and removing
their use of Foundation classes in favor of standard C/C++.

This won't compile out-of-the-box on Linux, it requires some Mac system
headers that are not included in this patch. I have those tentatively in
a separate patch to land in Gecko
(http://hg.mozilla.org/users/tmielczarek_mozilla.com/mc/rev/5fb8da23c83c),
but I wasn't sure if you'd be interested in having them in the Breakpad tree.
We could almost certainly pare down the set of headers included there, I
didn't spend too much time trying to minimize them (we primarily just need
the Mach-O structs and a few associated bits).

I just realized that this patch is missing updating the XCode project files
(ugh). I'll fix that up in a bit.

R=mark@chromium.org
BUG=https://bugzilla.mozilla.org/show_bug.cgi?id=543111

Review URL: https://codereview.chromium.org/1340543002 .
2015-09-16 06:46:55 -04:00
Ted Mielczarek
f766c4d790 Update gitignore to ignore more GYP things
Now that we're using gclient everywhere, the hook to run gyp on the Windows
projects gets run on Linux, so we get Makefiles strewn around the tree.

R=vapier@chromium.org

Review URL: https://codereview.chromium.org/1339653002 .
2015-09-11 14:20:15 -04:00
Mike Frysinger
cf1d2dcef9 solaris: fix spurious ;
As reported in the issue tracker, building on Solaris 8 fails:
.../src/common/solaris/guid_creator.cc:69: error: extra `;'

BUG=google-breakpad:251
R=ted.mielczarek@gmail.com

Review URL: https://codereview.chromium.org/1333243002 .
2015-09-11 12:59:53 -04:00
Mike Frysinger
282996a91e README: update dev documents w/new git flow
BUG=chromium:502355
R=thestig@chromium.org

Review URL: https://codereview.chromium.org/1335483002 .
2015-09-11 01:38:20 -04:00
Mike Frysinger
d9b5c83cc1 deps: switch lss to git
BUG=524777
TEST=`gclient sync` switches lss to git
R=thestig@chromium.org

Review URL: https://codereview.chromium.org/1331783002 .
2015-09-11 01:37:29 -04:00
Will Harris
5f520807ca Fix regression on x86 for "Fix compile error with Windows clang"
R=thakis@chromium.org

Review URL: https://codereview.chromium.org/1318013002 .
2015-09-03 16:38:57 -07:00
Vadim Shtayura
2ad6028981 Change codereview.settings to point to new repo URL.
It changes "Committed: <URL>" in CLs to point to Git repo browser.

BUG=chromium:502355
R=mark@chromium.org

Review URL: https://codereview.chromium.org/1319083007 .
2015-09-01 17:13:51 -07:00
mmandlis@chromium.org
2ef9e783ab The "CPU architecture" field is being filled from the wrong part of
the microdump. The microdump OS/arch line looks like:
O A arm 04 armv7l 3.4.0-perf-g4d6e88e #1 SMP PREEMPT Mon Mar 30 19:09:30 2015
and currently the field that says "armv7l" or "aarch64" is being used
to fill in the CPU arch field in crash. The problem is that on a
64-bit device this field *always* says "aarch64" even when running in
a 32-bit process, and so currently the crash reports for aarch64 are
a mix of 32-bit and 64-bit crashes. We should be using the first field
instead, which just says "arm" or "arm64" and reflects the actual
version of webview (32-bit or 64-bit) which is running.

BUG=
R=primiano@chromium.org

Review URL: https://codereview.chromium.org/1306983003 .

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1498 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-08-26 16:18:52 +00:00
Liu.andrew.x@gmail.com
f252ca8ed1 Add check for Linux minidump ending on bad write for exploitability rating.
If a crash occurred as a result to a write to unwritable memory, it is reason
to suggest exploitability. The processor checks for a bad write by
disassembling the command that caused the crash by piping the raw bytes near
the instruction pointer through objdump. This allows the processor to see if
the instruction that caused the crash is a write to memory and where the
target of the address is located.

R=ivanpe@chromium.org

Review URL: https://codereview.chromium.org/1273823004

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1497 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-08-21 16:22:19 +00:00
ted.mielczarek@gmail.com
7b1ec78407 Don't use strtok_s for mingw builds
R=ivanpe at https://codereview.chromium.org/1292503005/


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1496 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-08-20 15:09:16 +00:00
rmcilroy@chromium.org
013acd5326 Add user_regs_struct and user_fpsimd_struct for aarch64 on Android.
Android's sys/user.h is missing user_regs_struct and user_fpsimd_struct.
Add them to the Android specific user.h used by breakpad to workaround
Android / glibc compatibility issues.

A bug has been filed on the Android NDK team to add the missing structures to
the NDK, at which point this hack can be removed.

Also remove the mxcsr_mask hack on x64, which is no longer required since
we have moved to the r10d NDK which fixes this issue.

R=primiano@chromium.org

Review URL: https://codereview.chromium.org/1291983003 .

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1495 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-08-20 14:30:38 +00:00
wfh@chromium.org
01f9665c63 Fix compile error with Windows clang.
This change fixes the following errors shown during compile with
Windows clang:

error: cannot pass non-trivial object of type 'ATL::CComBSTR' to variadic function; expected type from format string was 'wchar_t *' [-Wnon-pod-varargs]

Original CL: https://codereview.chromium.org/1252913009/

BUG=https://code.google.com/p/google-breakpad/issues/detail?id=662

Review URL: https://codereview.chromium.org/1307463003

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1494 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-08-19 22:28:17 +00:00
primiano@chromium.org
6e30d1ad6d Fix inttypes format macros in src/processor/proc_maps_linux.cc
crrev.com/1298443002 has introduced a build failure by re-defining
__STDC_FORMAT_MACROS. Fixing it.

BUG=
R=mark@chromium.org, ted.mielczarek@gmail.com

Review URL: https://codereview.chromium.org/1303493003 .

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1493 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-08-19 07:24:21 +00:00
primiano@chromium.org
24a2f501a8 Remove obsolete seccomp_unwinder for legacy (pre-BPF) sandbox
The PopSeccompStackFrame was introduced to deal with stack frames
originated in the legacy seccomp sandbox. The only user of that
sandbox was Google Chrome, but the legacy sandbox has been
deprecated in 2013 (crrev.com/1290643003) in favor of the new
bpf sandbox.
Removing this dead code as it has some small bound checking bug
which causes occasional crashes in WebView (which are totally
unrelated to the sandbox).

Note: this will require a corresponding change in the chromium
GYP/GN build files to roll.

BUG=665,chromium:477444
R=jln@chromium.org, mark@chromium.org, torne@chromium.org

Review URL: https://codereview.chromium.org/1299593003 .

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1492 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-08-18 08:38:14 +00:00
ted.mielczarek@gmail.com
767d5d5b0c Fix proc_maps_linux compile for non-Linux
R=ivanpe at https://codereview.chromium.org/1298443002/


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1491 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-08-17 11:55:15 +00:00
primiano@chromium.org
b51a14f396 [microdump] Move microdump writes to the crash ring-buffer log
So far the microdump_writer dumped the log in logcat using the default
system log. This is simple to achieve but has some drawbacks:
 1. Creates spam in the system log, pushing back other eventual useful
    messages.
 2. There is a high chance that the microdump gets lost if some log
    spam storm happens immediately after a crash and before the log
    is collected by the feedback client.
 3. Since Android L, the logger is smartly throttling messages (to
    reduce logcat spam). Throttling brekpad logs defeats the all
    point of microdumps.

This change is conceptually very simple. Replace the use of
__android_log_write() with __android_log_buf_write(), which takes
an extra bufID argument. The main drawback is that the
__android_log_buf_write is not exported in the NDK and needs to be
dynamically looked up via dlsym.
This choice has been discussed and advocated by Android owners.
See the internal bug b/21753476.

BUG=chromium:512755
R=thestig@chromium.org

Review URL: https://codereview.chromium.org/1286063003 .

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1490 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-08-17 10:32:26 +00:00
primiano@chromium.org
3fcf2e1eef [microdump] Fix hw architecture indication in build fingerprint line
r1456 introduced the possibility to customize the OS-line of the
microdump, enabling to replace, in the case of android, the generic
uname() info with the Android build fingerprint.
While doing that, it mistakenly removed the HW architecture indication
from the format.
See crbug.com/520075 for more details.

BUG=chromium:520075
R=mmandlis@chromium.org, torne@chromium.org

Review URL: https://codereview.chromium.org/1288313002 .

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1489 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-08-17 08:02:16 +00:00
Liu.andrew.x@gmail.com
c8dd1d54f9 Add check for executable stack/heap when rating Linux exploitability.
This CL also consequentially adds a public method to get the number of
mappings in a Linux minidump.

R=ivanpe@chromium.org

Review URL: https://codereview.chromium.org/1291603002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1488 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-08-15 00:37:14 +00:00
Liu.andrew.x@gmail.com
a33bd704c1 Add check to see if stack pointer is off the stack according to the memory
mappings when rating Linux exploitability.

R=ivanpe@chromium.org

Review URL: https://codereview.chromium.org/1286033002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1487 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-08-15 00:27:27 +00:00
Liu.andrew.x@gmail.com
8a35448388 Fix format specifier in proc maps to support 32-bit architectures.
R=ivanpe@chromium.org

Review URL: https://codereview.chromium.org/1288323003

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1486 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-08-13 20:13:55 +00:00
ted.mielczarek@gmail.com
4f96b603fe Actually remove removed files
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1485 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-08-13 19:49:44 +00:00
ted.mielczarek@gmail.com
baab7a7cb6 Remove some old unused code, add a missing include
R=lei at https://codereview.chromium.org/1211963002



git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1484 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-08-13 16:38:19 +00:00
Liu.andrew.x@gmail.com
383b815ed5 Fix format specifier in proc maps to support 32-bit architectures.
R=ivanpe@chromium.org

Review URL: https://codereview.chromium.org/1280853003

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1483 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-08-12 00:53:39 +00:00
Liu.andrew.x@gmail.com
6fa7555947 Allow Print() to be called by const instances of MinidumpLinuxMaps and
MinidumpLinuxMapsList.

R=ivanpe@chromium.org

Review URL: https://codereview.chromium.org/1287803002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1482 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-08-12 00:21:44 +00:00
Liu.andrew.x@gmail.com
213e3f7853 Change Print method of MinidumpLinuxMaps and MinidumpLinuxMapsList to print
contents of /proc/<pid>/maps instead of just the files mapped to memory.

Review URL: https://codereview.chromium.org/1273123002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1481 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-08-11 16:05:48 +00:00
ivanpe@chromium.org
c3a641288d Workaround for range map overlaps caused by Android package relocation.
If there is a 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.

Patch from Simon Baldwin <simonb@chromium.org>.

https://code.google.com/p/chromium/issues/detail?id=509110

R=simonb@chromium.org

Review URL: https://codereview.chromium.org/1275173005

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1480 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-08-10 17:03:29 +00:00
cjhopman@chromium.org
413754dfdd Fix breakpad for arm on arm64
On arm64 devices, GETFPREGS fails with errno==EIO. Ignore those failures
on Android arm builds.

BUG=508324
R=thestig@chromium.org

Review URL: https://codereview.chromium.org/1268023003 .

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1479 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-08-05 22:48:48 +00:00
Liu.andrew.x@gmail.com
c625d7cb82 Fix potential null pointer dereference.
If a MinidumpLinuxMapsList was created and destroyed without its Read method,
the program would have a segmentation fault because the destructor did not
check for a null maps_ field. Additional changes include additional
supplementary null checks, a potential memory leak fix, and some comment
removal.

Review URL: https://codereview.chromium.org/1271543002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1478 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-07-31 15:26:39 +00:00
Liu.andrew.x@gmail.com
8608fe10bf Remove unnecessary dependencies.
Review URL: https://codereview.chromium.org/1266493002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1477 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-07-29 00:09:22 +00:00
Liu.andrew.x@gmail.com
044c744012 Add support for Linux memory mapping stream and remove ELF header usage
when checking exploitability rating.

Linux minidumps do not support MD_MEMORY_INFO_LIST_STREAM, meaning the
processor cannot retrieve its memory mappings. However, it has its own
stream, MD_LINUX_MAPS, which contains memory mappings specific to Linux
(it contains the contents of /proc/self/maps). This CL allows the minidump
to gather information from the memory mappings for Linux minidumps.

In addition, exploitability rating for Linux dumps now use memory mappings
instead of checking the ELF headers of binaries. The basis for the change
is that checking the ELF headers requires the minidumps to store the memory
from the ELF headers, while the memory mapping data is already present,
meaning the size of a minidump will be unchanged.

As a result, of removing ELF header analysis, two unit tests have been removed.
Arguably, the cases that those unit tests check do not merit a high
exploitability rating and do not warrant a solid conclusion that was given
earlier.

R=ivanpe@chromium.org

Review URL: https://codereview.chromium.org/1251593007

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1476 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-07-28 00:53:44 +00:00
Liu.andrew.x@gmail.com
93c3c398ff Fix incorrect comment.
The exploitability rating for a dump is EXPLOITABILITY_NOT_ANALYZED if the
exploitability engine in not enabled, not EXPLOITABILITY_NONE.

R=ivanpe@chromium.org

Review URL: https://codereview.chromium.org/1254333002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1475 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-07-27 18:04:54 +00:00
vapier@chromium.org
398384e1cf add aarch64 support to minidump-2-core
The thread info expects the struct names as they expect in asm/ptrace.h,
but the header doesn't include that, it includes sys/user.h.  Rename the
reg structs to match that header.

Rename the elf_siginfo to _elf_siginfo to avoid conflicting with the one
in the sys/procfs.h.  It is only used locally in one place, so we don't
need to update any callers.

Otherwise, drop in aarch64 support into the minidump-2-core file.

BUG=chromium:334368


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1474 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-07-20 10:21:27 +00:00
vapier@chromium.org
0295bfea40 tests: InstructionPointerMemoryNullPointer: make it work under llvm
When LLVM sees an attempt to dereference a NULL pointer, it will generate
invalid opcodes (undefined behavior) which leads to SIGILL which breaks
this unittest.  Upstream's recommendation in this case is to add volatile
markings to get the actual dereference to happen.

This is documented in the blog post under "Dereferencing a NULL Pointer":
http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1473 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-07-20 06:19:49 +00:00
Liu.andrew.x@gmail.com
4ef4c7a595 Add ELF header analysis when checking for instruction pointer in code.
If the minidump module containing the instruction pointer has memory
containing the ELF header and program header table, when checking the
exploitability rating, the processor will use the ELF header data to determine
if the instruction pointer lies in an executable region of the module, rather
than just checking if it lies in a module.

R=ivanpe@chromium.org

Review URL: https://codereview.chromium.org/1233973002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1472 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-07-16 20:42:29 +00:00
wfh@chromium.org
d74d407688 Fix -Wreorder warnings in the Windows code.
This makes the order of fields in constructor initializer lists match
the order in which the fields are declared in (which is the order
they're initialized in). No intended behavior change.

This change was originally reviewed at
https://codereview.chromium.org/1230923005/

BUG=chromium:505304
TBR=thakis@chromium.org

Review URL: https://codereview.chromium.org/1234653002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1471 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-07-10 20:24:33 +00:00
changluo@google.com
1d2b6ce3cd Default nil or empty version string to CFBundleVersion
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1470 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-07-10 01:29:50 +00:00
Liu.andrew.x@gmail.com
bd7af02472 Set exception whitelist check as earlier check instead of last check.
When I first added the exception whitelist, I meant to put the check before
checking the location of the instruction pointer. (I didn't notice that it
was after the other check until now.) The whitelist check is to quickly rule
out minidumps, and if checking the instruction pointer provided any useful
information, it would be pretty indicative that the exception causing the
dump is interesting.

R=ivanpe@chromium.org

Review URL: https://codereview.chromium.org/1211253009

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1469 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-07-07 21:30:06 +00:00
Liu.andrew.x@gmail.com
ff4d8facbf Use general instruction/stack pointer convenience method instead of manually
finding the instruction/stack pointer for exploitability rating.

There was already a method that found the instruction pointer, so the files
for exploitability ratings had repeated code. Also a method for finding the
stack pointer is implemented in this CL.

R=ivanpe@chromium.org

Review URL: https://codereview.chromium.org/1210943005

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1468 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-06-30 23:22:09 +00:00
Liu.andrew.x@gmail.com
ca21e62ecf Checking for benign exceptions that trigger a minidump.
If the exception reponsible for the crash is benign, such as a floating point
exception, we can rule out the possibility that the code is exploitable. This
CL checks for such exceptions and marks the dump as not exploitable if such an
exception is found.

R=ivanpe@chromium.org

Review URL: https://codereview.chromium.org/1212383004

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1467 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-06-30 20:34:39 +00:00
Liu.andrew.x@gmail.com
a3f0a28b69 This CL adds support for ARM and ARM64 architectures when calculating
exploitability ratings.

The stackwalker will now grab the instruction pointers for ARM and ARM64
architectures, so checking exploitability on ARM and ARM64 will no longer
return EXPLOITABILITY_ERR_PROCESSING.

R=ivanpe@chromium.org

Review URL: https://codereview.chromium.org/1216063004

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1466 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-06-30 18:17:23 +00:00
rmcilroy@chromium.org
5ecc80d579 Adjust breakpad module size to match adjusted start_addr.
When changing a module's start_addr to account for Android packed
relocations, also adjust its size field so that the apparent module
end addr calculated by the breakpad processor does not alter.

Ensures that the mapping entry from a packed library is consistent
with that which an unpacked one would produce.

BUG=499747
R=primiano@chromium.org, rmcilroy@chromium.org

Review URL: https://codereview.chromium.org/1211863002.

Patch from Simon Baldwin <simonb@chromium.org>.

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1465 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-06-30 13:30:22 +00:00
Liu.andrew.x@gmail.com
b559587dd7 Checking location of the instruction pointer to see if it is
in valid code for Linux exploitability rating.

This CL adds to the Linux exploitability checker by verifying that the
instruction pointer is in valid code. Verification is done by obtaining a
memory mapping of the crash and checking if the instruction pointer lies in
an executable region. If there is no memory mapping, the instruction pointer
is checked to determine if it lies within a known module.

R=ivanpe@chromium.org

Review URL: https://codereview.chromium.org/1210493003

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1464 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-06-25 23:05:16 +00:00
rsesek@chromium.org
cb4f056f12 Update the upload.py code review server.
This is follow-up to r1455.

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1463 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-06-24 16:27:36 +00:00
ivanpe@chromium.org
f681a13afe Reconfigured options for sym_upload to not treat h and ? flags as invalid options.
I'm submitting this on behalf of Andrew Liu.

R=mmandlis@chromium.org

Review URL: https://codereview.chromium.org/1196733004

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1462 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-06-22 21:21:40 +00:00
primiano@chromium.org
8b5c70a438 Fix signal propagation logic for Linux/Android exception handler.
The current code is relying on info->si_pid to figure out whether
the exception handler was triggered by a signal coming from the kernel
(that will re-trigger until the cause that triggered the signal has
been cleared) or from user-space e.g., kill -SIGNAL pid, which will NOT
automatically re-trigger in the next signal handler in the chain.
While the intentions are good (manually re-triggering user-space
signals), the current implementation mistakenly looks at the si_pid
field in siginfo_t, assuming that it is coming from the kernel if
si_pid == 0.
This is wrong. siginfo_t, in fact, is a union and si_pid is meaningful
only for userspace signals. For signals originated by the kernel,
instead, si_pid overlaps with si_addr (the faulting address).
As a matter of facts, the current implementation is mistakenly
re-triggering the signal using tgkill for most of the kernel-space
signals (unless the fault address is exactly 0x0).
This is not completelly correct for the case of SIGSEGV/SIGBUS. The
next handler in the chain will stil see the signal, but the |siginfo|
and the |context| arguments of the handler will be meaningless
(retriggering a signal with tgkill doesn't preserve them).
Therefore, if the next handler in the chain expects those arguments
to be set, it will fail.
Concretelly, this is causing problems to WebView. In some rare
circumstances, the next handler in the chain is a user-space runtime
which does SIGSEGV handling to implement speculative null pointer
managed exceptions (see as an example
http://www.mono-project.com/docs/advanced/runtime/docs/exception-handling/)

The fix herein proposed consists in using the si_code (see SI_FROMUSER
macros) to determine whether a signal is coming form the kernel
(and therefore just re-establish the next signal handler) or from
userspace (and use the tgkill logic).

Repro case:
This issue is visible in Chrome for Android with this simple repro case:
- Add a non-null pointer dereference in the codebase:
  *((volatile int*)0xbeef) = 42
Without this change: the next handler (the libc trap) prints:
  F/libc  (  595): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x487
  where 0x487 is actually the PID of the process (which is wrong).
With this change: the next handler prints:
  F/libc  (  595): Fatal signal 11 (SIGSEGV), code 1, fault addr 0xbeef
  which is the correct answer.

BUG=chromium:481937
R=mark@chromium.org

Review URL: https://breakpad.appspot.com/6844002.

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1461 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-06-22 11:50:00 +00:00
ivanpe@chromium.org
72c4716d06 Use local variable for out parameter rather than direct use of ivar
- Resolves spurious static analyzer warning about response_ being potentially leaked due to the retain in Xcode 6.3 and later.

I'm submitting this on behalf of Brian Moore.

R=qsr@chromium.org

Review URL: https://codereview.chromium.org/1171693007

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1460 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-06-20 00:32:37 +00:00
rmcilroy@chromium.org
b3b3d2144f Update breakpad for Android packed relocations.
Shared libraries containing Android packed relocations have a load
bias that differs from the start address in /proc/$$/maps. Current
breakpad assumes that the load bias and mapping start address are
the same.

Fixed by changing the client to detect the presence of Android packed
relocations in the address space of a loaded library, and adjusting the
stored mapping start address of any that are packed so that it contains
the linker's load bias.

For this to work properly, it is important that the non-packed library
is symbolized for breakpad. Either packed or non-packed libraries may
be run on the device; the client detects which has been loaded by the
linker.

BUG=499747
R=primiano@chromium.org, rmcilroy@chromium.org

Review URL: https://codereview.chromium.org/1189823002.

Patch from Simon Baldwin <simonb@chromium.org>.

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1459 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-06-19 16:30:42 +00:00
vapier@chromium.org
6ccf732733 update more ignore files
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1458 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-05-28 06:16:15 +00:00
primiano@chromium.org
e925c2a8c1 [microdump] Add build fingerprint and product info metadata.
This is to add build fingerprint and product name/version to
microdumps. Conversely to what happens in the case of minidumps
with MIME fields, due to the nature of minidumps, extra metadata
cannot be reliably injected after the dump is completed.
This CL adds the plumbing to inject two optional fields plus the
corresponding tests.

BUG=chromium:410294
R=thestig@chromium.org

Review URL: https://codereview.chromium.org/1125153008

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1456 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-05-15 08:43:01 +00:00
mark@chromium.org
3dc3a6d272 Switch code review server to codereview.chromium.org.
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1455 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-05-06 17:52:38 +00:00
primiano@chromium.org
5f0fc7acef Fix signal propagation logic for Linux/Android exception handler.
The current code is relying on info->si_pid to figure out whether
the exception handler was triggered by a signal coming from the kernel
(that will re-trigger until the cause that triggered the signal has
been cleared) or from user-space e.g., kill -SIGNAL pid, which will NOT
automatically re-trigger in the next signal handler in the chain.
While the intentions are good (manually re-triggering user-space
signals), the current implementation mistakenly looks at the si_pid
field in siginfo_t, assuming that it is coming from the kernel if
si_pid == 0.
This is wrong. siginfo_t, in fact, is a union and si_pid is meaningful
only for userspace signals. For signals originated by the kernel,
instead, si_pid overlaps with si_addr (the faulting address).
As a matter of facts, the current implementation is mistakenly
re-triggering the signal using tgkill for most of the kernel-space
signals (unless the fault address is exactly 0x0).
This is not completelly correct for the case of SIGSEGV/SIGBUS. The
next handler in the chain will stil see the signal, but the |siginfo|
and the |context| arguments of the handler will be meaningless
(retriggering a signal with tgkill doesn't preserve them).
Therefore, if the next handler in the chain expects those arguments
to be set, it will fail.
Concretelly, this is causing problems to WebView. In some rare
circumstances, the next handler in the chain is a user-space runtime
which does SIGSEGV handling to implement speculative null pointer
managed exceptions (see as an example
http://www.mono-project.com/docs/advanced/runtime/docs/exception-handling/)

The fix herein proposed consists in using the si_code (see SI_FROMUSER
macros) to determine whether a signal is coming form the kernel
(and therefore just re-establish the next signal handler) or from
userspace (and use the tgkill logic).

Repro case:
This issue is visible in Chrome for Android with this simple repro case:
- Add a non-null pointer dereference in the codebase:
  *((volatile int*)0xbeef) = 42
Without this change: the next handler (the libc trap) prints:
  F/libc  (  595): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x487
  where 0x487 is actually the PID of the process (which is wrong).
With this change: the next handler prints:
  F/libc  (  595): Fatal signal 11 (SIGSEGV), code 1, fault addr 0xbeef
  which is the correct answer.

BUG=chromium:481937
R=mark@chromium.org

Review URL: https://breakpad.appspot.com/6844002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1454 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-04-30 09:12:54 +00:00
erikchen@chromium.org
b0c09bd7ea Support object files larger than 2**32.
Reviewed at https://breakpad.appspot.com/7834002/#ps340001


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1453 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-04-22 20:14:24 +00:00
rmcilroy@chromium.org
1d4f1396b2 [MIPS]: Use mcontext_t structure for MIPS
This change removes user_regs_struct and
user_fpregs_struct structures for mips
and uses mcontext_t instead.

R=fdegans@chromium.org, mark@chromium.org, rmcilroy@chromium.org

Review URL: https://breakpad.appspot.com/3744002

Patch from Gordana Cmiljanovic <Gordana.Cmiljanovic@imgtec.com>.

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1452 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-04-21 21:34:14 +00:00
vapier@chromium.org
bffca12384 update svn:ignores
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1451 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-04-18 03:27:45 +00:00
vapier@chromium.org
27447e58e3 synx with latest upstream gnuconfig
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1450 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-04-18 03:25:50 +00:00
cjhopman@chromium.org
8f38da092c Fix call to rt_sigaction
Despite the fact that many places imply that sigaction and rt_sigaction
are essentially the same, rt_sigaction's signature is actually
different-- it takes the size of the kernel's sigset_t as an extra argument.

BUG=473973


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1447 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-04-15 22:57:24 +00:00
mark@chromium.org
097cf4f8ad MIPS64: Initial MIPS64 related change.
With this change Breakpad can be compiled for MIPS64,
but it is not yet functional.

Patch by Gordana Cmiljanovic <Gordana.Cmiljanovic@imgtec.com>
Review URL: https://breakpad.appspot.com/6824002/


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1446 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-04-15 19:28:11 +00:00
mark@chromium.org
8cabceb005 Use __NR_rt_sigaction instead of __NR_sigaction
__NR_sigaction is not defined on arm64/x64/etc (or rather, it's defined
in unistd-32.h instead of unistd.h).

Patch by Chris Hopman <cjhopman@chromium.org>
Review URL: https://breakpad.appspot.com/10724002/


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1443 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-04-13 23:59:06 +00:00
primiano@chromium.org
1a903f088b Microdump processor: be more tolerant for different logcat formats
The current processor implementation is grepping for /google-breakpad(
in the logcat lines, to filter out microdump lines, which by default
look like this:
W/google-breakpad( 3728): -----BEGIN BREAKPAD MICRODUMP-----

Turns out that logcat format can vary, when passing optional arguments,
and produce something like the following:

04-13 12:30:35.563  6531  6531 W google-breakpad: -----BEGIN ...

In the latter case, the "/google-breakpad(" filter is too aggressive.
This change is relaxing it, so it is compatible also with non-default
logcat arguments.

BUG=640
R=mmandlis@chromium.org

Review URL: https://breakpad.appspot.com/2864002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1442 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-04-13 17:45:17 +00:00
mark@chromium.org
b8b8f6c6f3 Add address and reason for IN_PAGE_ERROR.
ACCESS_VIOLATION and IN_PAGE_ERROR both specify
read/write/dep flags and address. ACCESS_VIOLATION currently
reports these, but IN_PAGE_ERROR does not. This change makes
IN_PAGE_ERROR report this information as well, and also the
additional NTSTATUS value for the underlying cause.

Patch by bungeman@chromium.org
Review URL: https://breakpad.appspot.com/1794002/


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1441 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-04-10 22:05:29 +00:00
mark@chromium.org
aa6268fdf9 Workaround Android sigaction bug
On Android L+, signal and sigaction symbols are provided by libsigchain
that override the system's versions. There is a bug in these functions
where they essentially ignore requests to install SIG_DFL.

Workaround this issue by explicitly performing a syscall to
__NR_rt_sigaction to install SIG_DFL on Android.

BUG=473973

Patch by Chris Hopman <cjhopman@chromium.org>
Review URL: https://breakpad.appspot.com/1804002/


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1438 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-04-10 17:57:24 +00:00
ted.mielczarek@gmail.com
9d1daff1d2 Fix compilation with gcc --std=c++11
Patch by Jon Turney <jon.turney.1111@gmail.com>
R=ted at https://breakpad.appspot.com/7824002/



git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1435 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-03-24 11:25:14 +00:00
primiano@chromium.org
622588226d Fix compatibility with Android NDK r10d.
This is a reland of the previous CL (r1433). r1433 did not achieve what
intended and failed the x86_64 build of Chrome with NDK r10c.
The workaround logic in this CL is identical to r1433, but the #define
magic is applied in a more appropriate proper place this time. Turns
out Breakpad already has an Android compatibility layer, which is
common/android/include. Piggybacking the fix there.

BUG=breakpad:642
R=fdegans@chromium.org, rmcilroy@chromium.org

Review URL: https://breakpad.appspot.com/3794002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1434 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-03-16 14:12:20 +00:00
primiano@chromium.org
be470f3a11 Make breakpad compatible with Android NDK r10d.
r1397 did introduce a workaround to deal with a typo in sys/user.h
in the Android NDK. The typo has been fixed in [1]. However, breakpad
cannot just switch to the fixed version as this would require atomic
rolls of Breakpad and NDK in chromium, which would make reverts hard
to handle.
This change introduces an inelegant yet functional hack which makes
breakpad compatible with both versions of the NDK, with and without
the typo. It can be reverted once Chrome has stably rolled to NDK
r10d.

[1] https://android.googlesource.com/platform/bionic/+/f485547b

BUG=breakpad:642
R=fdegans@chromium.org, rmcilroy@chromium.org

Review URL: https://breakpad.appspot.com/7814002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1433 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-03-10 20:09:06 +00:00
primiano@chromium.org
eb81077a4f Microdump writer: stop using new/malloc in compromised context
A recent change in the client-side microdump write (r1404) ended up
introducing a call to new() to instantiate the line buffer that
microdump uses to dump its lines. new/malloc is a luxury we cannot
afford in a compromised context.
This change switches the line buffer to be backed by the dumper
page allocator, which on Linux/Android ends up requesting pages
via mmap.
Also, the microdump write bails out without crashing if the page
allocator failed (crash during severe OOM).

BUG=640

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1432 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-03-10 20:06:04 +00:00
ted.mielczarek@gmail.com
8ba5453573 Fix Windows dump_syms x64 linking
The dia_sdk GYP target points at the x86 diaguids.lib, it needs to
point at the x64 one for x64 builds.
R=mark at https://breakpad.appspot.com/9784002/

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1431 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-03-06 20:12:00 +00:00
ted.mielczarek@gmail.com
b0fbff302a Formatting tweak for https://breakpad.appspot.com/9774002, add more newlines
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1430 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-02-27 13:40:41 +00:00
hashimoto@chromium.org
43b75f42a7 Add stack contents output functionality to minidump_stackwalk
This feature is enabled only when "-s" is provided as a commandline option.

minidump_stackwalk.cc:
 - Add a new commandline option "-s" to output stack contents.
 - Instantiate Minidump object in PrintMinidumpProcess() to keep it alive longer so that accessing process_state.thread_memory_regions() in stackwalk_common.cc doesn't result in use-after-free.

stackwalk_common.cc:
 - Add a new function PrintStackContents() to output stack contents.

R=mark@chromium.org

Review URL: https://breakpad.appspot.com/9774002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1429 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-02-27 04:52:21 +00:00
mark@chromium.org
8ca937a3a7 Update license on convert_UTF.* to the standard Unicode license.
BUG=google-breakpad:270
R=ted.mielczarek@gmail.com

Review URL: https://breakpad.appspot.com/9764002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1428 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-02-25 21:16:43 +00:00
wfh@chromium.org
2b7360217e Add option to Breakpad to consume INVALID_HANDLE_VALUE exceptions.
BUG=chromium:452613
R=mark@chromium.org

Review URL: https://breakpad.appspot.com/7794002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1427 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-02-22 02:27:35 +00:00
thestig@chromium.org
4aeb452cdd Cleanup Linux debug link file handling code.
- Handle the case when the debug link points back to the object file.
- Move some checks into a separate SanitizeDebugFile() function.

BUG=636
Review URL: https://breakpad.appspot.com/3784002/


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1426 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-02-10 22:36:39 +00:00
mark@chromium.org
19a35ba066 Fix overflow error in breakpad for linux
A computation in the stack unwind algorithm could cause an overflow if a base
pointer read from crashed process is sufficiently close to top of address space.
This causes a memory read that causes the dump thread to crash, resulting in a
failure to generate crash dump. Check fixed to properly detect that this pointer
is greater than actual memory range of current stack.

Patch by Kyle Joswiak <kjoswiak@chromium.org>

Review URL: https://breakpad.appspot.com/3754003/


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1425 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-02-05 23:01:31 +00:00
thestig@chromium.org
5bf649f336 Add unit tests for overlapping functions and externs.
R=mark@chromium.org

Review URL: https://breakpad.appspot.com/3774002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1424 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-02-04 00:03:58 +00:00
thestig@chromium.org
41f858a4d7 Handle ARM THUMB functions when removing duplicate PUBLIC entries.
In ELF symtab/dynsym sections, THUMB function addresses have bit 0 set,
whereas the DWARF function entries are not.

R=mark@chromium.org

Review URL: https://breakpad.appspot.com/7774002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1423 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-02-03 23:13:04 +00:00
hashimoto@chromium.org
54d899d631 Follow debug link correctly
As thestig@chromium.org pointed out in https://breakpad.appspot.com/9684002,
LoadSymbols() should return false if |read_gnu_debug_link| is false.

BUG=chromium:453498
R=thestig@chromium.org

Review URL: https://breakpad.appspot.com/2844002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1422 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-02-03 07:16:04 +00:00
hashimoto@chromium.org
16ab317dfc Demangle symbol name
The spec says it should be demangled.
https://code.google.com/p/google-breakpad/wiki/SymbolFiles

BUG=chromium:453498
R=mark@chromium.org

Review URL: https://breakpad.appspot.com/2854002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1421 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-02-03 03:17:30 +00:00
benchan@chromium.org
d6eb7fa1b8 Handle failures of copying process data from a core file.
When LinuxCoreDumper fails to copy process data from a core file, it
fills the return buffer with a repeated sequence of a special marker.
However, MinidumpWriter doesn't know about that and may incorrectly
interpret the data. In many cases, MinidumpWriter simply copies the
gibberish data to the minidump, which isn't too bad. However, the
gibberish data may cause MinidumpWriter to behave badly in some other
cases. For example, when MinidumpWriter tries to iterate through the
linked list of all loaded DSOs via the r_map field of a r_debug struct,
if the linked list is filed with the special marker, the code keeps
iterating through the same address.

This CL addresses the issue by having LinuxCoreDumper::CopyFromProcess()
returns a Boolean value to indicate if the expected data is found from
the core file. MinidumpWriter can then decide how to handle that.

BUG=chromium:453484
TEST=Run core2md with the test data attached to chromium:453484.
R=mark@chromium.org

Review URL: https://breakpad.appspot.com/4724002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1420 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-02-02 23:27:27 +00:00
ted.mielczarek@gmail.com
d2904bb421 Replace uses of hash_map with unordered_map
hash_map no longer exists in Visual C++ 2015.
A=Brian Smith <brian@briansmith.org>
R=ted at https://bugzilla.mozilla.org/show_bug.cgi?id=1119072

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1419 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-02-02 14:05:45 +00:00
vapier@chromium.org
7c7366dd6d Remove unneeded definitions of O_BINARY
Review URL: https://breakpad.appspot.com/6684002/


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1418 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-01-28 21:47:31 +00:00
benchan@chromium.org
55f879151c Remove unused variable 'kGUIDStringSize' in microdump_writer_unittest.
R=mark@chromium.org

Review URL: https://breakpad.appspot.com/3754002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1417 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-01-28 18:33:50 +00:00
hashimoto@chromium.org
a4eb2e302c Stop calling memmove when unnecessary
BUG=chromium:450137
R=mark@chromium.org



git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1416 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-01-27 03:27:08 +00:00
erikchen@chromium.org
ccc06f4798 Fix some fragile code that is likely to cause future memory corruption
problems.

- The ordering of keys in stl containers cannot change. Make the relevant
members const to guarantee this assumption.
- Add handling and logging for demangle errors.
- Fix a potential double-delete bug if a function passed to AddFunction() is
already present.

BUG=chromium:449214
R=mark@chromium.org

Review URL: https://breakpad.appspot.com/10704002/


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1415 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-01-27 01:20:59 +00:00
erikchen@chromium.org
acb33ed38f Fix a source of memory corruption.
This error was causing crashes in official Chrome Mac builds on 10.8.5
machines.

BUG=chromium:449214
R=mark@chromium.org


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1414 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-01-26 23:19:04 +00:00
primiano@chromium.org
2f77d4e41c Fix the scope on the initialization of kMicrodumpOnConsole to match header.
I whish I knew how this worked for months in chromium as it is clearly wrong.
As reported by azarchs@ it is breaking the cygprofile instrumented build.

BUG=chromium:410294

Review URL: https://breakpad.appspot.com/1784002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1413 4c0a9323-5329-0410-9bdc-e9ce6186880e
2015-01-09 17:58:19 +00:00
wfh@chromium.org
0a5700b594 Modify minidump_stackwalk to be more tolerant of overlapping ranges.
These ranges can be seen in some Android minidumps.

BUG=chromium:439531
R=mark@chromium.org

Review URL: https://breakpad.appspot.com/9744002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1412 4c0a9323-5329-0410-9bdc-e9ce6186880e
2014-12-20 00:47:07 +00:00
jessicag.feedback@gmail.com
e0d5189f74 Add microdump files to project.
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1411 4c0a9323-5329-0410-9bdc-e9ce6186880e
2014-12-11 19:30:37 +00:00
mdempsky@chromium.org
c32b7ad535 Remove pointers from serialized file format
BUG=breakpad:621
R=thestig@chromium.org

Review URL: https://breakpad.appspot.com/1764002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1410 4c0a9323-5329-0410-9bdc-e9ce6186880e
2014-12-11 01:17:43 +00:00
mark@chromium.org
aad5d66fa5 Breakpad: Fix build with new clang versions.
gcc has a single exception setting for all languages. Saying -fno-exceptions
in gcc disables exceptions and cleanups for cc files, but has no effect for mm
files.

In clang, -fno-exceptions only disables c++ exceptions, but keeps objective-c
exceptions and cleanups enabled.

http://llvm.org/viewvc/llvm-project?view=revision&revision=220714 changed
__EXCEPTIONS to be defined for clang when cleanups are enabled, independent of
if c++ exceptions are enabled. (This was necessary to have clang work with
glibc which looks at __EXCEPTIONS to decide if cleanups are enabled.)

Breakpad tried to use __EXCEPTIONS to figure out if c++ exceptions are enabled.
In cc files, this works: -fno-exceptions will disable c++ exceptions and
cleanups. But in mm files, -fno-exceptions will disable c++ exceptions and
objective-c exceptions will still be enabled, and so cleanups must run and hence
__EXCEPTIONS is defined.

To make things work with both old and new compilers, do the try/catch hack in
mm files either if __EXCEPTIONS is not defined (for old compilers) or if the
compiler is clang and __has_feature(cxx_exceptions) isn't set (which will work
for new clangs too, and which cleanly maps to if c++ exceptions are enabled).

Patch by Nico Weber <thakis@chromium.org>

Review URL: https://breakpad.appspot.com/1774002/


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1409 4c0a9323-5329-0410-9bdc-e9ce6186880e
2014-12-10 16:08:09 +00:00
mseaborn@chromium.org
e9df0305d3 dump_syms: Fix handling of DW_FORM_ref_addr to work with DWARF 4
Previously, dump_syms did not handle DW_FORM_ref_addr if it appeared
in DWARF 4 debugging info.

Also fix a DW_FORM_ref_addr case so that it doesn't fall through to
the next switch case when assertions are disabled and the DWARF
version isn't recognised.

The following steps will reproduce the problem when using LLVM 3.4:

cat <<END >example1.c
int main() { return 0; }
END
cat <<END >example2.c
void foo(int x) {}
END

clang -emit-llvm -g -c example1.c -o example1.bc
clang -emit-llvm -g -c example2.c -o example2.bc
llvm-link-3.4 example1.bc example2.bc -o combined.bc
clang combined.bc -o executable
./google-breakpad/build/src/tools/linux/dump_syms/dump_syms executable

When using LLVM bitcode linking in this way, LLVM's backend generates
partially-merged DWARF debugging info in which some of the references
to the "int" type go via "DW_FORM_ref_addr".  Since PNaCl uses LLVM
bitcode linking, this dump_syms failure occurs with nexes produced by
the PNaCl toolchain.

BUG= https://code.google.com/p/chromium/issues/detail?id=416368
TEST= see above
R=mark@chromium.org, mcgrathr@chromium.org

Review URL: https://breakpad.appspot.com/5744002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1408 4c0a9323-5329-0410-9bdc-e9ce6186880e
2014-12-03 20:39:55 +00:00
primiano@chromium.org
a4283fc4cf 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
2014-12-02 15:31:25 +00:00
ivanpe@chromium.org
259512f933 Surfacing the process create time in google_breakpad::ProcessState
and updating minidump_stackwalk to show process uptime.

I tested this with a minidump from Chrome and I got a result that
is inline with what the Windows debugger is showing for that dump:

minidump_stackwalk output:
--------------------------
Process uptime: 601 seconds

WinDBG output:
--------------
Process Uptime: 0 days 0:10:01.000

I didn't update the machine readable output of minidump_stackwalk
on purpose in order to avoid breaking someone that uses it.
It can be added later to the machine output if needed.

R=mark@chromium.org

Review URL: https://breakpad.appspot.com/7754002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1406 4c0a9323-5329-0410-9bdc-e9ce6186880e
2014-11-25 22:45:23 +00:00
primiano@chromium.org
725a5dff8a Introduce microdump_stackwalk comand line executable
This introduces the microdump_stackwalk binary which takes advantage
of the MicrodumpProcessor to symbolize microdumps.
Its operation is identical to the one of minidump_stackwalk.
This CL, in fact, is also refactoring most of the common bits into
stackwalk_common.

BUG=chromium:410294
R=mmandlis@chromium.org

Review URL: https://breakpad.appspot.com/4704002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1405 4c0a9323-5329-0410-9bdc-e9ce6186880e
2014-11-25 11:36:38 +00:00
primiano@chromium.org
63f4e5f479 Fix microdump_writer and add unittest.
This adds some small fixes to the microdump writer and introduces
a unittest.

BUG=chromium:410294
R=mmandlis@chromium.org

Review URL: https://breakpad.appspot.com/2814002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1404 4c0a9323-5329-0410-9bdc-e9ce6186880e
2014-11-25 10:35:53 +00:00
mmandlis@chromium.org
7de07eed33 Microdump processing implementation
According to design document: http://goo.gl/B3wIRN
This is an initial implementation version, support ARM architecture only.

BUG=chromium:410294
R=primiano@chromium.org

Review URL: https://breakpad.appspot.com/5714003

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1403 4c0a9323-5329-0410-9bdc-e9ce6186880e
2014-11-19 21:33:26 +00:00
95 changed files with 1149 additions and 8338 deletions

View File

@ -1,26 +0,0 @@
# Travis build integration.
# https://docs.travis-ci.com/
language: cpp
# TODO: add a clang build as well.
compiler:
- gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-4.8
- g++-4.8
# Travis sets CC/CXX to the system toolchain based on the `compiler`
# selection. If clang is added, this should move to be set inside the
# matrix.
env:
- USE_CC=gcc-4.8 USE_CXX=g++-4.8
before_install: ./scripts/travis-checkout.sh
script: ./scripts/travis-build.sh
# TODO: add mac support
os:
- linux
notifications:
email:
- google-breakpad-dev@googlegroups.com

View File

@ -116,7 +116,6 @@ pkgconfig_DATA =
if SYSTEM_TEST_LIBS
TEST_CFLAGS = $(GTEST_CFLAGS) $(GMOCK_CFLAGS)
TEST_LIBS = $(GTEST_LIBS) -lgtest_main $(GMOCK_LIBS)
TEST_DEPS =
else
TEST_CFLAGS = \
-I$(top_srcdir)/src/testing/include \
@ -124,7 +123,6 @@ TEST_CFLAGS = \
-I$(top_srcdir)/src/testing/gtest \
-I$(top_srcdir)/src/testing
TEST_LIBS = src/testing/libtesting.a
TEST_DEPS = $(TEST_LIBS)
endif
## Libraries
@ -140,7 +138,6 @@ check_LIBRARIES += src/testing/libtesting.a
if !SYSTEM_TEST_LIBS
src_testing_libtesting_a_SOURCES = \
src/breakpad_googletest_includes.h \
src/testing/gtest/src/gtest-all.cc \
src/testing/gtest/src/gtest_main.cc \
src/testing/src/gmock-all.cc
@ -164,33 +161,21 @@ src_client_linux_libbreakpad_client_a_SOURCES = \
src/client/linux/dump_writer_common/thread_info.cc \
src/client/linux/dump_writer_common/ucontext_reader.cc \
src/client/linux/handler/exception_handler.cc \
src/client/linux/handler/exception_handler.h \
src/client/linux/handler/minidump_descriptor.cc \
src/client/linux/handler/minidump_descriptor.h \
src/client/linux/log/log.cc \
src/client/linux/log/log.h \
src/client/linux/microdump_writer/microdump_writer.cc \
src/client/linux/microdump_writer/microdump_writer.h \
src/client/linux/minidump_writer/linux_core_dumper.cc \
src/client/linux/minidump_writer/linux_dumper.cc \
src/client/linux/minidump_writer/linux_ptrace_dumper.cc \
src/client/linux/minidump_writer/minidump_writer.cc \
src/client/minidump_file_writer-inl.h \
src/client/minidump_file_writer.cc \
src/client/minidump_file_writer.h \
src/common/convert_UTF.c \
src/common/convert_UTF.h \
src/common/md5.cc \
src/common/md5.h \
src/common/string_conversion.cc \
src/common/string_conversion.h \
src/common/linux/elf_core_dump.cc \
src/common/linux/elfutils.cc \
src/common/linux/elfutils.h \
src/common/linux/file_id.cc \
src/common/linux/file_id.h \
src/common/linux/guid_creator.cc \
src/common/linux/guid_creator.h \
src/common/linux/linux_libc_support.cc \
src/common/linux/memory_mapped_file.cc \
src/common/linux/safe_readlink.cc
@ -395,7 +380,6 @@ check_PROGRAMS += \
src/processor/pathname_stripper_unittest \
src/processor/postfix_evaluator_unittest \
src/processor/proc_maps_linux_unittest \
src/processor/range_map_shrink_down_unittest \
src/processor/range_map_unittest \
src/processor/stackwalker_amd64_unittest \
src/processor/stackwalker_arm_unittest \
@ -483,12 +467,9 @@ src_client_linux_linux_client_unittest_shlib_SOURCES = \
src/client/linux/minidump_writer/proc_cpuinfo_reader_unittest.cc \
src/common/linux/elf_core_dump.cc \
src/common/linux/linux_libc_support_unittest.cc \
src/common/linux/tests/auto_testfile.h \
src/common/linux/tests/crash_generator.cc \
src/common/memory_unittest.cc \
src/common/tests/auto_tempdir.h \
src/common/tests/file_utils.cc \
src/common/tests/file_utils.h \
src/processor/basic_code_modules.cc \
src/processor/dump_context.cc \
src/processor/dump_object.cc \
@ -543,14 +524,11 @@ endif
src_client_linux_linux_client_unittest_shlib_DEPENDENCIES = \
src/client/linux/linux_dumper_unittest_helper \
src/client/linux/libbreakpad_client.a \
$(TEST_DEPS) \
src/libbreakpad.a
src_client_linux_linux_client_unittest_SOURCES =
# The extra-long build id is for a test in minidump_writer_unittest.cc.
src_client_linux_linux_client_unittest_LDFLAGS = \
-Wl,-rpath,'$$ORIGIN' \
-Wl,--build-id=0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
-Wl,-rpath,'$$ORIGIN'
if ANDROID_HOST
src_client_linux_linux_client_unittest_LDFLAGS += \
-llog
@ -581,12 +559,9 @@ src_tools_linux_dump_syms_dump_syms_SOURCES = \
src/common/dwarf/bytereader.cc \
src/common/dwarf/dwarf2diehandler.cc \
src/common/dwarf/dwarf2reader.cc \
src/common/dwarf/elf_reader.cc \
src/common/linux/crc32.cc \
src/common/linux/dump_symbols.cc \
src/common/linux/dump_symbols.h \
src/common/linux/elf_symbols_to_module.cc \
src/common/linux/elf_symbols_to_module.h \
src/common/linux/elfutils.cc \
src/common/linux/file_id.cc \
src/common/linux/linux_libc_support.cc \
@ -596,8 +571,7 @@ src_tools_linux_dump_syms_dump_syms_SOURCES = \
src_tools_linux_md2core_minidump_2_core_SOURCES = \
src/common/linux/memory_mapped_file.cc \
src/tools/linux/md2core/minidump-2-core.cc \
src/tools/linux/md2core/minidump_memory_range.h
src/tools/linux/md2core/minidump-2-core.cc
src_tools_linux_symupload_minidump_upload_SOURCES = \
src/common/linux/http_upload.cc \
@ -606,9 +580,6 @@ src_tools_linux_symupload_minidump_upload_LDADD = -ldl
src_tools_linux_symupload_sym_upload_SOURCES = \
src/common/linux/http_upload.cc \
src/common/linux/http_upload.h \
src/common/linux/symbol_upload.cc \
src/common/linux/symbol_upload.h \
src/tools/linux/symupload/sym_upload.cc
src_tools_linux_symupload_sym_upload_LDADD = -ldl
@ -624,20 +595,13 @@ src_tools_mac_dump_syms_dump_syms_mac_SOURCES = \
src/common/dwarf/bytereader.cc \
src/common/dwarf/dwarf2diehandler.cc \
src/common/dwarf/dwarf2reader.cc \
src/common/dwarf/elf_reader.cc \
src/common/mac/arch_utilities.cc \
src/common/mac/dump_syms.cc \
src/common/mac/dump_syms.h \
src/common/mac/file_id.cc \
src/common/mac/file_id.h \
src/common/mac/macho_id.cc \
src/common/mac/macho_id.h \
src/common/mac/macho_reader.cc \
src/common/mac/macho_reader.h \
src/common/mac/macho_utilities.cc \
src/common/mac/macho_utilities.h \
src/common/mac/macho_walker.cc \
src/common/mac/macho_walker.h \
src/tools/mac/dump_syms/dump_syms_tool.cc
src_tools_mac_dump_syms_dump_syms_mac_CXXFLAGS= \
-I$(top_srcdir)/src/third_party/mac_headers \
@ -661,20 +625,13 @@ src_common_dumper_unittest_SOURCES = \
src/common/stabs_to_module_unittest.cc \
src/common/test_assembler.cc \
src/common/dwarf/bytereader.cc \
src/common/dwarf/bytereader.h \
src/common/dwarf/bytereader-inl.h \
src/common/dwarf/bytereader_unittest.cc \
src/common/dwarf/cfi_assembler.cc \
src/common/dwarf/cfi_assembler.h \
src/common/dwarf/dwarf2diehandler.cc \
src/common/dwarf/dwarf2diehandler_unittest.cc \
src/common/dwarf/dwarf2reader.cc \
src/common/dwarf/dwarf2reader.h \
src/common/dwarf/elf_reader.cc \
src/common/dwarf/elf_reader.h \
src/common/dwarf/dwarf2reader_cfi_unittest.cc \
src/common/dwarf/dwarf2reader_die_unittest.cc \
src/common/dwarf/dwarf2reader_test_common.h \
src/common/linux/crc32.cc \
src/common/linux/dump_symbols.cc \
src/common/linux/dump_symbols_unittest.cc \
@ -693,8 +650,6 @@ src_common_dumper_unittest_SOURCES = \
src/common/linux/synth_elf.cc \
src/common/linux/synth_elf_unittest.cc \
src/common/linux/tests/crash_generator.cc \
src/common/linux/tests/crash_generator.h \
src/common/testdata/func-line-pairing.h \
src/common/tests/file_utils.cc
src_common_dumper_unittest_CPPFLAGS = \
$(AM_CPPFLAGS) $(TEST_CFLAGS) \
@ -717,7 +672,6 @@ src_common_mac_macho_reader_unittest_SOURCES = \
src/common/dwarf/cfi_assembler.cc \
src/common/dwarf/dwarf2diehandler.cc \
src/common/dwarf/dwarf2reader.cc \
src/common/dwarf/elf_reader.cc \
src/common/mac/arch_utilities.cc \
src/common/mac/file_id.cc \
src/common/mac/macho_id.cc \
@ -1017,16 +971,6 @@ src_processor_postfix_evaluator_unittest_LDADD = \
src/processor/pathname_stripper.o \
$(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
src_processor_range_map_shrink_down_unittest_SOURCES = \
src/processor/range_map_shrink_down_unittest.cc
src_processor_range_map_shrink_down_unittest_LDADD = \
src/processor/logging.o \
src/processor/pathname_stripper.o \
$(TEST_LIBS) \
$(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
src_processor_range_map_shrink_down_unittest_CPPFLAGS = \
$(AM_CPPFLAGS) $(TEST_CFLAGS)
src_processor_range_map_unittest_SOURCES = \
src/processor/range_map_unittest.cc
src_processor_range_map_unittest_LDADD = \
@ -1251,32 +1195,33 @@ endif !DISABLE_PROCESSOR
## sed -e s/'^\(.*\)$'/'\t\1 \\'/
EXTRA_DIST = \
$(SCRIPTS) \
src/client/linux/data/linux-gate-amd.sym \
src/client/linux/data/linux-gate-intel.sym \
src/client/mac/handler/breakpad_nlist_64.cc \
src/client/mac/handler/breakpad_nlist_64.h \
src/processor/stackwalk_selftest_sol.s \
src/client/linux/handler/Makefile \
src/client/linux/handler/exception_handler.cc \
src/client/linux/handler/exception_handler.h \
src/client/linux/handler/minidump_descriptor.cc \
src/client/linux/handler/minidump_descriptor.h \
src/client/linux/handler/exception_handler_test.cc \
src/client/linux/handler/linux_thread.cc \
src/client/linux/handler/linux_thread.h \
src/client/linux/handler/linux_thread_test.cc \
src/client/linux/handler/minidump_generator.cc \
src/client/linux/handler/minidump_generator.h \
src/client/linux/handler/minidump_test.cc \
src/client/mac/handler/dynamic_images.cc \
src/client/mac/handler/dynamic_images.h \
src/client/mac/handler/exception_handler.cc \
src/client/mac/handler/exception_handler.h \
src/client/mac/handler/mach_vm_compat.h \
src/client/mac/handler/exception_handler_test.cc \
src/client/mac/handler/minidump_generator.cc \
src/client/mac/handler/minidump_generator.h \
src/client/mac/handler/minidump_generator_test.cc \
src/client/mac/handler/minidump_test.xcodeproj/project.pbxproj \
src/client/mac/handler/minidump_tests32-Info.plist \
src/client/mac/handler/minidump_tests64-Info.plist \
src/client/mac/handler/obj-cTestCases-Info.plist \
src/client/mac/handler/protected_memory_allocator.cc \
src/client/mac/handler/protected_memory_allocator.h \
src/client/mac/handler/ucontext_compat.h \
src/client/mac/handler/testcases/testdata/dump_syms_i386_breakpad.sym \
src/client/mac/tests/BreakpadFramework_Test.mm \
src/client/mac/tests/crash_generation_server_test.cc \
src/client/mac/tests/exception_handler_test.cc \
src/client/mac/tests/minidump_generator_test.cc \
src/client/mac/tests/minidump_generator_test_helper.cc \
src/client/mac/tests/spawn_child_process.h \
src/client/mac/tests/testlogging.h \
src/client/minidump_file_writer-inl.h \
src/client/minidump_file_writer.cc \
src/client/minidump_file_writer.h \
src/client/minidump_file_writer_unittest.cc \
src/client/solaris/handler/Makefile \
src/client/solaris/handler/exception_handler.cc \
@ -1287,24 +1232,44 @@ EXTRA_DIST = \
src/client/solaris/handler/minidump_test.cc \
src/client/solaris/handler/solaris_lwp.cc \
src/client/solaris/handler/solaris_lwp.h \
src/client/windows/breakpad_client.gyp \
src/client/windows/breakpad_client.sln \
src/client/windows/handler/exception_handler.cc \
src/client/windows/handler/exception_handler.h \
src/client/windows/handler/exception_handler.gyp \
src/client/windows/handler/exception_handler.vcproj \
src/client/windows/sender/crash_report_sender.cc \
src/client/windows/sender/crash_report_sender.h \
src/client/windows/sender/crash_report_sender.gyp \
src/common/dwarf/dwarf2diehandler.h \
src/common/dwarf/dwarf2enums.h \
src/common/dwarf/line_state_machine.h \
src/common/dwarf/types.h \
src/common/mac/arch_utilities.h \
src/common/mac/byteswap.h \
src/client/windows/sender/crash_report_sender.vcproj \
src/common/convert_UTF.c \
src/common/convert_UTF.h \
src/common/linux/crc32.cc \
src/common/linux/dump_symbols.cc \
src/common/linux/dump_symbols.h \
src/common/linux/elf_symbols_to_module.cc \
src/common/linux/elf_symbols_to_module.h \
src/common/linux/elfutils.cc \
src/common/linux/elfutils.h \
src/common/linux/file_id.cc \
src/common/linux/file_id.h \
src/common/linux/guid_creator.cc \
src/common/linux/guid_creator.h \
src/common/linux/http_upload.cc \
src/common/linux/http_upload.h \
src/common/mac/HTTPMultipartUpload.h \
src/common/mac/HTTPMultipartUpload.m \
src/common/mac/dump_syms.h \
src/common/mac/dump_syms.cc \
src/common/mac/file_id.cc \
src/common/mac/file_id.h \
src/common/mac/macho_id.cc \
src/common/mac/macho_id.h \
src/common/mac/macho_utilities.cc \
src/common/mac/macho_utilities.h \
src/common/mac/macho_walker.cc \
src/common/mac/macho_walker.h \
src/common/mac/string_utilities.cc \
src/common/mac/string_utilities.h \
src/common/mac/super_fat_arch.h \
src/common/md5.cc \
src/common/md5.h \
src/common/scoped_ptr.h \
src/common/solaris/dump_symbols.cc \
src/common/solaris/dump_symbols.h \
@ -1313,6 +1278,8 @@ EXTRA_DIST = \
src/common/solaris/guid_creator.cc \
src/common/solaris/guid_creator.h \
src/common/solaris/message_output.h \
src/common/string_conversion.cc \
src/common/string_conversion.h \
src/common/windows/guid_string.cc \
src/common/windows/guid_string.h \
src/common/windows/http_upload.cc \
@ -1321,158 +1288,22 @@ EXTRA_DIST = \
src/common/windows/pdb_source_line_writer.h \
src/common/windows/string_utils-inl.h \
src/common/windows/string_utils.cc \
src/processor/stackwalk_common.cc \
src/processor/stackwalk_common.h \
src/processor/stackwalker_selftest_sol.s \
src/processor/testdata/ascii_read_av_block_write.dmp \
src/processor/testdata/ascii_read_av_clobber_write.dmp \
src/processor/testdata/ascii_read_av_conditional.dmp \
src/processor/testdata/ascii_read_av.dmp \
src/processor/testdata/ascii_read_av_then_jmp.dmp \
src/processor/testdata/ascii_read_av_xchg_write.dmp \
src/processor/testdata/ascii_write_av_arg_to_call.dmp \
src/processor/testdata/ascii_write_av.dmp \
src/processor/testdata/exec_av_on_stack.dmp \
src/processor/testdata/linux_divide_by_zero.dmp \
src/processor/testdata/linux_executable_heap.dmp \
src/processor/testdata/linux_executable_stack.dmp \
src/processor/testdata/linux_inside_module_exe_region1.dmp \
src/processor/testdata/linux_inside_module_exe_region2.dmp \
src/processor/testdata/linux_jmp_to_0.dmp \
src/processor/testdata/linux_jmp_to_module_not_exe_region.dmp \
src/processor/testdata/linux_null_dereference.dmp \
src/processor/testdata/linux_null_read_av.dmp \
src/processor/testdata/linux_outside_module.dmp \
src/processor/testdata/linux_overflow.dmp \
src/processor/testdata/linux_raise_sigabrt.dmp \
src/processor/testdata/linux_stack_pointer_in_module.dmp \
src/processor/testdata/linux_stack_pointer_in_stack.dmp \
src/processor/testdata/linux_stacksmash.dmp \
src/processor/testdata/linux_write_to_nonwritable_module.dmp \
src/processor/testdata/linux_write_to_nonwritable_region_math.dmp \
src/processor/testdata/linux_write_to_outside_module.dmp \
src/processor/testdata/linux_write_to_outside_module_via_math.dmp \
src/processor/testdata/linux_write_to_under_4k.dmp \
src/processor/testdata/microdump-arm64.dmp \
src/processor/testdata/microdump-arm.dmp \
src/processor/testdata/microdump-mips32.dmp \
src/processor/testdata/microdump-mips64.dmp \
src/processor/testdata/microdump-multiple.dmp \
src/processor/testdata/microdump.stackwalk-arm64.out \
src/processor/testdata/microdump.stackwalk-arm.out \
src/processor/testdata/microdump.stackwalk.machine_readable-arm64.out \
src/processor/testdata/microdump.stackwalk.machine_readable-arm.out \
src/processor/testdata/microdump-x86.dmp \
src/processor/testdata/minidump2.dmp \
src/processor/testdata/minidump2.dump.out \
src/processor/testdata/minidump2.stackwalk.machine_readable.out \
src/processor/testdata/minidump2.stackwalk.out \
src/processor/testdata/module0.out \
src/processor/testdata/module1.out \
src/processor/testdata/module2.out \
src/processor/testdata/module3_bad.out \
src/processor/testdata/module4_bad.out \
src/processor/testdata/null_read_av.dmp \
src/processor/testdata/null_write_av.dmp \
src/processor/testdata/read_av_clobber_write.dmp \
src/processor/testdata/read_av_conditional.dmp \
src/processor/testdata/read_av_non_null.dmp \
src/processor/testdata/stack_exhaustion.dmp \
src/processor/testdata/write_av_non_null.dmp \
src/processor/testdata/symbols/kernel32.pdb/BCE8785C57B44245A669896B6A19B9542/kernel32.sym \
src/processor/testdata/symbols/ld-2.13.so/C32AD7E235EA6112E02A5B9D6219C4850/ld-2.13.so.sym \
src/processor/testdata/symbols/libc-2.13.so/F4F8DFCD5A5FB5A7CE64717E9E6AE3890/libc-2.13.so.sym \
src/processor/testdata/symbols/libgcc_s.so.1/18B180F90887D8F8B5C35D185444AF4C0/libgcc_s.so.1.sym \
src/processor/testdata/symbols/microdump/breakpad_unittests/D6D1FEC9A15DE7F38A236898871A2E770/breakpad_unittests.sym \
src/processor/testdata/symbols/microdump/breakpad_unittests/DA7778FB66018A4E9B4110ED06E730D00/breakpad_unittests.sym \
src/processor/testdata/symbols/microdump/crash_example/6E72E2F1A5F59AB3D51356FDFE394D490/crash_example.sym \
src/processor/testdata/symbols/microdump/crash_example/8F36148CC4647A8116CAF2A25F591F570/crash_example.sym \
src/processor/testdata/symbols/null_read_av/7B7D1968FF0D47AE4366E9C3A7E1B6750/null_read_av.sym \
src/processor/testdata/symbols/overflow/B0E1FC01EF48E39CAF5C881D2DF0C3840/overflow.sym \
src/processor/testdata/symbols/test_app.pdb/5A9832E5287241C1838ED98914E9B7FF1/test_app.sym \
src/processor/testdata/test_app.cc \
src/testing/gtest/include/gtest/gtest.h \
src/testing/gtest/include/gtest/gtest-death-test.h \
src/testing/gtest/include/gtest/gtest-message.h \
src/testing/gtest/include/gtest/gtest-param-test.h \
src/testing/gtest/include/gtest/gtest-printers.h \
src/testing/gtest/include/gtest/gtest-spi.h \
src/testing/gtest/include/gtest/gtest-test-part.h \
src/testing/gtest/include/gtest/gtest-typed-test.h \
src/testing/gtest/include/gtest/gtest_pred_impl.h \
src/testing/gtest/include/gtest/gtest_prod.h \
src/testing/gtest/include/gtest/internal/gtest-death-test-internal.h \
src/testing/gtest/include/gtest/internal/gtest-filepath.h \
src/testing/gtest/include/gtest/internal/gtest-internal.h \
src/testing/gtest/include/gtest/internal/gtest-linked_ptr.h \
src/testing/gtest/include/gtest/internal/gtest-param-util-generated.h \
src/testing/gtest/include/gtest/internal/gtest-param-util.h \
src/testing/gtest/include/gtest/internal/gtest-port.h \
src/testing/gtest/include/gtest/internal/gtest-string.h \
src/testing/gtest/include/gtest/internal/gtest-tuple.h \
src/testing/gtest/include/gtest/internal/gtest-type-util.h \
src/testing/gtest/src/gtest.cc \
src/testing/gtest/src/gtest-death-test.cc \
src/testing/gtest/src/gtest-filepath.cc \
src/testing/gtest/src/gtest-internal-inl.h \
src/testing/gtest/src/gtest-port.cc \
src/testing/gtest/src/gtest-printers.cc \
src/testing/gtest/src/gtest-test-part.cc \
src/testing/gtest/src/gtest-typed-test.cc \
src/testing/include/gmock/gmock.h \
src/testing/include/gmock/gmock-actions.h \
src/testing/include/gmock/gmock-cardinalities.h \
src/testing/include/gmock/gmock-generated-actions.h \
src/testing/include/gmock/gmock-generated-function-mockers.h \
src/testing/include/gmock/gmock-generated-matchers.h \
src/testing/include/gmock/gmock-generated-nice-strict.h \
src/testing/include/gmock/gmock-matchers.h \
src/testing/include/gmock/gmock-more-actions.h \
src/testing/include/gmock/gmock-more-matchers.h \
src/testing/include/gmock/gmock-spec-builders.h \
src/testing/include/gmock/internal/gmock-generated-internal-utils.h \
src/testing/include/gmock/internal/gmock-internal-utils.h \
src/testing/include/gmock/internal/gmock-port.h \
src/testing/src/gmock.cc \
src/testing/src/gmock-cardinalities.cc \
src/testing/src/gmock-internal-utils.cc \
src/testing/src/gmock-matchers.cc \
src/testing/src/gmock-spec-builders.cc \
src/testing/src/gmock_main.cc \
src/third_party/curl/COPYING \
src/third_party/curl/curlbuild.h \
src/third_party/curl/curl.h \
src/third_party/curl/curlrules.h \
src/third_party/curl/curlver.h \
src/third_party/curl/easy.h \
src/third_party/curl/mprintf.h \
src/third_party/curl/multi.h \
src/third_party/curl/stdcheaders.h \
src/third_party/curl/typecheck-gcc.h \
src/third_party/curl/types.h \
src/third_party/mac_headers/architecture/byte_order.h \
src/third_party/mac_headers/i386/_types.h \
src/third_party/mac_headers/mach/boolean.h \
src/third_party/mac_headers/mach/i386/boolean.h \
src/third_party/mac_headers/mach/i386/vm_param.h \
src/third_party/mac_headers/mach/i386/vm_types.h \
src/third_party/mac_headers/mach/machine/boolean.h \
src/third_party/mac_headers/mach/machine.h \
src/third_party/mac_headers/mach/machine/thread_state.h \
src/third_party/mac_headers/mach/machine/thread_status.h \
src/third_party/mac_headers/mach/machine/vm_types.h \
src/third_party/mac_headers/mach-o/arch.h \
src/third_party/mac_headers/mach-o/fat.h \
src/third_party/mac_headers/mach-o/loader.h \
src/third_party/mac_headers/mach-o/nlist.h \
src/third_party/mac_headers/mach/thread_status.h \
src/third_party/mac_headers/mach/vm_prot.h \
src/third_party/mac_headers/README \
src/third_party/musl/README \
src/third_party/musl/COPYRIGHT \
src/third_party/musl/README.breakpad \
src/third_party/musl/VERSION \
src/third_party/musl/include/elf.h \
src/tools/linux/dump_syms/Makefile \
src/tools/linux/dump_syms/dump_syms.cc \
src/tools/linux/symupload/Makefile \
src/tools/linux/symupload/minidump_upload.cc \
src/tools/linux/symupload/sym_upload.cc \
src/tools/mac/crash_report/crash_report.mm \
src/tools/mac/crash_report/crash_report.xcodeproj/project.pbxproj \
src/tools/mac/crash_report/on_demand_symbol_supplier.h \
@ -1491,20 +1322,15 @@ EXTRA_DIST = \
src/tools/solaris/dump_syms/testdata/dump_syms_regtest.sym \
src/tools/windows/converter/ms_symbol_server_converter.cc \
src/tools/windows/converter/ms_symbol_server_converter.h \
src/tools/windows/converter/ms_symbol_server_converter.gyp \
src/tools/windows/converter/ms_symbol_server_converter.vcproj \
src/tools/windows/dump_syms/dump_syms.cc \
src/tools/windows/dump_syms/dump_syms.gyp \
src/tools/windows/dump_syms/dump_syms.vcproj \
src/tools/windows/dump_syms/run_regtest.sh \
src/tools/windows/dump_syms/testdata/dump_syms_regtest.cc \
src/tools/windows/dump_syms/testdata/dump_syms_regtest.pdb \
src/tools/windows/dump_syms/testdata/dump_syms_regtest.sym \
src/tools/windows/dump_syms/testdata/dump_syms_regtest64.sym \
src/tools/windows/dump_syms/testdata/omap_reorder_bbs.sym \
src/tools/windows/dump_syms/testdata/omap_reorder_funcs.sym \
src/tools/windows/dump_syms/testdata/omap_stretched.sym \
src/tools/windows/dump_syms/testdata/omap_stretched_filled.sym \
src/tools/windows/symupload/symupload.cc \
src/tools/windows/symupload/symupload.gyp
src/tools/windows/symupload/symupload.vcproj
mostlyclean-local:
-find src -name '*.dwo' -exec rm -f {} +

View File

@ -194,7 +194,6 @@ EXTRA_PROGRAMS = $(am__EXEEXT_1)
@DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper_unittest \
@DISABLE_PROCESSOR_FALSE@ src/processor/postfix_evaluator_unittest \
@DISABLE_PROCESSOR_FALSE@ src/processor/proc_maps_linux_unittest \
@DISABLE_PROCESSOR_FALSE@ src/processor/range_map_shrink_down_unittest \
@DISABLE_PROCESSOR_FALSE@ src/processor/range_map_unittest \
@DISABLE_PROCESSOR_FALSE@ src/processor/stackwalker_amd64_unittest \
@DISABLE_PROCESSOR_FALSE@ src/processor/stackwalker_arm_unittest \
@ -299,25 +298,17 @@ am__src_client_linux_libbreakpad_client_a_SOURCES_DIST = \
src/client/linux/dump_writer_common/thread_info.cc \
src/client/linux/dump_writer_common/ucontext_reader.cc \
src/client/linux/handler/exception_handler.cc \
src/client/linux/handler/exception_handler.h \
src/client/linux/handler/minidump_descriptor.cc \
src/client/linux/handler/minidump_descriptor.h \
src/client/linux/log/log.cc src/client/linux/log/log.h \
src/client/linux/log/log.cc \
src/client/linux/microdump_writer/microdump_writer.cc \
src/client/linux/microdump_writer/microdump_writer.h \
src/client/linux/minidump_writer/linux_core_dumper.cc \
src/client/linux/minidump_writer/linux_dumper.cc \
src/client/linux/minidump_writer/linux_ptrace_dumper.cc \
src/client/linux/minidump_writer/minidump_writer.cc \
src/client/minidump_file_writer-inl.h \
src/client/minidump_file_writer.cc \
src/client/minidump_file_writer.h src/common/convert_UTF.c \
src/common/convert_UTF.h src/common/md5.cc src/common/md5.h \
src/common/string_conversion.cc src/common/string_conversion.h \
src/client/minidump_file_writer.cc src/common/convert_UTF.c \
src/common/md5.cc src/common/string_conversion.cc \
src/common/linux/elf_core_dump.cc src/common/linux/elfutils.cc \
src/common/linux/elfutils.h src/common/linux/file_id.cc \
src/common/linux/file_id.h src/common/linux/guid_creator.cc \
src/common/linux/guid_creator.h \
src/common/linux/file_id.cc src/common/linux/guid_creator.cc \
src/common/linux/linux_libc_support.cc \
src/common/linux/memory_mapped_file.cc \
src/common/linux/safe_readlink.cc \
@ -497,7 +488,6 @@ src_libbreakpad_a_OBJECTS = $(am_src_libbreakpad_a_OBJECTS)
src_testing_libtesting_a_AR = $(AR) $(ARFLAGS)
src_testing_libtesting_a_LIBADD =
am__src_testing_libtesting_a_SOURCES_DIST = \
src/breakpad_googletest_includes.h \
src/testing/gtest/src/gtest-all.cc \
src/testing/gtest/src/gtest_main.cc \
src/testing/src/gmock-all.cc
@ -581,7 +571,6 @@ src_third_party_libdisasm_libdisasm_a_OBJECTS = \
@DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper_unittest$(EXEEXT) \
@DISABLE_PROCESSOR_FALSE@ src/processor/postfix_evaluator_unittest$(EXEEXT) \
@DISABLE_PROCESSOR_FALSE@ src/processor/proc_maps_linux_unittest$(EXEEXT) \
@DISABLE_PROCESSOR_FALSE@ src/processor/range_map_shrink_down_unittest$(EXEEXT) \
@DISABLE_PROCESSOR_FALSE@ src/processor/range_map_unittest$(EXEEXT) \
@DISABLE_PROCESSOR_FALSE@ src/processor/stackwalker_amd64_unittest$(EXEEXT) \
@DISABLE_PROCESSOR_FALSE@ src/processor/stackwalker_arm_unittest$(EXEEXT) \
@ -608,7 +597,6 @@ src_client_linux_linux_client_unittest_LINK = $(CCLD) $(AM_CFLAGS) \
$(CFLAGS) $(src_client_linux_linux_client_unittest_LDFLAGS) \
$(LDFLAGS) -o $@
am__src_client_linux_linux_client_unittest_shlib_SOURCES_DIST = \
src/breakpad_googletest_includes.h \
src/testing/gtest/src/gtest-all.cc \
src/testing/gtest/src/gtest_main.cc \
src/testing/src/gmock-all.cc \
@ -624,10 +612,8 @@ am__src_client_linux_linux_client_unittest_shlib_SOURCES_DIST = \
src/client/linux/minidump_writer/proc_cpuinfo_reader_unittest.cc \
src/common/linux/elf_core_dump.cc \
src/common/linux/linux_libc_support_unittest.cc \
src/common/linux/tests/auto_testfile.h \
src/common/linux/tests/crash_generator.cc \
src/common/memory_unittest.cc src/common/tests/auto_tempdir.h \
src/common/tests/file_utils.cc src/common/tests/file_utils.h \
src/common/memory_unittest.cc src/common/tests/file_utils.cc \
src/processor/basic_code_modules.cc \
src/processor/dump_context.cc src/processor/dump_object.cc \
src/processor/logging.cc src/processor/minidump.cc \
@ -698,19 +684,13 @@ am__src_common_dumper_unittest_SOURCES_DIST = \
src/common/stabs_to_module.cc \
src/common/stabs_to_module_unittest.cc \
src/common/test_assembler.cc src/common/dwarf/bytereader.cc \
src/common/dwarf/bytereader.h \
src/common/dwarf/bytereader-inl.h \
src/common/dwarf/bytereader_unittest.cc \
src/common/dwarf/cfi_assembler.cc \
src/common/dwarf/cfi_assembler.h \
src/common/dwarf/dwarf2diehandler.cc \
src/common/dwarf/dwarf2diehandler_unittest.cc \
src/common/dwarf/dwarf2reader.cc \
src/common/dwarf/dwarf2reader.h src/common/dwarf/elf_reader.cc \
src/common/dwarf/elf_reader.h \
src/common/dwarf/dwarf2reader_cfi_unittest.cc \
src/common/dwarf/dwarf2reader_die_unittest.cc \
src/common/dwarf/dwarf2reader_test_common.h \
src/common/linux/crc32.cc src/common/linux/dump_symbols.cc \
src/common/linux/dump_symbols_unittest.cc \
src/common/linux/elf_core_dump.cc \
@ -727,8 +707,6 @@ am__src_common_dumper_unittest_SOURCES_DIST = \
src/common/linux/synth_elf.cc \
src/common/linux/synth_elf_unittest.cc \
src/common/linux/tests/crash_generator.cc \
src/common/linux/tests/crash_generator.h \
src/common/testdata/func-line-pairing.h \
src/common/tests/file_utils.cc
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@am_src_common_dumper_unittest_OBJECTS = src/common/src_common_dumper_unittest-byte_cursor_unittest.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/src_common_dumper_unittest-dwarf_cfi_to_module.$(OBJEXT) \
@ -752,7 +730,6 @@ am__src_common_dumper_unittest_SOURCES_DIST = \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_common_dumper_unittest-dwarf2diehandler.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_common_dumper_unittest-dwarf2diehandler_unittest.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_common_dumper_unittest-dwarf2reader.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_common_dumper_unittest-elf_reader.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_common_dumper_unittest-dwarf2reader_cfi_unittest.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_common_dumper_unittest-dwarf2reader_die_unittest.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/src_common_dumper_unittest-crc32.$(OBJEXT) \
@ -790,7 +767,6 @@ am__src_common_mac_macho_reader_unittest_SOURCES_DIST = \
src/common/dwarf/cfi_assembler.cc \
src/common/dwarf/dwarf2diehandler.cc \
src/common/dwarf/dwarf2reader.cc \
src/common/dwarf/elf_reader.cc \
src/common/mac/arch_utilities.cc src/common/mac/file_id.cc \
src/common/mac/macho_id.cc src/common/mac/macho_reader.cc \
src/common/mac/macho_reader_unittest.cc \
@ -809,7 +785,6 @@ am__src_common_mac_macho_reader_unittest_SOURCES_DIST = \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_common_mac_macho_reader_unittest-cfi_assembler.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_common_mac_macho_reader_unittest-dwarf2diehandler.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_common_mac_macho_reader_unittest-dwarf2reader.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_common_mac_macho_reader_unittest-elf_reader.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/mac/src_common_mac_macho_reader_unittest-arch_utilities.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/mac/src_common_mac_macho_reader_unittest-file_id.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/mac/src_common_mac_macho_reader_unittest-macho_id.$(OBJEXT) \
@ -1172,17 +1147,6 @@ src_processor_proc_maps_linux_unittest_OBJECTS = \
@DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_2) \
@DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_1) \
@DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_1)
am__src_processor_range_map_shrink_down_unittest_SOURCES_DIST = \
src/processor/range_map_shrink_down_unittest.cc
@DISABLE_PROCESSOR_FALSE@am_src_processor_range_map_shrink_down_unittest_OBJECTS = src/processor/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.$(OBJEXT)
src_processor_range_map_shrink_down_unittest_OBJECTS = \
$(am_src_processor_range_map_shrink_down_unittest_OBJECTS)
@DISABLE_PROCESSOR_FALSE@src_processor_range_map_shrink_down_unittest_DEPENDENCIES = \
@DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \
@DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \
@DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_2) \
@DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_1) \
@DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_1)
am__src_processor_range_map_unittest_SOURCES_DIST = \
src/processor/range_map_unittest.cc
@DISABLE_PROCESSOR_FALSE@am_src_processor_range_map_unittest_OBJECTS = src/processor/range_map_unittest.$(OBJEXT)
@ -1379,12 +1343,9 @@ am__src_tools_linux_dump_syms_dump_syms_SOURCES_DIST = \
src/common/module.cc src/common/stabs_reader.cc \
src/common/stabs_to_module.cc src/common/dwarf/bytereader.cc \
src/common/dwarf/dwarf2diehandler.cc \
src/common/dwarf/dwarf2reader.cc \
src/common/dwarf/elf_reader.cc src/common/linux/crc32.cc \
src/common/dwarf/dwarf2reader.cc src/common/linux/crc32.cc \
src/common/linux/dump_symbols.cc \
src/common/linux/dump_symbols.h \
src/common/linux/elf_symbols_to_module.cc \
src/common/linux/elf_symbols_to_module.h \
src/common/linux/elfutils.cc src/common/linux/file_id.cc \
src/common/linux/linux_libc_support.cc \
src/common/linux/memory_mapped_file.cc \
@ -1400,7 +1361,6 @@ am__src_tools_linux_dump_syms_dump_syms_SOURCES_DIST = \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/bytereader.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2diehandler.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2reader.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/elf_reader.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/crc32.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/dump_symbols.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/elf_symbols_to_module.$(OBJEXT) \
@ -1415,8 +1375,7 @@ src_tools_linux_dump_syms_dump_syms_OBJECTS = \
src_tools_linux_dump_syms_dump_syms_LDADD = $(LDADD)
am__src_tools_linux_md2core_minidump_2_core_SOURCES_DIST = \
src/common/linux/memory_mapped_file.cc \
src/tools/linux/md2core/minidump-2-core.cc \
src/tools/linux/md2core/minidump_memory_range.h
src/tools/linux/md2core/minidump-2-core.cc
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@am_src_tools_linux_md2core_minidump_2_core_OBJECTS = src/common/linux/memory_mapped_file.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/tools/linux/md2core/minidump-2-core.$(OBJEXT)
src_tools_linux_md2core_minidump_2_core_OBJECTS = \
@ -1438,12 +1397,9 @@ src_tools_linux_symupload_minidump_upload_OBJECTS = \
$(am_src_tools_linux_symupload_minidump_upload_OBJECTS)
src_tools_linux_symupload_minidump_upload_DEPENDENCIES =
am__src_tools_linux_symupload_sym_upload_SOURCES_DIST = \
src/common/linux/http_upload.cc src/common/linux/http_upload.h \
src/common/linux/symbol_upload.cc \
src/common/linux/symbol_upload.h \
src/common/linux/http_upload.cc \
src/tools/linux/symupload/sym_upload.cc
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@am_src_tools_linux_symupload_sym_upload_OBJECTS = src/common/linux/http_upload.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/symbol_upload.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/tools/linux/symupload/sym_upload.$(OBJEXT)
src_tools_linux_symupload_sym_upload_OBJECTS = \
$(am_src_tools_linux_symupload_sym_upload_OBJECTS)
@ -1457,15 +1413,11 @@ am__src_tools_mac_dump_syms_dump_syms_mac_SOURCES_DIST = \
src/common/dwarf/bytereader.cc \
src/common/dwarf/dwarf2diehandler.cc \
src/common/dwarf/dwarf2reader.cc \
src/common/dwarf/elf_reader.cc \
src/common/mac/arch_utilities.cc src/common/mac/dump_syms.cc \
src/common/mac/dump_syms.h src/common/mac/file_id.cc \
src/common/mac/file_id.h src/common/mac/macho_id.cc \
src/common/mac/macho_id.h src/common/mac/macho_reader.cc \
src/common/mac/macho_reader.h \
src/common/mac/file_id.cc src/common/mac/macho_id.cc \
src/common/mac/macho_reader.cc \
src/common/mac/macho_utilities.cc \
src/common/mac/macho_utilities.h \
src/common/mac/macho_walker.cc src/common/mac/macho_walker.h \
src/common/mac/macho_walker.cc \
src/tools/mac/dump_syms/dump_syms_tool.cc
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@am_src_tools_mac_dump_syms_dump_syms_mac_OBJECTS = src/common/src_tools_mac_dump_syms_dump_syms_mac-dwarf_cfi_to_module.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/src_tools_mac_dump_syms_dump_syms_mac-dwarf_cu_to_module.$(OBJEXT) \
@ -1478,7 +1430,6 @@ am__src_tools_mac_dump_syms_dump_syms_mac_SOURCES_DIST = \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_tools_mac_dump_syms_dump_syms_mac-bytereader.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_tools_mac_dump_syms_dump_syms_mac-dwarf2diehandler.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_tools_mac_dump_syms_dump_syms_mac-dwarf2reader.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/src_tools_mac_dump_syms_dump_syms_mac-elf_reader.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/mac/src_tools_mac_dump_syms_dump_syms_mac-arch_utilities.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/mac/src_tools_mac_dump_syms_dump_syms_mac-dump_syms.$(OBJEXT) \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/mac/src_tools_mac_dump_syms_dump_syms_mac-file_id.$(OBJEXT) \
@ -1572,7 +1523,6 @@ SOURCES = $(src_client_linux_libbreakpad_client_a_SOURCES) \
$(src_processor_pathname_stripper_unittest_SOURCES) \
$(src_processor_postfix_evaluator_unittest_SOURCES) \
$(src_processor_proc_maps_linux_unittest_SOURCES) \
$(src_processor_range_map_shrink_down_unittest_SOURCES) \
$(src_processor_range_map_unittest_SOURCES) \
$(src_processor_stackwalker_address_list_unittest_SOURCES) \
$(src_processor_stackwalker_amd64_unittest_SOURCES) \
@ -1622,7 +1572,6 @@ DIST_SOURCES = \
$(am__src_processor_pathname_stripper_unittest_SOURCES_DIST) \
$(am__src_processor_postfix_evaluator_unittest_SOURCES_DIST) \
$(am__src_processor_proc_maps_linux_unittest_SOURCES_DIST) \
$(am__src_processor_range_map_shrink_down_unittest_SOURCES_DIST) \
$(am__src_processor_range_map_unittest_SOURCES_DIST) \
$(am__src_processor_stackwalker_address_list_unittest_SOURCES_DIST) \
$(am__src_processor_stackwalker_amd64_unittest_SOURCES_DIST) \
@ -2056,14 +2005,11 @@ pkgconfig_DATA = $(am__append_6) $(am__append_9)
@SYSTEM_TEST_LIBS_TRUE@TEST_CFLAGS = $(GTEST_CFLAGS) $(GMOCK_CFLAGS)
@SYSTEM_TEST_LIBS_FALSE@TEST_LIBS = src/testing/libtesting.a
@SYSTEM_TEST_LIBS_TRUE@TEST_LIBS = $(GTEST_LIBS) -lgtest_main $(GMOCK_LIBS)
@SYSTEM_TEST_LIBS_FALSE@TEST_DEPS = $(TEST_LIBS)
@SYSTEM_TEST_LIBS_TRUE@TEST_DEPS =
check_LIBRARIES = src/testing/libtesting.a
noinst_LIBRARIES = $(am__append_7)
lib_LIBRARIES = $(am__append_5) $(am__append_8)
CLEANFILES = $(am__append_13)
@SYSTEM_TEST_LIBS_FALSE@src_testing_libtesting_a_SOURCES = \
@SYSTEM_TEST_LIBS_FALSE@ src/breakpad_googletest_includes.h \
@SYSTEM_TEST_LIBS_FALSE@ src/testing/gtest/src/gtest-all.cc \
@SYSTEM_TEST_LIBS_FALSE@ src/testing/gtest/src/gtest_main.cc \
@SYSTEM_TEST_LIBS_FALSE@ src/testing/src/gmock-all.cc
@ -2076,32 +2022,20 @@ CLEANFILES = $(am__append_13)
@LINUX_HOST_TRUE@ src/client/linux/dump_writer_common/thread_info.cc \
@LINUX_HOST_TRUE@ src/client/linux/dump_writer_common/ucontext_reader.cc \
@LINUX_HOST_TRUE@ src/client/linux/handler/exception_handler.cc \
@LINUX_HOST_TRUE@ src/client/linux/handler/exception_handler.h \
@LINUX_HOST_TRUE@ src/client/linux/handler/minidump_descriptor.cc \
@LINUX_HOST_TRUE@ src/client/linux/handler/minidump_descriptor.h \
@LINUX_HOST_TRUE@ src/client/linux/log/log.cc \
@LINUX_HOST_TRUE@ src/client/linux/log/log.h \
@LINUX_HOST_TRUE@ src/client/linux/microdump_writer/microdump_writer.cc \
@LINUX_HOST_TRUE@ src/client/linux/microdump_writer/microdump_writer.h \
@LINUX_HOST_TRUE@ src/client/linux/minidump_writer/linux_core_dumper.cc \
@LINUX_HOST_TRUE@ src/client/linux/minidump_writer/linux_dumper.cc \
@LINUX_HOST_TRUE@ src/client/linux/minidump_writer/linux_ptrace_dumper.cc \
@LINUX_HOST_TRUE@ src/client/linux/minidump_writer/minidump_writer.cc \
@LINUX_HOST_TRUE@ src/client/minidump_file_writer-inl.h \
@LINUX_HOST_TRUE@ src/client/minidump_file_writer.cc \
@LINUX_HOST_TRUE@ src/client/minidump_file_writer.h \
@LINUX_HOST_TRUE@ src/common/convert_UTF.c \
@LINUX_HOST_TRUE@ src/common/convert_UTF.h src/common/md5.cc \
@LINUX_HOST_TRUE@ src/common/md5.h \
@LINUX_HOST_TRUE@ src/common/convert_UTF.c src/common/md5.cc \
@LINUX_HOST_TRUE@ src/common/string_conversion.cc \
@LINUX_HOST_TRUE@ src/common/string_conversion.h \
@LINUX_HOST_TRUE@ src/common/linux/elf_core_dump.cc \
@LINUX_HOST_TRUE@ src/common/linux/elfutils.cc \
@LINUX_HOST_TRUE@ src/common/linux/elfutils.h \
@LINUX_HOST_TRUE@ src/common/linux/file_id.cc \
@LINUX_HOST_TRUE@ src/common/linux/file_id.h \
@LINUX_HOST_TRUE@ src/common/linux/guid_creator.cc \
@LINUX_HOST_TRUE@ src/common/linux/guid_creator.h \
@LINUX_HOST_TRUE@ src/common/linux/linux_libc_support.cc \
@LINUX_HOST_TRUE@ src/common/linux/memory_mapped_file.cc \
@LINUX_HOST_TRUE@ src/common/linux/safe_readlink.cc \
@ -2289,12 +2223,9 @@ TESTS = $(check_PROGRAMS) $(check_SCRIPTS)
@LINUX_HOST_TRUE@ src/client/linux/minidump_writer/proc_cpuinfo_reader_unittest.cc \
@LINUX_HOST_TRUE@ src/common/linux/elf_core_dump.cc \
@LINUX_HOST_TRUE@ src/common/linux/linux_libc_support_unittest.cc \
@LINUX_HOST_TRUE@ src/common/linux/tests/auto_testfile.h \
@LINUX_HOST_TRUE@ src/common/linux/tests/crash_generator.cc \
@LINUX_HOST_TRUE@ src/common/memory_unittest.cc \
@LINUX_HOST_TRUE@ src/common/tests/auto_tempdir.h \
@LINUX_HOST_TRUE@ src/common/tests/file_utils.cc \
@LINUX_HOST_TRUE@ src/common/tests/file_utils.h \
@LINUX_HOST_TRUE@ src/processor/basic_code_modules.cc \
@LINUX_HOST_TRUE@ src/processor/dump_context.cc \
@LINUX_HOST_TRUE@ src/processor/dump_object.cc \
@ -2338,15 +2269,11 @@ TESTS = $(check_PROGRAMS) $(check_SCRIPTS)
@LINUX_HOST_TRUE@src_client_linux_linux_client_unittest_shlib_DEPENDENCIES = \
@LINUX_HOST_TRUE@ src/client/linux/linux_dumper_unittest_helper \
@LINUX_HOST_TRUE@ src/client/linux/libbreakpad_client.a \
@LINUX_HOST_TRUE@ $(TEST_DEPS) \
@LINUX_HOST_TRUE@ src/libbreakpad.a
@LINUX_HOST_TRUE@src_client_linux_linux_client_unittest_SOURCES =
# The extra-long build id is for a test in minidump_writer_unittest.cc.
@LINUX_HOST_TRUE@src_client_linux_linux_client_unittest_LDFLAGS = \
@LINUX_HOST_TRUE@ -Wl,-rpath,'$$ORIGIN' \
@LINUX_HOST_TRUE@ -Wl,--build-id=0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f \
@LINUX_HOST_TRUE@ $(am__append_24)
@LINUX_HOST_TRUE@ -Wl,-rpath,'$$ORIGIN' $(am__append_24)
@LINUX_HOST_TRUE@src_client_linux_linux_client_unittest_LDADD = \
@LINUX_HOST_TRUE@ src/client/linux/linux_client_unittest_shlib \
@LINUX_HOST_TRUE@ $(TEST_LIBS)
@ -2371,12 +2298,9 @@ TESTS = $(check_PROGRAMS) $(check_SCRIPTS)
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/bytereader.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2diehandler.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2reader.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/elf_reader.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/crc32.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/dump_symbols.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/dump_symbols.h \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/elf_symbols_to_module.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/elf_symbols_to_module.h \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/elfutils.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/file_id.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/linux_libc_support.cc \
@ -2386,8 +2310,7 @@ TESTS = $(check_PROGRAMS) $(check_SCRIPTS)
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@src_tools_linux_md2core_minidump_2_core_SOURCES = \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/memory_mapped_file.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/tools/linux/md2core/minidump-2-core.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/tools/linux/md2core/minidump_memory_range.h
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/tools/linux/md2core/minidump-2-core.cc
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@src_tools_linux_symupload_minidump_upload_SOURCES = \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/http_upload.cc \
@ -2396,9 +2319,6 @@ TESTS = $(check_PROGRAMS) $(check_SCRIPTS)
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@src_tools_linux_symupload_minidump_upload_LDADD = -ldl
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@src_tools_linux_symupload_sym_upload_SOURCES = \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/http_upload.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/http_upload.h \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/symbol_upload.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/symbol_upload.h \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/tools/linux/symupload/sym_upload.cc
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@src_tools_linux_symupload_sym_upload_LDADD = -ldl
@ -2414,20 +2334,13 @@ TESTS = $(check_PROGRAMS) $(check_SCRIPTS)
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/bytereader.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2diehandler.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2reader.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/elf_reader.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/mac/arch_utilities.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/mac/dump_syms.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/mac/dump_syms.h \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/mac/file_id.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/mac/file_id.h \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/mac/macho_id.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/mac/macho_id.h \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/mac/macho_reader.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/mac/macho_reader.h \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/mac/macho_utilities.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/mac/macho_utilities.h \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/mac/macho_walker.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/mac/macho_walker.h \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/tools/mac/dump_syms/dump_syms_tool.cc
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@src_tools_mac_dump_syms_dump_syms_mac_CXXFLAGS = \
@ -2452,20 +2365,13 @@ TESTS = $(check_PROGRAMS) $(check_SCRIPTS)
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/stabs_to_module_unittest.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/test_assembler.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/bytereader.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/bytereader.h \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/bytereader-inl.h \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/bytereader_unittest.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/cfi_assembler.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/cfi_assembler.h \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2diehandler.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2diehandler_unittest.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2reader.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2reader.h \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/elf_reader.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/elf_reader.h \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2reader_cfi_unittest.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2reader_die_unittest.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2reader_test_common.h \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/crc32.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/dump_symbols.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/dump_symbols_unittest.cc \
@ -2484,8 +2390,6 @@ TESTS = $(check_PROGRAMS) $(check_SCRIPTS)
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/synth_elf.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/synth_elf_unittest.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/tests/crash_generator.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/tests/crash_generator.h \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/testdata/func-line-pairing.h \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/tests/file_utils.cc
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@src_common_dumper_unittest_CPPFLAGS = \
@ -2510,7 +2414,6 @@ TESTS = $(check_PROGRAMS) $(check_SCRIPTS)
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/cfi_assembler.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2diehandler.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2reader.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/elf_reader.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/mac/arch_utilities.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/mac/file_id.cc \
@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/mac/macho_id.cc \
@ -2842,18 +2745,6 @@ TESTS = $(check_PROGRAMS) $(check_SCRIPTS)
@DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \
@DISABLE_PROCESSOR_FALSE@ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
@DISABLE_PROCESSOR_FALSE@src_processor_range_map_shrink_down_unittest_SOURCES = \
@DISABLE_PROCESSOR_FALSE@ src/processor/range_map_shrink_down_unittest.cc
@DISABLE_PROCESSOR_FALSE@src_processor_range_map_shrink_down_unittest_LDADD = \
@DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \
@DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \
@DISABLE_PROCESSOR_FALSE@ $(TEST_LIBS) \
@DISABLE_PROCESSOR_FALSE@ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
@DISABLE_PROCESSOR_FALSE@src_processor_range_map_shrink_down_unittest_CPPFLAGS = \
@DISABLE_PROCESSOR_FALSE@ $(AM_CPPFLAGS) $(TEST_CFLAGS)
@DISABLE_PROCESSOR_FALSE@src_processor_range_map_unittest_SOURCES = \
@DISABLE_PROCESSOR_FALSE@ src/processor/range_map_unittest.cc
@ -3091,32 +2982,33 @@ TESTS = $(check_PROGRAMS) $(check_SCRIPTS)
EXTRA_DIST = \
$(SCRIPTS) \
src/client/linux/data/linux-gate-amd.sym \
src/client/linux/data/linux-gate-intel.sym \
src/client/mac/handler/breakpad_nlist_64.cc \
src/client/mac/handler/breakpad_nlist_64.h \
src/processor/stackwalk_selftest_sol.s \
src/client/linux/handler/Makefile \
src/client/linux/handler/exception_handler.cc \
src/client/linux/handler/exception_handler.h \
src/client/linux/handler/minidump_descriptor.cc \
src/client/linux/handler/minidump_descriptor.h \
src/client/linux/handler/exception_handler_test.cc \
src/client/linux/handler/linux_thread.cc \
src/client/linux/handler/linux_thread.h \
src/client/linux/handler/linux_thread_test.cc \
src/client/linux/handler/minidump_generator.cc \
src/client/linux/handler/minidump_generator.h \
src/client/linux/handler/minidump_test.cc \
src/client/mac/handler/dynamic_images.cc \
src/client/mac/handler/dynamic_images.h \
src/client/mac/handler/exception_handler.cc \
src/client/mac/handler/exception_handler.h \
src/client/mac/handler/mach_vm_compat.h \
src/client/mac/handler/exception_handler_test.cc \
src/client/mac/handler/minidump_generator.cc \
src/client/mac/handler/minidump_generator.h \
src/client/mac/handler/minidump_generator_test.cc \
src/client/mac/handler/minidump_test.xcodeproj/project.pbxproj \
src/client/mac/handler/minidump_tests32-Info.plist \
src/client/mac/handler/minidump_tests64-Info.plist \
src/client/mac/handler/obj-cTestCases-Info.plist \
src/client/mac/handler/protected_memory_allocator.cc \
src/client/mac/handler/protected_memory_allocator.h \
src/client/mac/handler/ucontext_compat.h \
src/client/mac/handler/testcases/testdata/dump_syms_i386_breakpad.sym \
src/client/mac/tests/BreakpadFramework_Test.mm \
src/client/mac/tests/crash_generation_server_test.cc \
src/client/mac/tests/exception_handler_test.cc \
src/client/mac/tests/minidump_generator_test.cc \
src/client/mac/tests/minidump_generator_test_helper.cc \
src/client/mac/tests/spawn_child_process.h \
src/client/mac/tests/testlogging.h \
src/client/minidump_file_writer-inl.h \
src/client/minidump_file_writer.cc \
src/client/minidump_file_writer.h \
src/client/minidump_file_writer_unittest.cc \
src/client/solaris/handler/Makefile \
src/client/solaris/handler/exception_handler.cc \
@ -3127,24 +3019,44 @@ EXTRA_DIST = \
src/client/solaris/handler/minidump_test.cc \
src/client/solaris/handler/solaris_lwp.cc \
src/client/solaris/handler/solaris_lwp.h \
src/client/windows/breakpad_client.gyp \
src/client/windows/breakpad_client.sln \
src/client/windows/handler/exception_handler.cc \
src/client/windows/handler/exception_handler.h \
src/client/windows/handler/exception_handler.gyp \
src/client/windows/handler/exception_handler.vcproj \
src/client/windows/sender/crash_report_sender.cc \
src/client/windows/sender/crash_report_sender.h \
src/client/windows/sender/crash_report_sender.gyp \
src/common/dwarf/dwarf2diehandler.h \
src/common/dwarf/dwarf2enums.h \
src/common/dwarf/line_state_machine.h \
src/common/dwarf/types.h \
src/common/mac/arch_utilities.h \
src/common/mac/byteswap.h \
src/client/windows/sender/crash_report_sender.vcproj \
src/common/convert_UTF.c \
src/common/convert_UTF.h \
src/common/linux/crc32.cc \
src/common/linux/dump_symbols.cc \
src/common/linux/dump_symbols.h \
src/common/linux/elf_symbols_to_module.cc \
src/common/linux/elf_symbols_to_module.h \
src/common/linux/elfutils.cc \
src/common/linux/elfutils.h \
src/common/linux/file_id.cc \
src/common/linux/file_id.h \
src/common/linux/guid_creator.cc \
src/common/linux/guid_creator.h \
src/common/linux/http_upload.cc \
src/common/linux/http_upload.h \
src/common/mac/HTTPMultipartUpload.h \
src/common/mac/HTTPMultipartUpload.m \
src/common/mac/dump_syms.h \
src/common/mac/dump_syms.cc \
src/common/mac/file_id.cc \
src/common/mac/file_id.h \
src/common/mac/macho_id.cc \
src/common/mac/macho_id.h \
src/common/mac/macho_utilities.cc \
src/common/mac/macho_utilities.h \
src/common/mac/macho_walker.cc \
src/common/mac/macho_walker.h \
src/common/mac/string_utilities.cc \
src/common/mac/string_utilities.h \
src/common/mac/super_fat_arch.h \
src/common/md5.cc \
src/common/md5.h \
src/common/scoped_ptr.h \
src/common/solaris/dump_symbols.cc \
src/common/solaris/dump_symbols.h \
@ -3153,6 +3065,8 @@ EXTRA_DIST = \
src/common/solaris/guid_creator.cc \
src/common/solaris/guid_creator.h \
src/common/solaris/message_output.h \
src/common/string_conversion.cc \
src/common/string_conversion.h \
src/common/windows/guid_string.cc \
src/common/windows/guid_string.h \
src/common/windows/http_upload.cc \
@ -3161,158 +3075,22 @@ EXTRA_DIST = \
src/common/windows/pdb_source_line_writer.h \
src/common/windows/string_utils-inl.h \
src/common/windows/string_utils.cc \
src/processor/stackwalk_common.cc \
src/processor/stackwalk_common.h \
src/processor/stackwalker_selftest_sol.s \
src/processor/testdata/ascii_read_av_block_write.dmp \
src/processor/testdata/ascii_read_av_clobber_write.dmp \
src/processor/testdata/ascii_read_av_conditional.dmp \
src/processor/testdata/ascii_read_av.dmp \
src/processor/testdata/ascii_read_av_then_jmp.dmp \
src/processor/testdata/ascii_read_av_xchg_write.dmp \
src/processor/testdata/ascii_write_av_arg_to_call.dmp \
src/processor/testdata/ascii_write_av.dmp \
src/processor/testdata/exec_av_on_stack.dmp \
src/processor/testdata/linux_divide_by_zero.dmp \
src/processor/testdata/linux_executable_heap.dmp \
src/processor/testdata/linux_executable_stack.dmp \
src/processor/testdata/linux_inside_module_exe_region1.dmp \
src/processor/testdata/linux_inside_module_exe_region2.dmp \
src/processor/testdata/linux_jmp_to_0.dmp \
src/processor/testdata/linux_jmp_to_module_not_exe_region.dmp \
src/processor/testdata/linux_null_dereference.dmp \
src/processor/testdata/linux_null_read_av.dmp \
src/processor/testdata/linux_outside_module.dmp \
src/processor/testdata/linux_overflow.dmp \
src/processor/testdata/linux_raise_sigabrt.dmp \
src/processor/testdata/linux_stack_pointer_in_module.dmp \
src/processor/testdata/linux_stack_pointer_in_stack.dmp \
src/processor/testdata/linux_stacksmash.dmp \
src/processor/testdata/linux_write_to_nonwritable_module.dmp \
src/processor/testdata/linux_write_to_nonwritable_region_math.dmp \
src/processor/testdata/linux_write_to_outside_module.dmp \
src/processor/testdata/linux_write_to_outside_module_via_math.dmp \
src/processor/testdata/linux_write_to_under_4k.dmp \
src/processor/testdata/microdump-arm64.dmp \
src/processor/testdata/microdump-arm.dmp \
src/processor/testdata/microdump-mips32.dmp \
src/processor/testdata/microdump-mips64.dmp \
src/processor/testdata/microdump-multiple.dmp \
src/processor/testdata/microdump.stackwalk-arm64.out \
src/processor/testdata/microdump.stackwalk-arm.out \
src/processor/testdata/microdump.stackwalk.machine_readable-arm64.out \
src/processor/testdata/microdump.stackwalk.machine_readable-arm.out \
src/processor/testdata/microdump-x86.dmp \
src/processor/testdata/minidump2.dmp \
src/processor/testdata/minidump2.dump.out \
src/processor/testdata/minidump2.stackwalk.machine_readable.out \
src/processor/testdata/minidump2.stackwalk.out \
src/processor/testdata/module0.out \
src/processor/testdata/module1.out \
src/processor/testdata/module2.out \
src/processor/testdata/module3_bad.out \
src/processor/testdata/module4_bad.out \
src/processor/testdata/null_read_av.dmp \
src/processor/testdata/null_write_av.dmp \
src/processor/testdata/read_av_clobber_write.dmp \
src/processor/testdata/read_av_conditional.dmp \
src/processor/testdata/read_av_non_null.dmp \
src/processor/testdata/stack_exhaustion.dmp \
src/processor/testdata/write_av_non_null.dmp \
src/processor/testdata/symbols/kernel32.pdb/BCE8785C57B44245A669896B6A19B9542/kernel32.sym \
src/processor/testdata/symbols/ld-2.13.so/C32AD7E235EA6112E02A5B9D6219C4850/ld-2.13.so.sym \
src/processor/testdata/symbols/libc-2.13.so/F4F8DFCD5A5FB5A7CE64717E9E6AE3890/libc-2.13.so.sym \
src/processor/testdata/symbols/libgcc_s.so.1/18B180F90887D8F8B5C35D185444AF4C0/libgcc_s.so.1.sym \
src/processor/testdata/symbols/microdump/breakpad_unittests/D6D1FEC9A15DE7F38A236898871A2E770/breakpad_unittests.sym \
src/processor/testdata/symbols/microdump/breakpad_unittests/DA7778FB66018A4E9B4110ED06E730D00/breakpad_unittests.sym \
src/processor/testdata/symbols/microdump/crash_example/6E72E2F1A5F59AB3D51356FDFE394D490/crash_example.sym \
src/processor/testdata/symbols/microdump/crash_example/8F36148CC4647A8116CAF2A25F591F570/crash_example.sym \
src/processor/testdata/symbols/null_read_av/7B7D1968FF0D47AE4366E9C3A7E1B6750/null_read_av.sym \
src/processor/testdata/symbols/overflow/B0E1FC01EF48E39CAF5C881D2DF0C3840/overflow.sym \
src/processor/testdata/symbols/test_app.pdb/5A9832E5287241C1838ED98914E9B7FF1/test_app.sym \
src/processor/testdata/test_app.cc \
src/testing/gtest/include/gtest/gtest.h \
src/testing/gtest/include/gtest/gtest-death-test.h \
src/testing/gtest/include/gtest/gtest-message.h \
src/testing/gtest/include/gtest/gtest-param-test.h \
src/testing/gtest/include/gtest/gtest-printers.h \
src/testing/gtest/include/gtest/gtest-spi.h \
src/testing/gtest/include/gtest/gtest-test-part.h \
src/testing/gtest/include/gtest/gtest-typed-test.h \
src/testing/gtest/include/gtest/gtest_pred_impl.h \
src/testing/gtest/include/gtest/gtest_prod.h \
src/testing/gtest/include/gtest/internal/gtest-death-test-internal.h \
src/testing/gtest/include/gtest/internal/gtest-filepath.h \
src/testing/gtest/include/gtest/internal/gtest-internal.h \
src/testing/gtest/include/gtest/internal/gtest-linked_ptr.h \
src/testing/gtest/include/gtest/internal/gtest-param-util-generated.h \
src/testing/gtest/include/gtest/internal/gtest-param-util.h \
src/testing/gtest/include/gtest/internal/gtest-port.h \
src/testing/gtest/include/gtest/internal/gtest-string.h \
src/testing/gtest/include/gtest/internal/gtest-tuple.h \
src/testing/gtest/include/gtest/internal/gtest-type-util.h \
src/testing/gtest/src/gtest.cc \
src/testing/gtest/src/gtest-death-test.cc \
src/testing/gtest/src/gtest-filepath.cc \
src/testing/gtest/src/gtest-internal-inl.h \
src/testing/gtest/src/gtest-port.cc \
src/testing/gtest/src/gtest-printers.cc \
src/testing/gtest/src/gtest-test-part.cc \
src/testing/gtest/src/gtest-typed-test.cc \
src/testing/include/gmock/gmock.h \
src/testing/include/gmock/gmock-actions.h \
src/testing/include/gmock/gmock-cardinalities.h \
src/testing/include/gmock/gmock-generated-actions.h \
src/testing/include/gmock/gmock-generated-function-mockers.h \
src/testing/include/gmock/gmock-generated-matchers.h \
src/testing/include/gmock/gmock-generated-nice-strict.h \
src/testing/include/gmock/gmock-matchers.h \
src/testing/include/gmock/gmock-more-actions.h \
src/testing/include/gmock/gmock-more-matchers.h \
src/testing/include/gmock/gmock-spec-builders.h \
src/testing/include/gmock/internal/gmock-generated-internal-utils.h \
src/testing/include/gmock/internal/gmock-internal-utils.h \
src/testing/include/gmock/internal/gmock-port.h \
src/testing/src/gmock.cc \
src/testing/src/gmock-cardinalities.cc \
src/testing/src/gmock-internal-utils.cc \
src/testing/src/gmock-matchers.cc \
src/testing/src/gmock-spec-builders.cc \
src/testing/src/gmock_main.cc \
src/third_party/curl/COPYING \
src/third_party/curl/curlbuild.h \
src/third_party/curl/curl.h \
src/third_party/curl/curlrules.h \
src/third_party/curl/curlver.h \
src/third_party/curl/easy.h \
src/third_party/curl/mprintf.h \
src/third_party/curl/multi.h \
src/third_party/curl/stdcheaders.h \
src/third_party/curl/typecheck-gcc.h \
src/third_party/curl/types.h \
src/third_party/mac_headers/architecture/byte_order.h \
src/third_party/mac_headers/i386/_types.h \
src/third_party/mac_headers/mach/boolean.h \
src/third_party/mac_headers/mach/i386/boolean.h \
src/third_party/mac_headers/mach/i386/vm_param.h \
src/third_party/mac_headers/mach/i386/vm_types.h \
src/third_party/mac_headers/mach/machine/boolean.h \
src/third_party/mac_headers/mach/machine.h \
src/third_party/mac_headers/mach/machine/thread_state.h \
src/third_party/mac_headers/mach/machine/thread_status.h \
src/third_party/mac_headers/mach/machine/vm_types.h \
src/third_party/mac_headers/mach-o/arch.h \
src/third_party/mac_headers/mach-o/fat.h \
src/third_party/mac_headers/mach-o/loader.h \
src/third_party/mac_headers/mach-o/nlist.h \
src/third_party/mac_headers/mach/thread_status.h \
src/third_party/mac_headers/mach/vm_prot.h \
src/third_party/mac_headers/README \
src/third_party/musl/README \
src/third_party/musl/COPYRIGHT \
src/third_party/musl/README.breakpad \
src/third_party/musl/VERSION \
src/third_party/musl/include/elf.h \
src/tools/linux/dump_syms/Makefile \
src/tools/linux/dump_syms/dump_syms.cc \
src/tools/linux/symupload/Makefile \
src/tools/linux/symupload/minidump_upload.cc \
src/tools/linux/symupload/sym_upload.cc \
src/tools/mac/crash_report/crash_report.mm \
src/tools/mac/crash_report/crash_report.xcodeproj/project.pbxproj \
src/tools/mac/crash_report/on_demand_symbol_supplier.h \
@ -3331,20 +3109,15 @@ EXTRA_DIST = \
src/tools/solaris/dump_syms/testdata/dump_syms_regtest.sym \
src/tools/windows/converter/ms_symbol_server_converter.cc \
src/tools/windows/converter/ms_symbol_server_converter.h \
src/tools/windows/converter/ms_symbol_server_converter.gyp \
src/tools/windows/converter/ms_symbol_server_converter.vcproj \
src/tools/windows/dump_syms/dump_syms.cc \
src/tools/windows/dump_syms/dump_syms.gyp \
src/tools/windows/dump_syms/dump_syms.vcproj \
src/tools/windows/dump_syms/run_regtest.sh \
src/tools/windows/dump_syms/testdata/dump_syms_regtest.cc \
src/tools/windows/dump_syms/testdata/dump_syms_regtest.pdb \
src/tools/windows/dump_syms/testdata/dump_syms_regtest.sym \
src/tools/windows/dump_syms/testdata/dump_syms_regtest64.sym \
src/tools/windows/dump_syms/testdata/omap_reorder_bbs.sym \
src/tools/windows/dump_syms/testdata/omap_reorder_funcs.sym \
src/tools/windows/dump_syms/testdata/omap_stretched.sym \
src/tools/windows/dump_syms/testdata/omap_stretched_filled.sym \
src/tools/windows/symupload/symupload.cc \
src/tools/windows/symupload/symupload.gyp
src/tools/windows/symupload/symupload.vcproj
all: all-am
@ -4000,9 +3773,6 @@ src/common/dwarf/src_common_dumper_unittest-dwarf2diehandler_unittest.$(OBJEXT):
src/common/dwarf/src_common_dumper_unittest-dwarf2reader.$(OBJEXT): \
src/common/dwarf/$(am__dirstamp) \
src/common/dwarf/$(DEPDIR)/$(am__dirstamp)
src/common/dwarf/src_common_dumper_unittest-elf_reader.$(OBJEXT): \
src/common/dwarf/$(am__dirstamp) \
src/common/dwarf/$(DEPDIR)/$(am__dirstamp)
src/common/dwarf/src_common_dumper_unittest-dwarf2reader_cfi_unittest.$(OBJEXT): \
src/common/dwarf/$(am__dirstamp) \
src/common/dwarf/$(DEPDIR)/$(am__dirstamp)
@ -4109,9 +3879,6 @@ src/common/dwarf/src_common_mac_macho_reader_unittest-dwarf2diehandler.$(OBJEXT)
src/common/dwarf/src_common_mac_macho_reader_unittest-dwarf2reader.$(OBJEXT): \
src/common/dwarf/$(am__dirstamp) \
src/common/dwarf/$(DEPDIR)/$(am__dirstamp)
src/common/dwarf/src_common_mac_macho_reader_unittest-elf_reader.$(OBJEXT): \
src/common/dwarf/$(am__dirstamp) \
src/common/dwarf/$(DEPDIR)/$(am__dirstamp)
src/common/mac/$(am__dirstamp):
@$(MKDIR_P) src/common/mac
@: > src/common/mac/$(am__dirstamp)
@ -4283,13 +4050,6 @@ src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.$(
src/processor/proc_maps_linux_unittest$(EXEEXT): $(src_processor_proc_maps_linux_unittest_OBJECTS) $(src_processor_proc_maps_linux_unittest_DEPENDENCIES) $(EXTRA_src_processor_proc_maps_linux_unittest_DEPENDENCIES) src/processor/$(am__dirstamp)
@rm -f src/processor/proc_maps_linux_unittest$(EXEEXT)
$(AM_V_CXXLD)$(CXXLINK) $(src_processor_proc_maps_linux_unittest_OBJECTS) $(src_processor_proc_maps_linux_unittest_LDADD) $(LIBS)
src/processor/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.$(OBJEXT): \
src/processor/$(am__dirstamp) \
src/processor/$(DEPDIR)/$(am__dirstamp)
src/processor/range_map_shrink_down_unittest$(EXEEXT): $(src_processor_range_map_shrink_down_unittest_OBJECTS) $(src_processor_range_map_shrink_down_unittest_DEPENDENCIES) $(EXTRA_src_processor_range_map_shrink_down_unittest_DEPENDENCIES) src/processor/$(am__dirstamp)
@rm -f src/processor/range_map_shrink_down_unittest$(EXEEXT)
$(AM_V_CXXLD)$(CXXLINK) $(src_processor_range_map_shrink_down_unittest_OBJECTS) $(src_processor_range_map_shrink_down_unittest_LDADD) $(LIBS)
src/processor/range_map_unittest.$(OBJEXT): \
src/processor/$(am__dirstamp) \
src/processor/$(DEPDIR)/$(am__dirstamp)
@ -4451,9 +4211,6 @@ src/common/dwarf/dwarf2diehandler.$(OBJEXT): \
src/common/dwarf/dwarf2reader.$(OBJEXT): \
src/common/dwarf/$(am__dirstamp) \
src/common/dwarf/$(DEPDIR)/$(am__dirstamp)
src/common/dwarf/elf_reader.$(OBJEXT): \
src/common/dwarf/$(am__dirstamp) \
src/common/dwarf/$(DEPDIR)/$(am__dirstamp)
src/common/linux/crc32.$(OBJEXT): src/common/linux/$(am__dirstamp) \
src/common/linux/$(DEPDIR)/$(am__dirstamp)
src/common/linux/dump_symbols.$(OBJEXT): \
@ -4511,9 +4268,6 @@ src/tools/linux/symupload/minidump_upload.$(OBJEXT): \
src/tools/linux/symupload/minidump_upload$(EXEEXT): $(src_tools_linux_symupload_minidump_upload_OBJECTS) $(src_tools_linux_symupload_minidump_upload_DEPENDENCIES) $(EXTRA_src_tools_linux_symupload_minidump_upload_DEPENDENCIES) src/tools/linux/symupload/$(am__dirstamp)
@rm -f src/tools/linux/symupload/minidump_upload$(EXEEXT)
$(AM_V_CXXLD)$(CXXLINK) $(src_tools_linux_symupload_minidump_upload_OBJECTS) $(src_tools_linux_symupload_minidump_upload_LDADD) $(LIBS)
src/common/linux/symbol_upload.$(OBJEXT): \
src/common/linux/$(am__dirstamp) \
src/common/linux/$(DEPDIR)/$(am__dirstamp)
src/tools/linux/symupload/sym_upload.$(OBJEXT): \
src/tools/linux/symupload/$(am__dirstamp) \
src/tools/linux/symupload/$(DEPDIR)/$(am__dirstamp)
@ -4554,9 +4308,6 @@ src/common/dwarf/src_tools_mac_dump_syms_dump_syms_mac-dwarf2diehandler.$(OBJEXT
src/common/dwarf/src_tools_mac_dump_syms_dump_syms_mac-dwarf2reader.$(OBJEXT): \
src/common/dwarf/$(am__dirstamp) \
src/common/dwarf/$(DEPDIR)/$(am__dirstamp)
src/common/dwarf/src_tools_mac_dump_syms_dump_syms_mac-elf_reader.$(OBJEXT): \
src/common/dwarf/$(am__dirstamp) \
src/common/dwarf/$(DEPDIR)/$(am__dirstamp)
src/common/mac/src_tools_mac_dump_syms_dump_syms_mac-arch_utilities.$(OBJEXT): \
src/common/mac/$(am__dirstamp) \
src/common/mac/$(DEPDIR)/$(am__dirstamp)
@ -4707,7 +4458,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/bytereader.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/dwarf2diehandler.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/dwarf2reader.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/elf_reader.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-bytereader.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-bytereader_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-cfi_assembler.Po@am__quote@
@ -4716,16 +4466,13 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-dwarf2reader.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-dwarf2reader_cfi_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-dwarf2reader_die_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-elf_reader.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_common_mac_macho_reader_unittest-bytereader.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_common_mac_macho_reader_unittest-cfi_assembler.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_common_mac_macho_reader_unittest-dwarf2diehandler.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_common_mac_macho_reader_unittest-dwarf2reader.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_common_mac_macho_reader_unittest-elf_reader.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_tools_mac_dump_syms_dump_syms_mac-bytereader.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_tools_mac_dump_syms_dump_syms_mac-dwarf2diehandler.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_tools_mac_dump_syms_dump_syms_mac-dwarf2reader.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/dwarf/$(DEPDIR)/src_tools_mac_dump_syms_dump_syms_mac-elf_reader.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/crc32.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/dump_symbols.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/elf_core_dump.Po@am__quote@
@ -4756,7 +4503,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/src_common_dumper_unittest-safe_readlink_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/src_common_dumper_unittest-synth_elf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/src_common_dumper_unittest-synth_elf_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/symbol_upload.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/tests/$(DEPDIR)/src_client_linux_linux_client_unittest_shlib-crash_generator.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/tests/$(DEPDIR)/src_common_dumper_unittest-crash_generator.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/common/mac/$(DEPDIR)/src_common_mac_macho_reader_unittest-arch_utilities.Po@am__quote@
@ -4826,7 +4572,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_minidump_unittest-synth_minidump.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_proc_maps_linux_unittest-proc_maps_linux.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_stackwalker_address_list_unittest-stackwalker_address_list_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_stackwalker_amd64_unittest-stackwalker_amd64_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_stackwalker_arm64_unittest-stackwalker_arm64_unittest.Po@am__quote@
@ -5687,20 +5432,6 @@ src/common/dwarf/src_common_dumper_unittest-dwarf2reader.obj: src/common/dwarf/d
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/dwarf/src_common_dumper_unittest-dwarf2reader.obj `if test -f 'src/common/dwarf/dwarf2reader.cc'; then $(CYGPATH_W) 'src/common/dwarf/dwarf2reader.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/dwarf/dwarf2reader.cc'; fi`
src/common/dwarf/src_common_dumper_unittest-elf_reader.o: src/common/dwarf/elf_reader.cc
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/dwarf/src_common_dumper_unittest-elf_reader.o -MD -MP -MF src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-elf_reader.Tpo -c -o src/common/dwarf/src_common_dumper_unittest-elf_reader.o `test -f 'src/common/dwarf/elf_reader.cc' || echo '$(srcdir)/'`src/common/dwarf/elf_reader.cc
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-elf_reader.Tpo src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-elf_reader.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/common/dwarf/elf_reader.cc' object='src/common/dwarf/src_common_dumper_unittest-elf_reader.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/dwarf/src_common_dumper_unittest-elf_reader.o `test -f 'src/common/dwarf/elf_reader.cc' || echo '$(srcdir)/'`src/common/dwarf/elf_reader.cc
src/common/dwarf/src_common_dumper_unittest-elf_reader.obj: src/common/dwarf/elf_reader.cc
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/dwarf/src_common_dumper_unittest-elf_reader.obj -MD -MP -MF src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-elf_reader.Tpo -c -o src/common/dwarf/src_common_dumper_unittest-elf_reader.obj `if test -f 'src/common/dwarf/elf_reader.cc'; then $(CYGPATH_W) 'src/common/dwarf/elf_reader.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/dwarf/elf_reader.cc'; fi`
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-elf_reader.Tpo src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-elf_reader.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/common/dwarf/elf_reader.cc' object='src/common/dwarf/src_common_dumper_unittest-elf_reader.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/dwarf/src_common_dumper_unittest-elf_reader.obj `if test -f 'src/common/dwarf/elf_reader.cc'; then $(CYGPATH_W) 'src/common/dwarf/elf_reader.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/dwarf/elf_reader.cc'; fi`
src/common/dwarf/src_common_dumper_unittest-dwarf2reader_cfi_unittest.o: src/common/dwarf/dwarf2reader_cfi_unittest.cc
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/dwarf/src_common_dumper_unittest-dwarf2reader_cfi_unittest.o -MD -MP -MF src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-dwarf2reader_cfi_unittest.Tpo -c -o src/common/dwarf/src_common_dumper_unittest-dwarf2reader_cfi_unittest.o `test -f 'src/common/dwarf/dwarf2reader_cfi_unittest.cc' || echo '$(srcdir)/'`src/common/dwarf/dwarf2reader_cfi_unittest.cc
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-dwarf2reader_cfi_unittest.Tpo src/common/dwarf/$(DEPDIR)/src_common_dumper_unittest-dwarf2reader_cfi_unittest.Po
@ -6177,20 +5908,6 @@ src/common/dwarf/src_common_mac_macho_reader_unittest-dwarf2reader.obj: src/comm
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_mac_macho_reader_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/dwarf/src_common_mac_macho_reader_unittest-dwarf2reader.obj `if test -f 'src/common/dwarf/dwarf2reader.cc'; then $(CYGPATH_W) 'src/common/dwarf/dwarf2reader.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/dwarf/dwarf2reader.cc'; fi`
src/common/dwarf/src_common_mac_macho_reader_unittest-elf_reader.o: src/common/dwarf/elf_reader.cc
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_mac_macho_reader_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/dwarf/src_common_mac_macho_reader_unittest-elf_reader.o -MD -MP -MF src/common/dwarf/$(DEPDIR)/src_common_mac_macho_reader_unittest-elf_reader.Tpo -c -o src/common/dwarf/src_common_mac_macho_reader_unittest-elf_reader.o `test -f 'src/common/dwarf/elf_reader.cc' || echo '$(srcdir)/'`src/common/dwarf/elf_reader.cc
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/common/dwarf/$(DEPDIR)/src_common_mac_macho_reader_unittest-elf_reader.Tpo src/common/dwarf/$(DEPDIR)/src_common_mac_macho_reader_unittest-elf_reader.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/common/dwarf/elf_reader.cc' object='src/common/dwarf/src_common_mac_macho_reader_unittest-elf_reader.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_mac_macho_reader_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/dwarf/src_common_mac_macho_reader_unittest-elf_reader.o `test -f 'src/common/dwarf/elf_reader.cc' || echo '$(srcdir)/'`src/common/dwarf/elf_reader.cc
src/common/dwarf/src_common_mac_macho_reader_unittest-elf_reader.obj: src/common/dwarf/elf_reader.cc
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_mac_macho_reader_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/dwarf/src_common_mac_macho_reader_unittest-elf_reader.obj -MD -MP -MF src/common/dwarf/$(DEPDIR)/src_common_mac_macho_reader_unittest-elf_reader.Tpo -c -o src/common/dwarf/src_common_mac_macho_reader_unittest-elf_reader.obj `if test -f 'src/common/dwarf/elf_reader.cc'; then $(CYGPATH_W) 'src/common/dwarf/elf_reader.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/dwarf/elf_reader.cc'; fi`
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/common/dwarf/$(DEPDIR)/src_common_mac_macho_reader_unittest-elf_reader.Tpo src/common/dwarf/$(DEPDIR)/src_common_mac_macho_reader_unittest-elf_reader.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/common/dwarf/elf_reader.cc' object='src/common/dwarf/src_common_mac_macho_reader_unittest-elf_reader.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_mac_macho_reader_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/dwarf/src_common_mac_macho_reader_unittest-elf_reader.obj `if test -f 'src/common/dwarf/elf_reader.cc'; then $(CYGPATH_W) 'src/common/dwarf/elf_reader.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/dwarf/elf_reader.cc'; fi`
src/common/mac/src_common_mac_macho_reader_unittest-arch_utilities.o: src/common/mac/arch_utilities.cc
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_mac_macho_reader_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/mac/src_common_mac_macho_reader_unittest-arch_utilities.o -MD -MP -MF src/common/mac/$(DEPDIR)/src_common_mac_macho_reader_unittest-arch_utilities.Tpo -c -o src/common/mac/src_common_mac_macho_reader_unittest-arch_utilities.o `test -f 'src/common/mac/arch_utilities.cc' || echo '$(srcdir)/'`src/common/mac/arch_utilities.cc
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/common/mac/$(DEPDIR)/src_common_mac_macho_reader_unittest-arch_utilities.Tpo src/common/mac/$(DEPDIR)/src_common_mac_macho_reader_unittest-arch_utilities.Po
@ -6513,20 +6230,6 @@ src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.ob
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_proc_maps_linux_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.obj `if test -f 'src/processor/proc_maps_linux_unittest.cc'; then $(CYGPATH_W) 'src/processor/proc_maps_linux_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/proc_maps_linux_unittest.cc'; fi`
src/processor/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.o: src/processor/range_map_shrink_down_unittest.cc
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_range_map_shrink_down_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.o -MD -MP -MF src/processor/$(DEPDIR)/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.Tpo -c -o src/processor/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.o `test -f 'src/processor/range_map_shrink_down_unittest.cc' || echo '$(srcdir)/'`src/processor/range_map_shrink_down_unittest.cc
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/processor/$(DEPDIR)/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.Tpo src/processor/$(DEPDIR)/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/processor/range_map_shrink_down_unittest.cc' object='src/processor/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_range_map_shrink_down_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.o `test -f 'src/processor/range_map_shrink_down_unittest.cc' || echo '$(srcdir)/'`src/processor/range_map_shrink_down_unittest.cc
src/processor/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.obj: src/processor/range_map_shrink_down_unittest.cc
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_range_map_shrink_down_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.obj -MD -MP -MF src/processor/$(DEPDIR)/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.Tpo -c -o src/processor/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.obj `if test -f 'src/processor/range_map_shrink_down_unittest.cc'; then $(CYGPATH_W) 'src/processor/range_map_shrink_down_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/range_map_shrink_down_unittest.cc'; fi`
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/processor/$(DEPDIR)/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.Tpo src/processor/$(DEPDIR)/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/processor/range_map_shrink_down_unittest.cc' object='src/processor/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_range_map_shrink_down_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.obj `if test -f 'src/processor/range_map_shrink_down_unittest.cc'; then $(CYGPATH_W) 'src/processor/range_map_shrink_down_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/range_map_shrink_down_unittest.cc'; fi`
src/common/src_processor_stackwalker_address_list_unittest-test_assembler.o: src/common/test_assembler.cc
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_stackwalker_address_list_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/src_processor_stackwalker_address_list_unittest-test_assembler.o -MD -MP -MF src/common/$(DEPDIR)/src_processor_stackwalker_address_list_unittest-test_assembler.Tpo -c -o src/common/src_processor_stackwalker_address_list_unittest-test_assembler.o `test -f 'src/common/test_assembler.cc' || echo '$(srcdir)/'`src/common/test_assembler.cc
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/common/$(DEPDIR)/src_processor_stackwalker_address_list_unittest-test_assembler.Tpo src/common/$(DEPDIR)/src_processor_stackwalker_address_list_unittest-test_assembler.Po
@ -6989,20 +6692,6 @@ src/common/dwarf/src_tools_mac_dump_syms_dump_syms_mac-dwarf2reader.obj: src/com
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_tools_mac_dump_syms_dump_syms_mac_CXXFLAGS) $(CXXFLAGS) -c -o src/common/dwarf/src_tools_mac_dump_syms_dump_syms_mac-dwarf2reader.obj `if test -f 'src/common/dwarf/dwarf2reader.cc'; then $(CYGPATH_W) 'src/common/dwarf/dwarf2reader.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/dwarf/dwarf2reader.cc'; fi`
src/common/dwarf/src_tools_mac_dump_syms_dump_syms_mac-elf_reader.o: src/common/dwarf/elf_reader.cc
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_tools_mac_dump_syms_dump_syms_mac_CXXFLAGS) $(CXXFLAGS) -MT src/common/dwarf/src_tools_mac_dump_syms_dump_syms_mac-elf_reader.o -MD -MP -MF src/common/dwarf/$(DEPDIR)/src_tools_mac_dump_syms_dump_syms_mac-elf_reader.Tpo -c -o src/common/dwarf/src_tools_mac_dump_syms_dump_syms_mac-elf_reader.o `test -f 'src/common/dwarf/elf_reader.cc' || echo '$(srcdir)/'`src/common/dwarf/elf_reader.cc
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/common/dwarf/$(DEPDIR)/src_tools_mac_dump_syms_dump_syms_mac-elf_reader.Tpo src/common/dwarf/$(DEPDIR)/src_tools_mac_dump_syms_dump_syms_mac-elf_reader.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/common/dwarf/elf_reader.cc' object='src/common/dwarf/src_tools_mac_dump_syms_dump_syms_mac-elf_reader.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_tools_mac_dump_syms_dump_syms_mac_CXXFLAGS) $(CXXFLAGS) -c -o src/common/dwarf/src_tools_mac_dump_syms_dump_syms_mac-elf_reader.o `test -f 'src/common/dwarf/elf_reader.cc' || echo '$(srcdir)/'`src/common/dwarf/elf_reader.cc
src/common/dwarf/src_tools_mac_dump_syms_dump_syms_mac-elf_reader.obj: src/common/dwarf/elf_reader.cc
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_tools_mac_dump_syms_dump_syms_mac_CXXFLAGS) $(CXXFLAGS) -MT src/common/dwarf/src_tools_mac_dump_syms_dump_syms_mac-elf_reader.obj -MD -MP -MF src/common/dwarf/$(DEPDIR)/src_tools_mac_dump_syms_dump_syms_mac-elf_reader.Tpo -c -o src/common/dwarf/src_tools_mac_dump_syms_dump_syms_mac-elf_reader.obj `if test -f 'src/common/dwarf/elf_reader.cc'; then $(CYGPATH_W) 'src/common/dwarf/elf_reader.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/dwarf/elf_reader.cc'; fi`
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/common/dwarf/$(DEPDIR)/src_tools_mac_dump_syms_dump_syms_mac-elf_reader.Tpo src/common/dwarf/$(DEPDIR)/src_tools_mac_dump_syms_dump_syms_mac-elf_reader.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/common/dwarf/elf_reader.cc' object='src/common/dwarf/src_tools_mac_dump_syms_dump_syms_mac-elf_reader.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_tools_mac_dump_syms_dump_syms_mac_CXXFLAGS) $(CXXFLAGS) -c -o src/common/dwarf/src_tools_mac_dump_syms_dump_syms_mac-elf_reader.obj `if test -f 'src/common/dwarf/elf_reader.cc'; then $(CYGPATH_W) 'src/common/dwarf/elf_reader.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/dwarf/elf_reader.cc'; fi`
src/common/mac/src_tools_mac_dump_syms_dump_syms_mac-arch_utilities.o: src/common/mac/arch_utilities.cc
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(src_tools_mac_dump_syms_dump_syms_mac_CXXFLAGS) $(CXXFLAGS) -MT src/common/mac/src_tools_mac_dump_syms_dump_syms_mac-arch_utilities.o -MD -MP -MF src/common/mac/$(DEPDIR)/src_tools_mac_dump_syms_dump_syms_mac-arch_utilities.Tpo -c -o src/common/mac/src_tools_mac_dump_syms_dump_syms_mac-arch_utilities.o `test -f 'src/common/mac/arch_utilities.cc' || echo '$(srcdir)/'`src/common/mac/arch_utilities.cc
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/common/mac/$(DEPDIR)/src_tools_mac_dump_syms_dump_syms_mac-arch_utilities.Tpo src/common/mac/$(DEPDIR)/src_tools_mac_dump_syms_dump_syms_mac-arch_utilities.Po
@ -7679,13 +7368,6 @@ src/processor/proc_maps_linux_unittest.log: src/processor/proc_maps_linux_unitte
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
src/processor/range_map_shrink_down_unittest.log: src/processor/range_map_shrink_down_unittest$(EXEEXT)
@p='src/processor/range_map_shrink_down_unittest$(EXEEXT)'; \
b='src/processor/range_map_shrink_down_unittest'; \
$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
src/processor/range_map_unittest.log: src/processor/range_map_unittest$(EXEEXT)
@p='src/processor/range_map_unittest$(EXEEXT)'; \
b='src/processor/range_map_unittest'; \

View File

@ -6,7 +6,7 @@ on Android, and later generate valid stack traces from the minidumps
it generates.
This release supports ARM, x86 and MIPS based Android systems.
This release requires NDK release r11c or higher.
This release requires NDK release r10c or higher.
I. Building the client library:
===============================
@ -58,7 +58,7 @@ II. Using the client library in Android:
========================================
The usage instructions are very similar to the Linux ones that are
found at https://chromium.googlesource.com/breakpad/breakpad/+/master/docs/linux_starter_guide.md
found at http://code.google.com/p/google-breakpad/wiki/LinuxStarterGuide
1/ You need to include "client/linux/handler/exception_handler.h" from a C++
source file.

View File

@ -8,73 +8,42 @@ crash-reporting system.
* [Bugs](https://bugs.chromium.org/p/google-breakpad/)
* Discussion/Questions: [google-breakpad-discuss@googlegroups.com](https://groups.google.com/d/forum/google-breakpad-discuss)
* Developer/Reviews: [google-breakpad-dev@googlegroups.com](https://groups.google.com/d/forum/google-breakpad-dev)
* Tests: [![Build Status](https://travis-ci.org/google/breakpad.svg?branch=master)](https://travis-ci.org/google/breakpad)
## Getting started (from master)
## Getting started in 32-bit mode (from trunk)
1. First, [download depot_tools](http://dev.chromium.org/developers/how-tos/install-depot-tools)
and ensure that they're in your `PATH`.
2. Create a new directory for checking out the source code (it must be named
breakpad).
```sh
mkdir breakpad && cd breakpad
```
3. Run the `fetch` tool from depot_tools to download all the source repos.
```sh
fetch breakpad
cd src
```
4. Build the source.
```sh
./configure && make
```
You can also cd to another directory and run configure from there to build
outside the source tree.
This will build the processor tools (`src/processor/minidump_stackwalk`,
`src/processor/minidump_dump`, etc), and when building on Linux it will
also build the client libraries and some tools
(`src/tools/linux/dump_syms/dump_syms`,
`src/tools/linux/md2core/minidump-2-core`, etc).
5. Optionally, run tests.
```sh
make check
```
6. Optionally, install the built libraries
```sh
make install
```
```sh
# Configure
CXXFLAGS=-m32 CFLAGS=-m32 CPPFLAGS=-m32 ./configure
# Build
make
# Test
make check
# Install
make install
```
If you need to reconfigure your build be sure to run `make distclean` first.
To update an existing checkout to a newer revision, you can
`git pull` as usual, but then you should run `gclient sync` to ensure that the
dependent repos are up-to-date.
## To request change review:
## To request change review
1. Get a copy of depot_tools repo.
http://dev.chromium.org/developers/how-tos/install-depot-tools
1. Follow the steps above to get the source and build it.
2. Create a new directory for checking out the source code.
mkdir breakpad && cd breakpad
2. Make changes. Build and test your changes.
3. Run the `fetch` tool from depot_tools to download all the source repos.
`fetch breakpad`
4. Make changes. Build and test your changes.
For core code like processor use methods above.
For linux/mac/windows, there are test targets in each project file.
3. Commit your changes to your local repo and upload them to the server.
5. Commit your changes to your local repo and upload them to the server.
http://dev.chromium.org/developers/contributing-code
e.g. `git commit ... && git cl upload ...`
You will be prompted for credential and a description.
4. At https://codereview.chromium.org/ you'll find your issue listed; click on
6. At https://codereview.chromium.org/ you'll find your issue listed; click on
it, and select Publish+Mail, and enter in the code reviewer and CC
google-breakpad-dev@googlegroups.com

View File

@ -71,12 +71,9 @@ LOCAL_ARM_MODE := arm
# List of client source files, directly taken from Makefile.am
LOCAL_SRC_FILES := \
src/client/linux/crash_generation/crash_generation_client.cc \
src/client/linux/dump_writer_common/thread_info.cc \
src/client/linux/dump_writer_common/ucontext_reader.cc \
src/client/linux/handler/exception_handler.cc \
src/client/linux/handler/minidump_descriptor.cc \
src/client/linux/log/log.cc \
src/client/linux/microdump_writer/microdump_writer.cc \
src/client/linux/minidump_writer/linux_dumper.cc \
src/client/linux/minidump_writer/linux_ptrace_dumper.cc \
src/client/linux/minidump_writer/minidump_writer.cc \

View File

@ -29,4 +29,3 @@
APP_STL := stlport_static
APP_ABI := all
APP_CXXFLAGS := -std=c++11 -D__STDC_LIMIT_MACROS

View File

@ -14,85 +14,76 @@ necessary to produce minidumps from an application.
First, configure your build process to link **libbreakpad\_client.a** into your
binary, and set your include paths to include the **src** directory in the
**google-breakpad** source tree. Next, include the exception handler header:
**google-breakpad** source tree. Next, include the exception handler header: ```
# include "client/linux/handler/exception_handler.h"
```cpp
#include "client/linux/handler/exception_handler.h"
```
Now you can instantiate an `ExceptionHandler` object. Exception handling is active for the lifetime of the `ExceptionHandler` object, so you should instantiate it as early as possible in your application's startup process, and keep it alive for as close to shutdown as possible. To do anything useful, the `ExceptionHandler` constructor requires a path where it can write minidumps, as well as a callback function to receive information about minidumps that were written:
```
```cpp
static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor,
void* context, bool succeeded) {
printf("Dump path: %s\n", descriptor.path());
return succeeded;
}
void* context, bool succeeded) { printf("Dump path: %s\n", descriptor.path());
return succeeded; }
void crash() { volatile int* a = (int*)(NULL); *a = 1; }
int main(int argc, char* argv[]) {
google_breakpad::MinidumpDescriptor descriptor("/tmp");
google_breakpad::ExceptionHandler eh(descriptor, NULL, dumpCallback, NULL, true, -1);
crash();
return 0;
}
```
int main(int argc, char* argv[]) { google_breakpad::MinidumpDescriptor
descriptor("/tmp"); google_breakpad::ExceptionHandler eh(descriptor, NULL,
dumpCallback, NULL, true, -1); crash(); return 0; } ```
Compiling and running this example should produce a minidump file in /tmp, and
it should print the minidump filename before exiting. You can read more about
the other parameters to the `ExceptionHandler` constructor [in the exception_handler.h source file][1].
[1]: https://chromium.googlesource.com/breakpad/breakpad/+/master/src/client/linux/handler/exception_handler.h
the other parameters to the `ExceptionHandler` constructor <a
href='http://code.google.com/p/google-breakpad/source/browse/trunk/src/client/linux/handler/exception_handler.h'>in
the exception_handler.h source file</a>.
**Note**: You should do as little work as possible in the callback function.
Your application is in an unsafe state. It may not be safe to allocate memory or
call functions from other shared libraries. The safest thing to do is `fork` and
`exec` a new process to do any work you need to do. If you must do some work in
the callback, the Breakpad source contains [some simple reimplementations of libc functions][2], to avoid calling directly into
libc, as well as [a header file for making Linux system calls][3] (in **src/third\_party/lss**) to avoid calling into other shared libraries.
[2]: https://chromium.googlesource.com/breakpad/breakpad/+/master/src/common/linux/linux_libc_support.h
[3]: https://chromium.googlesource.com/linux-syscall-support/+/master
the callback, the Breakpad source contains <a
href='http://code.google.com/p/google-breakpad/source/browse/trunk/src/common/linux/linux_libc_support.h'>some
simple reimplementations of libc functions</a>, to avoid calling directly into
libc, as well as <a href='http://code.google.com/p/linux-syscall-support/'>a
header file for making Linux system calls</a> (in **src/third\_party/lss**) to
avoid calling into other shared libraries.
## Sending the minidump file
In a real application, you would want to handle the minidump in some way, likely
by sending it to a server for analysis. The Breakpad source tree contains [some
HTTP upload source][4] that you might find useful, as well as [a minidump upload tool][5].
[4]: https://chromium.googlesource.com/breakpad/breakpad/+/master/src/common/linux/http_upload.h
[5]: https://chromium.googlesource.com/breakpad/breakpad/+/master/src/tools/linux/symupload/minidump_upload.cc
by sending it to a server for analysis. The Breakpad source tree contains <a
href='http://code.google.com/p/google-breakpad/source/browse/#svn/trunk/src/common/linux'>some
HTTP upload source</a> that you might find useful, as well as <a
href='http://code.google.com/p/google-breakpad/source/browse/#svn/trunk/src/tools/linux/symupload'>a
minidump upload tool</a>.
## Producing symbols for your application
To produce useful stack traces, Breakpad requires you to convert the debugging
symbols in your binaries to [text-format symbol files][6]. First, ensure that you've compiled your binaries with `-g` to
symbols in your binaries to <a
href='http://code.google.com/p/google-breakpad/wiki/SymbolFiles'>text-format
symbol files</a>. First, ensure that you've compiled your binaries with `-g` to
include debugging symbols. Next, compile the `dump_syms` tool by running
`configure && make` in the Breakpad source directory. Next, run `dump_syms` on
your binaries to produce the text-format symbols. For example, if your main
binary was named `test`:
[6]: https://chromium.googlesource.com/breakpad/breakpad/+/master/docs/symbol_files.md
```
$ google-breakpad/src/tools/linux/dump_syms/dump_syms ./test > test.sym
```
binary was named `test`: `$ google-breakpad/src/tools/linux/dump_syms/dump_syms
./test > test.sym
`
In order to use these symbols with the `minidump_stackwalk` tool, you will need
to place them in a specific directory structure. The first line of the symbol
file contains the information you need to produce this directory structure, for
example (your output will vary):
example (your output will vary): `$ head -n1 test.sym MODULE Linux x86_64
6EDC6ACDB282125843FD59DA9C81BD830 test $ mkdir -p
./symbols/test/6EDC6ACDB282125843FD59DA9C81BD830 $ mv test.sym
./symbols/test/6EDC6ACDB282125843FD59DA9C81BD830
`
```
$ head -n1 test.sym MODULE Linux x86_64 6EDC6ACDB282125843FD59DA9C81BD830 test
$ mkdir -p ./symbols/test/6EDC6ACDB282125843FD59DA9C81BD830
$ mv test.sym ./symbols/test/6EDC6ACDB282125843FD59DA9C81BD830
```
You may also find the [symbolstore.py][7] script in the Mozilla repository useful, as it encapsulates these steps.
[7]: https://dxr.mozilla.org/mozilla-central/source/toolkit/crashreporter/tools/symbolstore.py
You may also find the <a
href='http://mxr.mozilla.org/mozilla-central/source/toolkit/crashreporter/tools/symbolstore.py'>symbolstore.py</a>
script in the Mozilla repository useful, as it encapsulates these steps.
## Processing the minidump to produce a stack trace
@ -101,10 +92,6 @@ plus its corresponding text-format symbols and produce a symbolized stacktrace.
It should be in the **google-breakpad/src/processor** directory if you compiled
the Breakpad source using the directions above. Simply pass it the minidump and
the symbol path as commandline parameters:
```
$ google-breakpad/src/processor/minidump_stackwalk minidump.dmp ./symbols
```
It produces verbose output on stderr, and the stacktrace on stdout, so you may
`google-breakpad/src/processor/minidump_stackwalk minidump.dmp ./symbols
` It produces verbose output on stderr, and the stacktrace on stdout, so you may
want to redirect stderr.

View File

@ -1,43 +0,0 @@
#!/bin/sh
set -ex
setup_env() {
# Travis sets CC/CXX to the system toolchain, so our .travis.yml
# exports USE_{CC,CXX} for this script to use.
if [ -n "$USE_CC" ]; then
export CC=$USE_CC
fi
if [ -n "$USE_CXX" ]; then
export CXX=$USE_CXX
fi
# Use -jN for faster builds. Travis build machines under Docker
# have a lot of cores, but are memory-limited, so the kernel
# will OOM if we try to use them all, so use at most 4.
# See https://github.com/travis-ci/travis-ci/issues/1972
export NCPUS=$(getconf _NPROCESSORS_ONLN)
export JOBS=$(( $NCPUS < 4 ? $NCPUS : 4 ))
}
# Do an in-tree build and make sure tests pass.
build() {
./configure
make -j${JOBS} check VERBOSE=1
make distclean
}
# Do an out-of-tree build and make sure we can create a release tarball.
build_out_of_tree() {
mkdir -p build/native
cd build/native
../../configure
make -j${JOBS} distcheck VERBOSE=1
}
main() {
setup_env
build
build_out_of_tree
}
main "$@"

View File

@ -1,24 +0,0 @@
#!/bin/sh
set -ex
get_depot_tools() {
cd
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
PATH="$HOME/depot_tools:$PATH"
}
gclient_sync() {
# Rename the source dir to match what gclient expects.
srcdir=$(basename "$TRAVIS_BUILD_DIR")
cd "${TRAVIS_BUILD_DIR}"/..
mv "${srcdir}" src
gclient config --unmanaged https://github.com/google/breakpad.git
gclient sync
}
main() {
get_depot_tools
gclient_sync
}
main "$@"

View File

@ -118,7 +118,7 @@ namespace {
// all these signals must be Core (see man 7 signal) because we rethrow the
// signal after handling it and expect that it'll be fatal.
const int kExceptionSignals[] = {
SIGSEGV, SIGABRT, SIGFPE, SIGILL, SIGBUS, SIGTRAP
SIGSEGV, SIGABRT, SIGFPE, SIGILL, SIGBUS
};
const int kNumHandledSignals =
sizeof(kExceptionSignals) / sizeof(kExceptionSignals[0]);

View File

@ -45,6 +45,7 @@
#include "client/linux/handler/exception_handler.h"
#include "client/linux/minidump_writer/minidump_writer.h"
#include "common/linux/eintr_wrapper.h"
#include "common/linux/file_id.h"
#include "common/linux/ignore_ret.h"
#include "common/linux/linux_libc_support.h"
#include "common/tests/auto_tempdir.h"
@ -93,6 +94,10 @@ void FlushInstructionCache(const char* memory, uint32_t memory_size) {
#endif
}
// Length of a formatted GUID string =
// sizeof(MDGUID) * 2 + 4 (for dashes) + 1 (null terminator)
const int kGUIDStringSize = 37;
void sigchld_handler(int signo) { }
int CreateTMPFile(const string& dir, string* path) {
@ -812,7 +817,19 @@ TEST(ExceptionHandlerTest, ModuleInfo) {
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
};
const string module_identifier = "33221100554477668899AABBCCDDEEFF0";
char module_identifier_buffer[kGUIDStringSize];
FileID::ConvertIdentifierToString(kModuleGUID,
module_identifier_buffer,
sizeof(module_identifier_buffer));
string module_identifier(module_identifier_buffer);
// Strip out dashes
size_t pos;
while ((pos = module_identifier.find('-')) != string::npos) {
module_identifier.erase(pos, 1);
}
// And append a zero, because module IDs include an "age" field
// which is always zero on Linux.
module_identifier += "0";
// Get some memory.
char* memory =

View File

@ -32,8 +32,6 @@
#include "client/linux/microdump_writer/microdump_writer.h"
#include <limits>
#include <sys/utsname.h>
#include "client/linux/dump_writer_common/thread_info.h"
@ -42,15 +40,11 @@
#include "client/linux/handler/microdump_extra_info.h"
#include "client/linux/log/log.h"
#include "client/linux/minidump_writer/linux_ptrace_dumper.h"
#include "common/linux/file_id.h"
#include "common/linux/linux_libc_support.h"
#include "common/memory.h"
namespace {
using google_breakpad::auto_wasteful_vector;
using google_breakpad::ExceptionHandler;
using google_breakpad::kDefaultBuildIdSize;
using google_breakpad::LinuxDumper;
using google_breakpad::LinuxPtraceDumper;
using google_breakpad::MappingInfo;
@ -62,72 +56,6 @@ using google_breakpad::UContextReader;
const size_t kLineBufferSize = 2048;
#if !defined(__LP64__)
// The following are only used by DumpFreeSpace, so need to be compiled
// in conditionally in the same way.
template <typename Dst, typename Src>
Dst saturated_cast(Src src) {
if (src >= std::numeric_limits<Dst>::max())
return std::numeric_limits<Dst>::max();
if (src <= std::numeric_limits<Dst>::min())
return std::numeric_limits<Dst>::min();
return static_cast<Dst>(src);
}
int Log2Floor(uint64_t n) {
// Copied from chromium src/base/bits.h
if (n == 0)
return -1;
int log = 0;
uint64_t value = n;
for (int i = 5; i >= 0; --i) {
int shift = (1 << i);
uint64_t x = value >> shift;
if (x != 0) {
value = x;
log += shift;
}
}
assert(value == 1u);
return log;
}
bool MappingsAreAdjacent(const MappingInfo& a, const MappingInfo& b) {
// Because of load biasing, we can end up with a situation where two
// mappings actually overlap. So we will define adjacency to also include a
// b start address that lies within a's address range (including starting
// immediately after a).
// Because load biasing only ever moves the start address backwards, the end
// address should still increase.
return a.start_addr <= b.start_addr && a.start_addr + a.size >= b.start_addr;
}
bool MappingLessThan(const MappingInfo* a, const MappingInfo* b) {
// Return true if mapping a is before mapping b.
// For the same reason (load biasing) we compare end addresses, which - unlike
// start addresses - will not have been modified.
return a->start_addr + a->size < b->start_addr + b->size;
}
size_t NextOrderedMapping(
const google_breakpad::wasteful_vector<MappingInfo*>& mappings,
size_t curr) {
// Find the mapping that directly follows mappings[curr].
// If no such mapping exists, return |invalid| to indicate this.
const size_t invalid = std::numeric_limits<size_t>::max();
size_t best = invalid;
for (size_t next = 0; next < mappings.size(); ++next) {
if (MappingLessThan(mappings[curr], mappings[next]) &&
(best == invalid || MappingLessThan(mappings[next], mappings[best]))) {
best = next;
}
}
return best;
}
#endif // !__LP64__
class MicrodumpWriter {
public:
MicrodumpWriter(const ExceptionHandler::CrashContext* context,
@ -165,9 +93,6 @@ class MicrodumpWriter {
DumpProductInformation();
DumpOSInformation();
DumpGPUInformation();
#if !defined(__LP64__)
DumpFreeSpace();
#endif
success = DumpCrashingThread();
if (success)
success = DumpMappings();
@ -411,31 +336,21 @@ class MicrodumpWriter {
bool member,
unsigned int mapping_id,
const uint8_t* identifier) {
auto_wasteful_vector<uint8_t, kDefaultBuildIdSize> identifier_bytes(
dumper_->allocator());
MDGUID module_identifier;
if (identifier) {
// GUID was provided by caller.
identifier_bytes.insert(identifier_bytes.end(),
identifier,
identifier + sizeof(MDGUID));
my_memcpy(&module_identifier, identifier, sizeof(MDGUID));
} else {
dumper_->ElfFileIdentifierForMapping(
mapping,
member,
mapping_id,
identifier_bytes);
reinterpret_cast<uint8_t*>(&module_identifier));
}
// Copy as many bytes of |identifier| as will fit into a MDGUID
MDGUID module_identifier = {0};
memcpy(&module_identifier, &identifier_bytes[0],
std::min(sizeof(MDGUID), identifier_bytes.size()));
char file_name[NAME_MAX];
char file_path[NAME_MAX];
dumper_->GetMappingEffectiveNameAndPath(
LinuxDumper::GetMappingEffectiveNameAndPath(
mapping, file_path, sizeof(file_path), file_name, sizeof(file_name));
LogAppend("M ");
@ -461,80 +376,6 @@ class MicrodumpWriter {
LogCommitLine();
}
#if !defined(__LP64__)
void DumpFreeSpace() {
const google_breakpad::wasteful_vector<MappingInfo*>& mappings =
dumper_->mappings();
if (mappings.size() == 0) return;
// This is complicated by the fact that mappings is not in order. It should
// be mostly in order, however the mapping that contains the entry point for
// the process is always at the front of the vector.
static const int HBITS = sizeof(size_t) * 8;
size_t hole_histogram[HBITS];
my_memset(hole_histogram, 0, sizeof(hole_histogram));
// Find the lowest address mapping.
size_t curr = 0;
for (size_t i = 1; i < mappings.size(); ++i) {
if (mappings[i]->start_addr < mappings[curr]->start_addr) curr = i;
}
uintptr_t lo_addr = mappings[curr]->start_addr;
size_t hole_cnt = 0;
size_t hole_max = 0;
size_t hole_sum = 0;
while (true) {
// Skip to the end of an adjacent run of mappings. This is an optimization
// for the fact that mappings is mostly sorted.
while (curr != mappings.size() - 1 &&
MappingsAreAdjacent(*mappings[curr], *mappings[curr + 1])) {
++curr;
}
size_t next = NextOrderedMapping(mappings, curr);
if (next == std::numeric_limits<size_t>::max())
break;
uintptr_t hole_lo = mappings[curr]->start_addr + mappings[curr]->size;
uintptr_t hole_hi = mappings[next]->start_addr;
if (hole_hi > hole_lo) {
size_t hole_sz = hole_hi - hole_lo;
hole_sum += hole_sz;
hole_max = std::max(hole_sz, hole_max);
++hole_cnt;
++hole_histogram[Log2Floor(hole_sz)];
}
curr = next;
}
uintptr_t hi_addr = mappings[curr]->start_addr + mappings[curr]->size;
LogAppend("H ");
LogAppend(lo_addr);
LogAppend(" ");
LogAppend(hi_addr);
LogAppend(" ");
LogAppend(saturated_cast<uint16_t>(hole_cnt));
LogAppend(" ");
LogAppend(hole_max);
LogAppend(" ");
LogAppend(hole_sum);
for (unsigned int i = 0; i < HBITS; ++i) {
if (!hole_histogram[i]) continue;
LogAppend(" ");
LogAppend(saturated_cast<uint8_t>(i));
LogAppend(":");
LogAppend(saturated_cast<uint8_t>(hole_histogram[i]));
}
LogCommitLine();
}
#endif
// Write information about the mappings in effect.
bool DumpMappings() {
// First write all the mappings from the dumper

View File

@ -49,9 +49,8 @@ namespace google_breakpad {
LinuxCoreDumper::LinuxCoreDumper(pid_t pid,
const char* core_path,
const char* procfs_path,
const char* root_prefix)
: LinuxDumper(pid, root_prefix),
const char* procfs_path)
: LinuxDumper(pid),
core_path_(core_path),
procfs_path_(procfs_path),
thread_infos_(&allocator_, 8) {

View File

@ -47,9 +47,7 @@ class LinuxCoreDumper : public LinuxDumper {
// its proc files at |procfs_path|. If |procfs_path| is a copy of
// /proc/<pid>, it should contain the following files:
// auxv, cmdline, environ, exe, maps, status
// See LinuxDumper for the purpose of |root_prefix|.
LinuxCoreDumper(pid_t pid, const char* core_path, const char* procfs_path,
const char* root_prefix = "");
LinuxCoreDumper(pid_t pid, const char* core_path, const char* procfs_path);
// Implements LinuxDumper::BuildProcPath().
// Builds a proc path for a certain pid for a node (/proc/<pid>/<node>).

View File

@ -39,16 +39,6 @@
using namespace google_breakpad;
TEST(LinuxCoreDumperTest, GetMappingAbsolutePath) {
const LinuxCoreDumper dumper(getpid(), "core", "/tmp", "/mnt/root");
const MappingInfo mapping = { 0, 0, 0, false, "/usr/lib/libc.so" };
char path[PATH_MAX];
dumper.GetMappingAbsolutePath(mapping, path);
EXPECT_STREQ("/mnt/root/usr/lib/libc.so", path);
}
TEST(LinuxCoreDumperTest, BuildProcPath) {
const pid_t pid = getpid();
const char procfs_path[] = "/procfs_copy";

View File

@ -70,6 +70,7 @@ static const int DT_ANDROID_RELA = DT_LOOS + 4;
static const char kMappedFileUnsafePrefix[] = "/dev/";
static const char kDeletedSuffix[] = " (deleted)";
static const char kReservedFlags[] = " ---p";
inline static bool IsMappedFileOpenUnsafe(
const google_breakpad::MappingInfo& mapping) {
@ -87,16 +88,14 @@ namespace google_breakpad {
// All interesting auvx entry types are below AT_SYSINFO_EHDR
#define AT_MAX AT_SYSINFO_EHDR
LinuxDumper::LinuxDumper(pid_t pid, const char* root_prefix)
LinuxDumper::LinuxDumper(pid_t pid)
: pid_(pid),
root_prefix_(root_prefix),
crash_address_(0),
crash_signal_(0),
crash_thread_(pid),
threads_(&allocator_, 8),
mappings_(&allocator_),
auxv_(&allocator_, AT_MAX + 1) {
assert(root_prefix_ && my_strlen(root_prefix_) < PATH_MAX);
// The passed-in size to the constructor (above) is only a hint.
// Must call .resize() to do actual initialization of the elements.
auxv_.resize(AT_MAX + 1);
@ -120,8 +119,9 @@ bool
LinuxDumper::ElfFileIdentifierForMapping(const MappingInfo& mapping,
bool member,
unsigned int mapping_id,
wasteful_vector<uint8_t>& identifier) {
uint8_t identifier[sizeof(MDGUID)]) {
assert(!member || mapping_id < mappings_.size());
my_memset(identifier, 0, sizeof(MDGUID));
if (IsMappedFileOpenUnsafe(mapping))
return false;
@ -139,9 +139,14 @@ LinuxDumper::ElfFileIdentifierForMapping(const MappingInfo& mapping,
return FileID::ElfFileIdentifierFromMappedFile(linux_gate, identifier);
}
char filename[PATH_MAX];
if (!GetMappingAbsolutePath(mapping, filename))
char filename[NAME_MAX];
size_t filename_len = my_strlen(mapping.name);
if (filename_len >= NAME_MAX) {
assert(false);
return false;
}
my_memcpy(filename, mapping.name, filename_len);
filename[filename_len] = '\0';
bool filename_modified = HandleDeletedFileInMapping(filename);
MemoryMappedFile mapped_file(filename, mapping.offset);
@ -151,19 +156,13 @@ LinuxDumper::ElfFileIdentifierForMapping(const MappingInfo& mapping,
bool success =
FileID::ElfFileIdentifierFromMappedFile(mapped_file.data(), identifier);
if (success && member && filename_modified) {
mappings_[mapping_id]->name[my_strlen(mapping.name) -
mappings_[mapping_id]->name[filename_len -
sizeof(kDeletedSuffix) + 1] = '\0';
}
return success;
}
bool LinuxDumper::GetMappingAbsolutePath(const MappingInfo& mapping,
char path[PATH_MAX]) const {
return my_strlcpy(path, root_prefix_, PATH_MAX) < PATH_MAX &&
my_strlcat(path, mapping.name, PATH_MAX) < PATH_MAX;
}
namespace {
bool ElfFileSoNameFromMappedFile(
const void* elf_base, char* soname, size_t soname_size) {
@ -213,16 +212,23 @@ bool ElfFileSoNameFromMappedFile(
// for |mapping|. If the SONAME is found copy it into the passed buffer
// |soname| and return true. The size of the buffer is |soname_size|.
// The SONAME will be truncated if it is too long to fit in the buffer.
bool ElfFileSoName(const LinuxDumper& dumper,
bool ElfFileSoName(
const MappingInfo& mapping, char* soname, size_t soname_size) {
if (IsMappedFileOpenUnsafe(mapping)) {
// Not safe
return false;
}
char filename[PATH_MAX];
if (!dumper.GetMappingAbsolutePath(mapping, filename))
char filename[NAME_MAX];
size_t filename_len = my_strlen(mapping.name);
if (filename_len >= NAME_MAX) {
assert(false);
// name too long
return false;
}
my_memcpy(filename, mapping.name, filename_len);
filename[filename_len] = '\0';
MemoryMappedFile mapped_file(filename, mapping.offset);
if (!mapped_file.data() || mapped_file.size() < SELFMAG) {
@ -236,6 +242,7 @@ bool ElfFileSoName(const LinuxDumper& dumper,
} // namespace
// static
void LinuxDumper::GetMappingEffectiveNameAndPath(const MappingInfo& mapping,
char* file_path,
size_t file_path_size,
@ -248,10 +255,8 @@ void LinuxDumper::GetMappingEffectiveNameAndPath(const MappingInfo& mapping,
// apk on Android). We try to find the name of the shared object (SONAME) by
// looking in the file for ELF sections.
bool mapped_from_archive = false;
if (mapping.exec && mapping.offset != 0) {
mapped_from_archive =
ElfFileSoName(*this, mapping, file_name, file_name_size);
}
if (mapping.exec && mapping.offset != 0)
mapped_from_archive = ElfFileSoName(mapping, file_name, file_name_size);
if (mapped_from_archive) {
// Some tools (e.g., stackwalk) extract the basename from the pathname. In
@ -349,8 +354,24 @@ bool LinuxDumper::EnumerateMappings() {
MappingInfo* module = mappings_.back();
if ((start_addr == module->start_addr + module->size) &&
(my_strlen(name) == my_strlen(module->name)) &&
(my_strncmp(name, module->name, my_strlen(name)) == 0) &&
(exec == module->exec)) {
(my_strncmp(name, module->name, my_strlen(name)) == 0)) {
module->size = end_addr - module->start_addr;
line_reader->PopLine(line_len);
continue;
}
}
// Also merge mappings that result from address ranges that the
// linker reserved but which a loaded library did not use. These
// appear as an anonymous private mapping with no access flags set
// and which directly follow an executable mapping.
if (!name && !mappings_.empty()) {
MappingInfo* module = mappings_.back();
if ((start_addr == module->start_addr + module->size) &&
module->exec &&
module->name[0] == '/' &&
offset == 0 && my_strncmp(i2,
kReservedFlags,
sizeof(kReservedFlags) - 1) == 0) {
module->size = end_addr - module->start_addr;
line_reader->PopLine(line_len);
continue;
@ -559,13 +580,10 @@ bool LinuxDumper::HandleDeletedFileInMapping(char* path) const {
// Check |path| against the /proc/pid/exe 'symlink'.
char exe_link[NAME_MAX];
char new_path[NAME_MAX];
if (!BuildProcPath(exe_link, pid_, "exe"))
return false;
MappingInfo new_mapping = {0};
if (!SafeReadLink(exe_link, new_mapping.name))
return false;
char new_path[PATH_MAX];
if (!GetMappingAbsolutePath(new_mapping, new_path))
if (!SafeReadLink(exe_link, new_path))
return false;
if (my_strcmp(path, new_path) != 0)
return false;

View File

@ -49,7 +49,6 @@
#include "client/linux/dump_writer_common/mapping_info.h"
#include "client/linux/dump_writer_common/thread_info.h"
#include "common/linux/file_id.h"
#include "common/memory.h"
#include "google_breakpad/common/minidump_format.h"
@ -73,9 +72,7 @@ const char kLinuxGateLibraryName[] = "linux-gate.so";
class LinuxDumper {
public:
// The |root_prefix| is prepended to mapping paths before opening them, which
// is useful if the crash originates from a chroot.
explicit LinuxDumper(pid_t pid, const char* root_prefix = "");
explicit LinuxDumper(pid_t pid);
virtual ~LinuxDumper();
@ -130,7 +127,7 @@ class LinuxDumper {
bool ElfFileIdentifierForMapping(const MappingInfo& mapping,
bool member,
unsigned int mapping_id,
wasteful_vector<uint8_t>& identifier);
uint8_t identifier[sizeof(MDGUID)]);
uintptr_t crash_address() const { return crash_address_; }
void set_crash_address(uintptr_t crash_address) {
@ -143,21 +140,16 @@ class LinuxDumper {
pid_t crash_thread() const { return crash_thread_; }
void set_crash_thread(pid_t crash_thread) { crash_thread_ = crash_thread; }
// Concatenates the |root_prefix_| and |mapping| path. Writes into |path| and
// returns true unless the string is too long.
bool GetMappingAbsolutePath(const MappingInfo& mapping,
char path[PATH_MAX]) const;
// Extracts the effective path and file name of from |mapping|. In most cases
// the effective name/path are just the mapping's path and basename. In some
// other cases, however, a library can be mapped from an archive (e.g., when
// loading .so libs from an apk on Android) and this method is able to
// reconstruct the original file name.
void GetMappingEffectiveNameAndPath(const MappingInfo& mapping,
char* file_path,
size_t file_path_size,
char* file_name,
size_t file_name_size);
static void GetMappingEffectiveNameAndPath(const MappingInfo& mapping,
char* file_path,
size_t file_path_size,
char* file_name,
size_t file_name_size);
protected:
bool ReadAuxv();
@ -180,9 +172,6 @@ class LinuxDumper {
// ID of the crashed process.
const pid_t pid_;
// Path of the root directory to which mapping paths are relative.
const char* const root_prefix_;
// Virtual address at which the process crashed.
uintptr_t crash_address_;

View File

@ -66,7 +66,6 @@ using namespace google_breakpad;
namespace {
typedef wasteful_vector<uint8_t> id_vector;
typedef testing::Test LinuxPtraceDumperTest;
/* Fixture for running tests in a child process. */
@ -106,17 +105,11 @@ class LinuxPtraceDumperChildTest : public testing::Test {
* This is achieved by defining a TestBody macro further below.
*/
virtual void RealTestBody() = 0;
id_vector make_vector() {
return id_vector(&allocator, kDefaultBuildIdSize);
}
private:
static const int kFatalFailure = 1;
static const int kNonFatalFailure = 2;
pid_t child_pid_;
PageAllocator allocator;
};
} // namespace
@ -317,15 +310,14 @@ TEST_F(LinuxPtraceDumperChildTest, LinuxGateMappingID) {
// Need to suspend the child so ptrace actually works.
ASSERT_TRUE(dumper.ThreadsSuspend());
id_vector identifier(make_vector());
uint8_t identifier[sizeof(MDGUID)];
ASSERT_TRUE(dumper.ElfFileIdentifierForMapping(*mappings[index],
true,
index,
identifier));
id_vector empty_identifier(make_vector());
empty_identifier.resize(kDefaultBuildIdSize, 0);
EXPECT_NE(empty_identifier, identifier);
uint8_t empty_identifier[sizeof(MDGUID)];
memset(empty_identifier, 0, sizeof(empty_identifier));
EXPECT_NE(0, memcmp(empty_identifier, identifier, sizeof(identifier)));
EXPECT_TRUE(dumper.ThreadsResume());
}
#endif
@ -351,18 +343,19 @@ TEST_F(LinuxPtraceDumperChildTest, FileIDsMatch) {
}
ASSERT_TRUE(found_exe);
id_vector identifier1(make_vector());
id_vector identifier2(make_vector());
uint8_t identifier1[sizeof(MDGUID)];
uint8_t identifier2[sizeof(MDGUID)];
EXPECT_TRUE(dumper.ElfFileIdentifierForMapping(*mappings[i], true, i,
identifier1));
FileID fileid(exe_name);
EXPECT_TRUE(fileid.ElfFileIdentifier(identifier2));
string identifier_string1 =
FileID::ConvertIdentifierToUUIDString(identifier1);
string identifier_string2 =
FileID::ConvertIdentifierToUUIDString(identifier2);
EXPECT_EQ(identifier_string1, identifier_string2);
char identifier_string1[37];
char identifier_string2[37];
FileID::ConvertIdentifierToString(identifier1, identifier_string1,
37);
FileID::ConvertIdentifierToString(identifier2, identifier_string2,
37);
EXPECT_STREQ(identifier_string1, identifier_string2);
}
/* Get back to normal behavior of TEST*() macros wrt TestBody. */

View File

@ -73,7 +73,6 @@
#include "client/linux/minidump_writer/linux_ptrace_dumper.h"
#include "client/linux/minidump_writer/proc_cpuinfo_reader.h"
#include "client/minidump_file_writer.h"
#include "common/linux/file_id.h"
#include "common/linux/linux_libc_support.h"
#include "common/minidump_type_helper.h"
#include "google_breakpad/common/minidump_format.h"
@ -82,10 +81,8 @@
namespace {
using google_breakpad::AppMemoryList;
using google_breakpad::auto_wasteful_vector;
using google_breakpad::ExceptionHandler;
using google_breakpad::CpuSet;
using google_breakpad::kDefaultBuildIdSize;
using google_breakpad::LineReader;
using google_breakpad::LinuxDumper;
using google_breakpad::LinuxPtraceDumper;
@ -275,14 +272,6 @@ class MinidumpWriter {
if (max_stack_len >= 0 &&
stack_len > static_cast<unsigned int>(max_stack_len)) {
stack_len = max_stack_len;
// Skip empty chunks of length max_stack_len.
uintptr_t int_stack = reinterpret_cast<uintptr_t>(stack);
if (max_stack_len > 0) {
while (int_stack + max_stack_len < stack_pointer) {
int_stack += max_stack_len;
}
}
stack = reinterpret_cast<const void*>(int_stack);
}
if (!memory.Allocate(stack_len))
return false;
@ -557,40 +546,41 @@ class MinidumpWriter {
mod->base_of_image = mapping.start_addr;
mod->size_of_image = mapping.size;
auto_wasteful_vector<uint8_t, kDefaultBuildIdSize> identifier_bytes(
dumper_->allocator());
uint8_t cv_buf[MDCVInfoPDB70_minsize + NAME_MAX];
uint8_t* cv_ptr = cv_buf;
const uint32_t cv_signature = MD_CVINFOPDB70_SIGNATURE;
my_memcpy(cv_ptr, &cv_signature, sizeof(cv_signature));
cv_ptr += sizeof(cv_signature);
uint8_t* signature = cv_ptr;
cv_ptr += sizeof(MDGUID);
if (identifier) {
// GUID was provided by caller.
identifier_bytes.insert(identifier_bytes.end(),
identifier,
identifier + sizeof(MDGUID));
my_memcpy(signature, identifier, sizeof(MDGUID));
} else {
// Note: ElfFileIdentifierForMapping() can manipulate the |mapping.name|.
dumper_->ElfFileIdentifierForMapping(mapping,
member,
mapping_id,
identifier_bytes);
}
if (!identifier_bytes.empty()) {
UntypedMDRVA cv(&minidump_writer_);
if (!cv.Allocate(MDCVInfoELF_minsize + identifier_bytes.size()))
return false;
const uint32_t cv_signature = MD_CVINFOELF_SIGNATURE;
cv.Copy(&cv_signature, sizeof(cv_signature));
cv.Copy(cv.position() + sizeof(cv_signature), &identifier_bytes[0],
identifier_bytes.size());
mod->cv_record = cv.location();
dumper_->ElfFileIdentifierForMapping(mapping, member,
mapping_id, signature);
}
my_memset(cv_ptr, 0, sizeof(uint32_t)); // Set age to 0 on Linux.
cv_ptr += sizeof(uint32_t);
char file_name[NAME_MAX];
char file_path[NAME_MAX];
dumper_->GetMappingEffectiveNameAndPath(
LinuxDumper::GetMappingEffectiveNameAndPath(
mapping, file_path, sizeof(file_path), file_name, sizeof(file_name));
const size_t file_name_len = my_strlen(file_name);
UntypedMDRVA cv(&minidump_writer_);
if (!cv.Allocate(MDCVInfoPDB70_minsize + file_name_len + 1))
return false;
// Write pdb_file_name
my_memcpy(cv_ptr, file_name, file_name_len + 1);
cv.Copy(cv_buf, MDCVInfoPDB70_minsize + file_name_len + 1);
mod->cv_record = cv.location();
MDLocationDescriptor ld;
if (!minidump_writer_.WriteString(file_path, my_strlen(file_path), &ld))
return false;

View File

@ -54,6 +54,10 @@
using namespace google_breakpad;
// Length of a formatted GUID string =
// sizeof(MDGUID) * 2 + 4 (for dashes) + 1 (null terminator)
const int kGUIDStringSize = 37;
namespace {
typedef testing::Test MinidumpWriterTest;
@ -133,7 +137,19 @@ TEST(MinidumpWriterTest, MappingInfo) {
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
};
const string module_identifier = "33221100554477668899AABBCCDDEEFF0";
char module_identifier_buffer[kGUIDStringSize];
FileID::ConvertIdentifierToString(kModuleGUID,
module_identifier_buffer,
sizeof(module_identifier_buffer));
string module_identifier(module_identifier_buffer);
// Strip out dashes
size_t pos;
while ((pos = module_identifier.find('-')) != string::npos) {
module_identifier.erase(pos, 1);
}
// And append a zero, because module IDs include an "age" field
// which is always zero on Linux.
module_identifier += "0";
// Get some memory.
char* memory =
@ -214,53 +230,6 @@ TEST(MinidumpWriterTest, MappingInfo) {
close(fds[1]);
}
// Test that a binary with a longer-than-usual build id note
// makes its way all the way through to the minidump unscathed.
// The linux_client_unittest is linked with an explicit --build-id
// in Makefile.am.
TEST(MinidumpWriterTest, BuildIDLong) {
int fds[2];
ASSERT_NE(-1, pipe(fds));
const pid_t child = fork();
if (child == 0) {
close(fds[1]);
char b;
IGNORE_RET(HANDLE_EINTR(read(fds[0], &b, sizeof(b))));
close(fds[0]);
syscall(__NR_exit);
}
close(fds[0]);
ExceptionHandler::CrashContext context;
memset(&context, 0, sizeof(context));
ASSERT_EQ(0, getcontext(&context.context));
context.tid = child;
AutoTempDir temp_dir;
const string dump_path = temp_dir.path() + kMDWriterUnitTestFileName;
EXPECT_TRUE(WriteMinidump(dump_path.c_str(),
child, &context, sizeof(context)));
close(fds[1]);
// Read the minidump. Load the module list, and ensure that
// the main module has the correct debug id and code id.
Minidump minidump(dump_path);
ASSERT_TRUE(minidump.Read());
MinidumpModuleList* module_list = minidump.GetModuleList();
ASSERT_TRUE(module_list);
const MinidumpModule* module = module_list->GetMainModule();
ASSERT_TRUE(module);
const string module_identifier = "030201000504070608090A0B0C0D0E0F0";
// This is passed explicitly to the linker in Makefile.am
const string build_id =
"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f";
EXPECT_EQ(module_identifier, module->debug_identifier());
EXPECT_EQ(build_id, module->code_identifier());
}
// Test that mapping info can be specified, and that it overrides
// existing mappings that are wholly contained within the specified
// range.
@ -276,7 +245,19 @@ TEST(MinidumpWriterTest, MappingInfoContained) {
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
};
const string module_identifier = "33221100554477668899AABBCCDDEEFF0";
char module_identifier_buffer[kGUIDStringSize];
FileID::ConvertIdentifierToString(kModuleGUID,
module_identifier_buffer,
sizeof(module_identifier_buffer));
string module_identifier(module_identifier_buffer);
// Strip out dashes
size_t pos;
while ((pos = module_identifier.find('-')) != string::npos) {
module_identifier.erase(pos, 1);
}
// And append a zero, because module IDs include an "age" field
// which is always zero on Linux.
module_identifier += "0";
// mmap a file
AutoTempDir temp_dir;
@ -429,10 +410,12 @@ TEST(MinidumpWriterTest, DeletedBinary) {
EXPECT_STREQ(binpath.c_str(), module->code_file().c_str());
// Check that the file ID is correct.
FileID fileid(helper_path.c_str());
PageAllocator allocator;
wasteful_vector<uint8_t> identifier(&allocator, kDefaultBuildIdSize);
uint8_t identifier[sizeof(MDGUID)];
EXPECT_TRUE(fileid.ElfFileIdentifier(identifier));
string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier);
char identifier_string[kGUIDStringSize];
FileID::ConvertIdentifierToString(identifier,
identifier_string,
kGUIDStringSize);
string module_identifier(identifier_string);
// Strip out dashes
size_t pos;

View File

@ -583,6 +583,7 @@
4DBE4769134A4F080072546A /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; };
8B31007011F0CD3C00FCF3E4 /* GTMDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GTMDefines.h; path = ../../common/mac/GTMDefines.h; sourceTree = SOURCE_ROOT; };
8B3101E911F0CDE300FCF3E4 /* SenTestingKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SenTestingKit.framework; path = Library/Frameworks/SenTestingKit.framework; sourceTree = DEVELOPER_DIR; };
8B31022211F0CE1000FCF3E4 /* GTMGarbageCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GTMGarbageCollection.h; path = ../../common/mac/GTMGarbageCollection.h; sourceTree = SOURCE_ROOT; };
8B31027711F0D3AF00FCF3E4 /* BreakpadDebug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = BreakpadDebug.xcconfig; path = ../../common/mac/BreakpadDebug.xcconfig; sourceTree = SOURCE_ROOT; };
8B31027811F0D3AF00FCF3E4 /* BreakpadRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = BreakpadRelease.xcconfig; path = ../../common/mac/BreakpadRelease.xcconfig; sourceTree = SOURCE_ROOT; };
8B31FFF611F0C90500FCF3E4 /* Breakpad.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Breakpad.xcconfig; path = ../../common/mac/Breakpad.xcconfig; sourceTree = SOURCE_ROOT; };
@ -954,6 +955,7 @@
children = (
162F64F0161C577500CD68D5 /* arch_utilities.cc */,
162F64F1161C577500CD68D5 /* arch_utilities.h */,
8B31022211F0CE1000FCF3E4 /* GTMGarbageCollection.h */,
8B31007011F0CD3C00FCF3E4 /* GTMDefines.h */,
F9C77E0F0F7DDF650045F7DB /* testing */,
F9C44EE70EF0A3C1003AEBAA /* GTMLogger.h */,

View File

@ -75,8 +75,6 @@
'dwarf/dwarf2reader.cc',
'dwarf/dwarf2reader.h',
'dwarf/dwarf2reader_test_common.h',
'dwarf/elf_reader.cc',
'dwarf/elf_reader.h',
'dwarf/functioninfo.cc',
'dwarf/functioninfo.h',
'dwarf/line_state_machine.h',

View File

@ -243,8 +243,4 @@ uint64 ByteReader::ReadEncodedPointer(const uint8_t *buffer,
return pointer;
}
Endianness ByteReader::GetEndianness() const {
return endian_;
}
} // namespace dwarf2reader

View File

@ -280,7 +280,6 @@ class ByteReader {
DwarfPointerEncoding encoding,
size_t *len) const;
Endianness GetEndianness() const;
private:
// Function pointer type for our address and offset readers.

View File

@ -149,10 +149,7 @@ enum DwarfForm {
DW_FORM_sec_offset = 0x17,
DW_FORM_exprloc = 0x18,
DW_FORM_flag_present = 0x19,
DW_FORM_ref_sig8 = 0x20,
// Extensions for Fission. See http://gcc.gnu.org/wiki/DebugFission.
DW_FORM_GNU_addr_index = 0x1f01,
DW_FORM_GNU_str_index = 0x1f02
DW_FORM_ref_sig8 = 0x20
};
// Attribute names and codes
@ -267,13 +264,6 @@ enum DwarfAttribute {
DW_AT_body_begin = 0x2105,
DW_AT_body_end = 0x2106,
DW_AT_GNU_vector = 0x2107,
// Extensions for Fission. See http://gcc.gnu.org/wiki/DebugFission.
DW_AT_GNU_dwo_name = 0x2130,
DW_AT_GNU_dwo_id = 0x2131,
DW_AT_GNU_ranges_base = 0x2132,
DW_AT_GNU_addr_base = 0x2133,
DW_AT_GNU_pubnames = 0x2134,
DW_AT_GNU_pubtypes = 0x2135,
// VMS extensions.
DW_AT_VMS_rtnbeg_pd_address = 0x2201,
// UPC extension.
@ -501,22 +491,7 @@ enum DwarfOpcode {
DW_OP_lo_user =0xe0,
DW_OP_hi_user =0xff,
// GNU extensions
DW_OP_GNU_push_tls_address =0xe0,
// Extensions for Fission. See http://gcc.gnu.org/wiki/DebugFission.
DW_OP_GNU_addr_index =0xfb,
DW_OP_GNU_const_index =0xfc
};
// Section identifiers for DWP files
enum DwarfSectionId {
DW_SECT_INFO = 1,
DW_SECT_TYPES = 2,
DW_SECT_ABBREV = 3,
DW_SECT_LINE = 4,
DW_SECT_LOC = 5,
DW_SECT_STR_OFFSETS = 6,
DW_SECT_MACINFO = 7,
DW_SECT_MACRO = 8
DW_OP_GNU_push_tls_address =0xe0
};
// Source languages. These are values for DW_AT_language.

View File

@ -44,8 +44,6 @@
#include <string>
#include <utility>
#include <sys/stat.h>
#include "common/dwarf/bytereader-inl.h"
#include "common/dwarf/bytereader.h"
#include "common/dwarf/line_state_machine.h"
@ -53,38 +51,11 @@
namespace dwarf2reader {
CompilationUnit::CompilationUnit(const string& path,
const SectionMap& sections, uint64 offset,
CompilationUnit::CompilationUnit(const SectionMap& sections, uint64 offset,
ByteReader* reader, Dwarf2Handler* handler)
: path_(path), offset_from_section_start_(offset), reader_(reader),
sections_(sections), handler_(handler), abbrevs_(),
string_buffer_(NULL), string_buffer_length_(0),
str_offsets_buffer_(NULL), str_offsets_buffer_length_(0),
addr_buffer_(NULL), addr_buffer_length_(0),
is_split_dwarf_(false), dwo_id_(0), dwo_name_(),
skeleton_dwo_id_(0), ranges_base_(0), addr_base_(0),
have_checked_for_dwp_(false), dwp_path_(),
dwp_byte_reader_(), dwp_reader_() {}
// Initialize a compilation unit from a .dwo or .dwp file.
// In this case, we need the .debug_addr section from the
// executable file that contains the corresponding skeleton
// compilation unit. We also inherit the Dwarf2Handler from
// the executable file, and call it as if we were still
// processing the original compilation unit.
void CompilationUnit::SetSplitDwarf(const uint8_t* addr_buffer,
uint64 addr_buffer_length,
uint64 addr_base,
uint64 ranges_base,
uint64 dwo_id) {
is_split_dwarf_ = true;
addr_buffer_ = addr_buffer;
addr_buffer_length_ = addr_buffer_length;
addr_base_ = addr_base;
ranges_base_ = ranges_base;
skeleton_dwo_id_ = dwo_id;
}
: offset_from_section_start_(offset), reader_(reader),
sections_(sections), handler_(handler), abbrevs_(NULL),
string_buffer_(NULL), string_buffer_length_(0) {}
// Read a DWARF2/3 abbreviation section.
// Each abbrev consists of a abbreviation number, a tag, a byte
@ -203,8 +174,6 @@ const uint8_t *CompilationUnit::SkipAttribute(const uint8_t *start,
return start + strlen(reinterpret_cast<const char *>(start)) + 1;
case DW_FORM_udata:
case DW_FORM_ref_udata:
case DW_FORM_GNU_str_index:
case DW_FORM_GNU_addr_index:
reader_->ReadUnsignedLEB128(start, &len);
return start + len;
@ -266,9 +235,7 @@ void CompilationUnit::ReadHeader() {
header_.abbrev_offset = reader_->ReadOffset(headerptr);
headerptr += reader_->OffsetSize();
// Compare against less than or equal because this may be the last
// section in the file.
assert(headerptr + 1 <= buffer_ + buffer_length_);
assert(headerptr + 1 < buffer_ + buffer_length_);
header_.address_size = reader_->ReadOneByte(headerptr);
reader_->SetAddressSize(header_.address_size);
headerptr += 1;
@ -329,31 +296,9 @@ uint64 CompilationUnit::Start() {
string_buffer_length_ = iter->second.second;
}
// Set the string offsets section if we have one.
iter = sections_.find(".debug_str_offsets");
if (iter != sections_.end()) {
str_offsets_buffer_ = iter->second.first;
str_offsets_buffer_length_ = iter->second.second;
}
// Set the address section if we have one.
iter = sections_.find(".debug_addr");
if (iter != sections_.end()) {
addr_buffer_ = iter->second.first;
addr_buffer_length_ = iter->second.second;
}
// Now that we have our abbreviations, start processing DIE's.
ProcessDIEs();
// If this is a skeleton compilation unit generated with split DWARF,
// and the client needs the full debug info, we need to find the full
// compilation unit in a .dwo or .dwp file.
if (!is_split_dwarf_
&& dwo_name_ != NULL
&& handler_->NeedSplitDebugInfo())
ProcessSplitDwarf();
return ourlength;
}
@ -375,46 +320,48 @@ const uint8_t *CompilationUnit::ProcessAttribute(
return ProcessAttribute(dieoffset, start, attr, form);
case DW_FORM_flag_present:
ProcessAttributeUnsigned(dieoffset, attr, form, 1);
handler_->ProcessAttributeUnsigned(dieoffset, attr, form, 1);
return start;
case DW_FORM_data1:
case DW_FORM_flag:
ProcessAttributeUnsigned(dieoffset, attr, form,
reader_->ReadOneByte(start));
handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
reader_->ReadOneByte(start));
return start + 1;
case DW_FORM_data2:
ProcessAttributeUnsigned(dieoffset, attr, form,
reader_->ReadTwoBytes(start));
handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
reader_->ReadTwoBytes(start));
return start + 2;
case DW_FORM_data4:
ProcessAttributeUnsigned(dieoffset, attr, form,
reader_->ReadFourBytes(start));
handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
reader_->ReadFourBytes(start));
return start + 4;
case DW_FORM_data8:
ProcessAttributeUnsigned(dieoffset, attr, form,
reader_->ReadEightBytes(start));
handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
reader_->ReadEightBytes(start));
return start + 8;
case DW_FORM_string: {
const char *str = reinterpret_cast<const char *>(start);
ProcessAttributeString(dieoffset, attr, form, str);
handler_->ProcessAttributeString(dieoffset, attr, form,
str);
return start + strlen(str) + 1;
}
case DW_FORM_udata:
ProcessAttributeUnsigned(dieoffset, attr, form,
reader_->ReadUnsignedLEB128(start, &len));
handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
reader_->ReadUnsignedLEB128(start,
&len));
return start + len;
case DW_FORM_sdata:
ProcessAttributeSigned(dieoffset, attr, form,
reader_->ReadSignedLEB128(start, &len));
handler_->ProcessAttributeSigned(dieoffset, attr, form,
reader_->ReadSignedLEB128(start, &len));
return start + len;
case DW_FORM_addr:
ProcessAttributeUnsigned(dieoffset, attr, form,
reader_->ReadAddress(start));
handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
reader_->ReadAddress(start));
return start + reader_->AddressSize();
case DW_FORM_sec_offset:
ProcessAttributeUnsigned(dieoffset, attr, form,
reader_->ReadOffset(start));
handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
reader_->ReadOffset(start));
return start + reader_->OffsetSize();
case DW_FORM_ref1:
@ -494,32 +441,10 @@ const uint8_t *CompilationUnit::ProcessAttribute(
assert(string_buffer_ + offset < string_buffer_ + string_buffer_length_);
const char *str = reinterpret_cast<const char *>(string_buffer_ + offset);
ProcessAttributeString(dieoffset, attr, form, str);
handler_->ProcessAttributeString(dieoffset, attr, form,
str);
return start + reader_->OffsetSize();
}
case DW_FORM_GNU_str_index: {
uint64 str_index = reader_->ReadUnsignedLEB128(start, &len);
const uint8_t* offset_ptr =
str_offsets_buffer_ + str_index * reader_->OffsetSize();
const uint64 offset = reader_->ReadOffset(offset_ptr);
if (offset >= string_buffer_length_) {
return NULL;
}
const char* str = reinterpret_cast<const char *>(string_buffer_) + offset;
ProcessAttributeString(dieoffset, attr, form, str);
return start + len;
break;
}
case DW_FORM_GNU_addr_index: {
uint64 addr_index = reader_->ReadUnsignedLEB128(start, &len);
const uint8_t* addr_ptr =
addr_buffer_ + addr_base_ + addr_index * reader_->AddressSize();
ProcessAttributeUnsigned(dieoffset, attr, form,
reader_->ReadAddress(addr_ptr));
return start + len;
}
}
fprintf(stderr, "Unhandled form type\n");
return NULL;
@ -533,16 +458,6 @@ const uint8_t *CompilationUnit::ProcessDIE(uint64 dieoffset,
i++) {
start = ProcessAttribute(dieoffset, start, i->first, i->second);
}
// If this is a compilation unit in a split DWARF object, verify that
// the dwo_id matches. If it does not match, we will ignore this
// compilation unit.
if (abbrev.tag == DW_TAG_compile_unit
&& is_split_dwarf_
&& dwo_id_ != skeleton_dwo_id_) {
return NULL;
}
return start;
}
@ -600,307 +515,6 @@ void CompilationUnit::ProcessDIEs() {
}
}
// Check for a valid ELF file and return the Address size.
// Returns 0 if not a valid ELF file.
inline int GetElfWidth(const ElfReader& elf) {
if (elf.IsElf32File())
return 4;
if (elf.IsElf64File())
return 8;
return 0;
}
void CompilationUnit::ProcessSplitDwarf() {
struct stat statbuf;
if (!have_checked_for_dwp_) {
// Look for a .dwp file in the same directory as the executable.
have_checked_for_dwp_ = true;
string dwp_suffix(".dwp");
dwp_path_ = path_ + dwp_suffix;
if (stat(dwp_path_.c_str(), &statbuf) != 0) {
// Fall back to a split .debug file in the same directory.
string debug_suffix(".debug");
dwp_path_ = path_;
size_t found = path_.rfind(debug_suffix);
if (found + debug_suffix.length() == path_.length())
dwp_path_ = dwp_path_.replace(found, debug_suffix.length(), dwp_suffix);
}
if (stat(dwp_path_.c_str(), &statbuf) == 0) {
ElfReader* elf = new ElfReader(dwp_path_);
int width = GetElfWidth(*elf);
if (width != 0) {
dwp_byte_reader_.reset(new ByteReader(reader_->GetEndianness()));
dwp_byte_reader_->SetAddressSize(width);
dwp_reader_.reset(new DwpReader(*dwp_byte_reader_, elf));
dwp_reader_->Initialize();
} else {
delete elf;
}
}
}
bool found_in_dwp = false;
if (dwp_reader_) {
// If we have a .dwp file, read the debug sections for the requested CU.
SectionMap sections;
dwp_reader_->ReadDebugSectionsForCU(dwo_id_, &sections);
if (!sections.empty()) {
found_in_dwp = true;
CompilationUnit dwp_comp_unit(dwp_path_, sections, 0,
dwp_byte_reader_.get(), handler_);
dwp_comp_unit.SetSplitDwarf(addr_buffer_, addr_buffer_length_, addr_base_,
ranges_base_, dwo_id_);
dwp_comp_unit.Start();
}
}
if (!found_in_dwp) {
// If no .dwp file, try to open the .dwo file.
if (stat(dwo_name_, &statbuf) == 0) {
ElfReader elf(dwo_name_);
int width = GetElfWidth(elf);
if (width != 0) {
ByteReader reader(ENDIANNESS_LITTLE);
reader.SetAddressSize(width);
SectionMap sections;
ReadDebugSectionsFromDwo(&elf, &sections);
CompilationUnit dwo_comp_unit(dwo_name_, sections, 0, &reader,
handler_);
dwo_comp_unit.SetSplitDwarf(addr_buffer_, addr_buffer_length_,
addr_base_, ranges_base_, dwo_id_);
dwo_comp_unit.Start();
}
}
}
}
void CompilationUnit::ReadDebugSectionsFromDwo(ElfReader* elf_reader,
SectionMap* sections) {
static const char* const section_names[] = {
".debug_abbrev",
".debug_info",
".debug_str_offsets",
".debug_str"
};
for (unsigned int i = 0u;
i < sizeof(section_names)/sizeof(*(section_names)); ++i) {
string base_name = section_names[i];
string dwo_name = base_name + ".dwo";
size_t section_size;
const char* section_data = elf_reader->GetSectionByName(dwo_name,
&section_size);
if (section_data != NULL)
sections->insert(std::make_pair(
base_name, std::make_pair(
reinterpret_cast<const uint8_t *>(section_data),
section_size)));
}
}
DwpReader::DwpReader(const ByteReader& byte_reader, ElfReader* elf_reader)
: elf_reader_(elf_reader), byte_reader_(byte_reader),
cu_index_(NULL), cu_index_size_(0), string_buffer_(NULL),
string_buffer_size_(0), version_(0), ncolumns_(0), nunits_(0),
nslots_(0), phash_(NULL), pindex_(NULL), shndx_pool_(NULL),
offset_table_(NULL), size_table_(NULL), abbrev_data_(NULL),
abbrev_size_(0), info_data_(NULL), info_size_(0),
str_offsets_data_(NULL), str_offsets_size_(0) {}
DwpReader::~DwpReader() {
if (elf_reader_) delete elf_reader_;
}
void DwpReader::Initialize() {
cu_index_ = elf_reader_->GetSectionByName(".debug_cu_index",
&cu_index_size_);
if (cu_index_ == NULL) {
return;
}
// The .debug_str.dwo section is shared by all CUs in the file.
string_buffer_ = elf_reader_->GetSectionByName(".debug_str.dwo",
&string_buffer_size_);
version_ = byte_reader_.ReadFourBytes(
reinterpret_cast<const uint8_t *>(cu_index_));
if (version_ == 1) {
nslots_ = byte_reader_.ReadFourBytes(
reinterpret_cast<const uint8_t *>(cu_index_)
+ 3 * sizeof(uint32));
phash_ = cu_index_ + 4 * sizeof(uint32);
pindex_ = phash_ + nslots_ * sizeof(uint64);
shndx_pool_ = pindex_ + nslots_ * sizeof(uint32);
if (shndx_pool_ >= cu_index_ + cu_index_size_) {
version_ = 0;
}
} else if (version_ == 2) {
ncolumns_ = byte_reader_.ReadFourBytes(
reinterpret_cast<const uint8_t *>(cu_index_) + sizeof(uint32));
nunits_ = byte_reader_.ReadFourBytes(
reinterpret_cast<const uint8_t *>(cu_index_) + 2 * sizeof(uint32));
nslots_ = byte_reader_.ReadFourBytes(
reinterpret_cast<const uint8_t *>(cu_index_) + 3 * sizeof(uint32));
phash_ = cu_index_ + 4 * sizeof(uint32);
pindex_ = phash_ + nslots_ * sizeof(uint64);
offset_table_ = pindex_ + nslots_ * sizeof(uint32);
size_table_ = offset_table_ + ncolumns_ * (nunits_ + 1) * sizeof(uint32);
abbrev_data_ = elf_reader_->GetSectionByName(".debug_abbrev.dwo",
&abbrev_size_);
info_data_ = elf_reader_->GetSectionByName(".debug_info.dwo", &info_size_);
str_offsets_data_ = elf_reader_->GetSectionByName(".debug_str_offsets.dwo",
&str_offsets_size_);
if (size_table_ >= cu_index_ + cu_index_size_) {
version_ = 0;
}
}
}
void DwpReader::ReadDebugSectionsForCU(uint64 dwo_id,
SectionMap* sections) {
if (version_ == 1) {
int slot = LookupCU(dwo_id);
if (slot == -1) {
return;
}
// The index table points to the section index pool, where we
// can read a list of section indexes for the debug sections
// for the CU whose dwo_id we are looking for.
int index = byte_reader_.ReadFourBytes(
reinterpret_cast<const uint8_t *>(pindex_)
+ slot * sizeof(uint32));
const char* shndx_list = shndx_pool_ + index * sizeof(uint32);
for (;;) {
if (shndx_list >= cu_index_ + cu_index_size_) {
version_ = 0;
return;
}
unsigned int shndx = byte_reader_.ReadFourBytes(
reinterpret_cast<const uint8_t *>(shndx_list));
shndx_list += sizeof(uint32);
if (shndx == 0)
break;
const char* section_name = elf_reader_->GetSectionName(shndx);
size_t section_size;
const char* section_data;
// We're only interested in these four debug sections.
// The section names in the .dwo file end with ".dwo", but we
// add them to the sections table with their normal names.
if (!strncmp(section_name, ".debug_abbrev", strlen(".debug_abbrev"))) {
section_data = elf_reader_->GetSectionByIndex(shndx, &section_size);
sections->insert(std::make_pair(
".debug_abbrev",
std::make_pair(reinterpret_cast<const uint8_t *> (section_data),
section_size)));
} else if (!strncmp(section_name, ".debug_info", strlen(".debug_info"))) {
section_data = elf_reader_->GetSectionByIndex(shndx, &section_size);
sections->insert(std::make_pair(
".debug_info",
std::make_pair(reinterpret_cast<const uint8_t *> (section_data),
section_size)));
} else if (!strncmp(section_name, ".debug_str_offsets",
strlen(".debug_str_offsets"))) {
section_data = elf_reader_->GetSectionByIndex(shndx, &section_size);
sections->insert(std::make_pair(
".debug_str_offsets",
std::make_pair(reinterpret_cast<const uint8_t *> (section_data),
section_size)));
}
}
sections->insert(std::make_pair(
".debug_str",
std::make_pair(reinterpret_cast<const uint8_t *> (string_buffer_),
string_buffer_size_)));
} else if (version_ == 2) {
uint32 index = LookupCUv2(dwo_id);
if (index == 0) {
return;
}
// The index points to a row in each of the section offsets table
// and the section size table, where we can read the offsets and sizes
// of the contributions to each debug section from the CU whose dwo_id
// we are looking for. Row 0 of the section offsets table has the
// section ids for each column of the table. The size table begins
// with row 1.
const char* id_row = offset_table_;
const char* offset_row = offset_table_
+ index * ncolumns_ * sizeof(uint32);
const char* size_row =
size_table_ + (index - 1) * ncolumns_ * sizeof(uint32);
if (size_row + ncolumns_ * sizeof(uint32) > cu_index_ + cu_index_size_) {
version_ = 0;
return;
}
for (unsigned int col = 0u; col < ncolumns_; ++col) {
uint32 section_id =
byte_reader_.ReadFourBytes(reinterpret_cast<const uint8_t *>(id_row)
+ col * sizeof(uint32));
uint32 offset = byte_reader_.ReadFourBytes(
reinterpret_cast<const uint8_t *>(offset_row)
+ col * sizeof(uint32));
uint32 size = byte_reader_.ReadFourBytes(
reinterpret_cast<const uint8_t *>(size_row) + col * sizeof(uint32));
if (section_id == DW_SECT_ABBREV) {
sections->insert(std::make_pair(
".debug_abbrev",
std::make_pair(reinterpret_cast<const uint8_t *> (abbrev_data_)
+ offset, size)));
} else if (section_id == DW_SECT_INFO) {
sections->insert(std::make_pair(
".debug_info",
std::make_pair(reinterpret_cast<const uint8_t *> (info_data_)
+ offset, size)));
} else if (section_id == DW_SECT_STR_OFFSETS) {
sections->insert(std::make_pair(
".debug_str_offsets",
std::make_pair(reinterpret_cast<const uint8_t *> (str_offsets_data_)
+ offset, size)));
}
}
sections->insert(std::make_pair(
".debug_str",
std::make_pair(reinterpret_cast<const uint8_t *> (string_buffer_),
string_buffer_size_)));
}
}
int DwpReader::LookupCU(uint64 dwo_id) {
uint32 slot = static_cast<uint32>(dwo_id) & (nslots_ - 1);
uint64 probe = byte_reader_.ReadEightBytes(
reinterpret_cast<const uint8_t *>(phash_) + slot * sizeof(uint64));
if (probe != 0 && probe != dwo_id) {
uint32 secondary_hash =
(static_cast<uint32>(dwo_id >> 32) & (nslots_ - 1)) | 1;
do {
slot = (slot + secondary_hash) & (nslots_ - 1);
probe = byte_reader_.ReadEightBytes(
reinterpret_cast<const uint8_t *>(phash_) + slot * sizeof(uint64));
} while (probe != 0 && probe != dwo_id);
}
if (probe == 0)
return -1;
return slot;
}
uint32 DwpReader::LookupCUv2(uint64 dwo_id) {
uint32 slot = static_cast<uint32>(dwo_id) & (nslots_ - 1);
uint64 probe = byte_reader_.ReadEightBytes(
reinterpret_cast<const uint8_t *>(phash_) + slot * sizeof(uint64));
uint32 index = byte_reader_.ReadFourBytes(
reinterpret_cast<const uint8_t *>(pindex_) + slot * sizeof(uint32));
if (index != 0 && probe != dwo_id) {
uint32 secondary_hash =
(static_cast<uint32>(dwo_id >> 32) & (nslots_ - 1)) | 1;
do {
slot = (slot + secondary_hash) & (nslots_ - 1);
probe = byte_reader_.ReadEightBytes(
reinterpret_cast<const uint8_t *>(phash_) + slot * sizeof(uint64));
index = byte_reader_.ReadFourBytes(
reinterpret_cast<const uint8_t *>(pindex_) + slot * sizeof(uint32));
} while (index != 0 && probe != dwo_id);
}
return index;
}
LineInfo::LineInfo(const uint8_t *buffer, uint64 buffer_length,
ByteReader* reader, LineInfoHandler* handler):
handler_(handler), reader_(reader), buffer_(buffer) {

View File

@ -47,19 +47,16 @@
#include <string>
#include <utility>
#include <vector>
#include <memory>
#include "common/dwarf/bytereader.h"
#include "common/dwarf/dwarf2enums.h"
#include "common/dwarf/types.h"
#include "common/using_std_string.h"
#include "common/dwarf/elf_reader.h"
namespace dwarf2reader {
struct LineStateMachine;
class Dwarf2Handler;
class LineInfoHandler;
class DwpReader;
// This maps from a string naming a section to a pair containing a
// the data for the section, and the size of the section.
@ -187,10 +184,151 @@ class LineInfoHandler {
uint32 file_num, uint32 line_num, uint32 column_num) { }
};
// The base of DWARF2/3 debug info is a DIE (Debugging Information
// Entry.
// DWARF groups DIE's into a tree and calls the root of this tree a
// "compilation unit". Most of the time, there is one compilation
// unit in the .debug_info section for each file that had debug info
// generated.
// Each DIE consists of
// 1. a tag specifying a thing that is being described (ie
// DW_TAG_subprogram for functions, DW_TAG_variable for variables, etc
// 2. attributes (such as DW_AT_location for location in memory,
// DW_AT_name for name), and data for each attribute.
// 3. A flag saying whether the DIE has children or not
// In order to gain some amount of compression, the format of
// each DIE (tag name, attributes and data forms for the attributes)
// are stored in a separate table called the "abbreviation table".
// This is done because a large number of DIEs have the exact same tag
// and list of attributes, but different data for those attributes.
// As a result, the .debug_info section is just a stream of data, and
// requires reading of the .debug_abbrev section to say what the data
// means.
// As a warning to the user, it should be noted that the reason for
// using absolute offsets from the beginning of .debug_info is that
// DWARF2/3 supports referencing DIE's from other DIE's by their offset
// from either the current compilation unit start, *or* the beginning
// of the .debug_info section. This means it is possible to reference
// a DIE in one compilation unit from a DIE in another compilation
// unit. This style of reference is usually used to eliminate
// duplicated information that occurs across compilation
// units, such as base types, etc. GCC 3.4+ support this with
// -feliminate-dwarf2-dups. Other toolchains will sometimes do
// duplicate elimination in the linker.
class CompilationUnit {
public:
// Initialize a compilation unit. This requires a map of sections,
// the offset of this compilation unit in the .debug_info section, a
// ByteReader, and a Dwarf2Handler class to call callbacks in.
CompilationUnit(const SectionMap& sections, uint64 offset,
ByteReader* reader, Dwarf2Handler* handler);
virtual ~CompilationUnit() {
if (abbrevs_) delete abbrevs_;
}
// Begin reading a Dwarf2 compilation unit, and calling the
// callbacks in the Dwarf2Handler
// Return the full length of the compilation unit, including
// headers. This plus the starting offset passed to the constructor
// is the offset of the end of the compilation unit --- and the
// start of the next compilation unit, if there is one.
uint64 Start();
private:
// This struct represents a single DWARF2/3 abbreviation
// The abbreviation tells how to read a DWARF2/3 DIE, and consist of a
// tag and a list of attributes, as well as the data form of each attribute.
struct Abbrev {
uint64 number;
enum DwarfTag tag;
bool has_children;
AttributeList attributes;
};
// A DWARF2/3 compilation unit header. This is not the same size as
// in the actual file, as the one in the file may have a 32 bit or
// 64 bit length.
struct CompilationUnitHeader {
uint64 length;
uint16 version;
uint64 abbrev_offset;
uint8 address_size;
} header_;
// Reads the DWARF2/3 header for this compilation unit.
void ReadHeader();
// Reads the DWARF2/3 abbreviations for this compilation unit
void ReadAbbrevs();
// Processes a single DIE for this compilation unit and return a new
// pointer just past the end of it
const uint8_t *ProcessDIE(uint64 dieoffset,
const uint8_t *start,
const Abbrev& abbrev);
// Processes a single attribute and return a new pointer just past the
// end of it
const uint8_t *ProcessAttribute(uint64 dieoffset,
const uint8_t *start,
enum DwarfAttribute attr,
enum DwarfForm form);
// Processes all DIEs for this compilation unit
void ProcessDIEs();
// Skips the die with attributes specified in ABBREV starting at
// START, and return the new place to position the stream to.
const uint8_t *SkipDIE(const uint8_t *start, const Abbrev& abbrev);
// Skips the attribute starting at START, with FORM, and return the
// new place to position the stream to.
const uint8_t *SkipAttribute(const uint8_t *start, enum DwarfForm form);
// Offset from section start is the offset of this compilation unit
// from the beginning of the .debug_info section.
uint64 offset_from_section_start_;
// buffer is the buffer for our CU, starting at .debug_info + offset
// passed in from constructor.
// after_header points to right after the compilation unit header.
const uint8_t *buffer_;
uint64 buffer_length_;
const uint8_t *after_header_;
// The associated ByteReader that handles endianness issues for us
ByteReader* reader_;
// The map of sections in our file to buffers containing their data
const SectionMap& sections_;
// The associated handler to call processing functions in
Dwarf2Handler* handler_;
// Set of DWARF2/3 abbreviations for this compilation unit. Indexed
// by abbreviation number, which means that abbrevs_[0] is not
// valid.
std::vector<Abbrev>* abbrevs_;
// String section buffer and length, if we have a string section.
// This is here to avoid doing a section lookup for strings in
// ProcessAttribute, which is in the hot path for DWARF2 reading.
const uint8_t *string_buffer_;
uint64 string_buffer_length_;
};
// This class is the main interface between the reader and the
// client. The virtual functions inside this get called for
// interesting events that happen during DWARF2 reading.
// The default implementation skips everything.
class Dwarf2Handler {
public:
Dwarf2Handler() { }
@ -204,19 +342,6 @@ class Dwarf2Handler {
uint8 offset_size, uint64 cu_length,
uint8 dwarf_version) { return false; }
// When processing a skeleton compilation unit, resulting from a split
// DWARF compilation, once the skeleton debug info has been read,
// the reader will call this function to ask the client if it needs
// the full debug info from the .dwo or .dwp file. Return true if
// you need it, or false to skip processing the split debug info.
virtual bool NeedSplitDebugInfo() { return true; }
// Start to process a split compilation unit at OFFSET from the beginning of
// the debug_info section in the .dwp/.dwo file. Return false if you would
// like to skip this compilation unit.
virtual bool StartSplitCompilationUnit(uint64 offset,
uint64 cu_length) { return false; }
// Start to process a DIE at OFFSET from the beginning of the .debug_info
// section. Return false if you would like to skip this DIE.
virtual bool StartDIE(uint64 offset, enum DwarfTag tag) { return false; }
@ -287,367 +412,6 @@ class Dwarf2Handler {
};
// The base of DWARF2/3 debug info is a DIE (Debugging Information
// Entry.
// DWARF groups DIE's into a tree and calls the root of this tree a
// "compilation unit". Most of the time, there is one compilation
// unit in the .debug_info section for each file that had debug info
// generated.
// Each DIE consists of
// 1. a tag specifying a thing that is being described (ie
// DW_TAG_subprogram for functions, DW_TAG_variable for variables, etc
// 2. attributes (such as DW_AT_location for location in memory,
// DW_AT_name for name), and data for each attribute.
// 3. A flag saying whether the DIE has children or not
// In order to gain some amount of compression, the format of
// each DIE (tag name, attributes and data forms for the attributes)
// are stored in a separate table called the "abbreviation table".
// This is done because a large number of DIEs have the exact same tag
// and list of attributes, but different data for those attributes.
// As a result, the .debug_info section is just a stream of data, and
// requires reading of the .debug_abbrev section to say what the data
// means.
// As a warning to the user, it should be noted that the reason for
// using absolute offsets from the beginning of .debug_info is that
// DWARF2/3 supports referencing DIE's from other DIE's by their offset
// from either the current compilation unit start, *or* the beginning
// of the .debug_info section. This means it is possible to reference
// a DIE in one compilation unit from a DIE in another compilation
// unit. This style of reference is usually used to eliminate
// duplicated information that occurs across compilation
// units, such as base types, etc. GCC 3.4+ support this with
// -feliminate-dwarf2-dups. Other toolchains will sometimes do
// duplicate elimination in the linker.
class CompilationUnit {
public:
// Initialize a compilation unit. This requires a map of sections,
// the offset of this compilation unit in the .debug_info section, a
// ByteReader, and a Dwarf2Handler class to call callbacks in.
CompilationUnit(const string& path, const SectionMap& sections, uint64 offset,
ByteReader* reader, Dwarf2Handler* handler);
virtual ~CompilationUnit() {
if (abbrevs_) delete abbrevs_;
}
// Initialize a compilation unit from a .dwo or .dwp file.
// In this case, we need the .debug_addr section from the
// executable file that contains the corresponding skeleton
// compilation unit. We also inherit the Dwarf2Handler from
// the executable file, and call it as if we were still
// processing the original compilation unit.
void SetSplitDwarf(const uint8_t* addr_buffer, uint64 addr_buffer_length,
uint64 addr_base, uint64 ranges_base, uint64 dwo_id);
// Begin reading a Dwarf2 compilation unit, and calling the
// callbacks in the Dwarf2Handler
// Return the full length of the compilation unit, including
// headers. This plus the starting offset passed to the constructor
// is the offset of the end of the compilation unit --- and the
// start of the next compilation unit, if there is one.
uint64 Start();
private:
// This struct represents a single DWARF2/3 abbreviation
// The abbreviation tells how to read a DWARF2/3 DIE, and consist of a
// tag and a list of attributes, as well as the data form of each attribute.
struct Abbrev {
uint64 number;
enum DwarfTag tag;
bool has_children;
AttributeList attributes;
};
// A DWARF2/3 compilation unit header. This is not the same size as
// in the actual file, as the one in the file may have a 32 bit or
// 64 bit length.
struct CompilationUnitHeader {
uint64 length;
uint16 version;
uint64 abbrev_offset;
uint8 address_size;
} header_;
// Reads the DWARF2/3 header for this compilation unit.
void ReadHeader();
// Reads the DWARF2/3 abbreviations for this compilation unit
void ReadAbbrevs();
// Processes a single DIE for this compilation unit and return a new
// pointer just past the end of it
const uint8_t *ProcessDIE(uint64 dieoffset,
const uint8_t *start,
const Abbrev& abbrev);
// Processes a single attribute and return a new pointer just past the
// end of it
const uint8_t *ProcessAttribute(uint64 dieoffset,
const uint8_t *start,
enum DwarfAttribute attr,
enum DwarfForm form);
// Called when we have an attribute with unsigned data to give to
// our handler. The attribute is for the DIE at OFFSET from the
// beginning of compilation unit, has a name of ATTR, a form of
// FORM, and the actual data of the attribute is in DATA.
// If we see a DW_AT_GNU_dwo_id attribute, save the value so that
// we can find the debug info in a .dwo or .dwp file.
void ProcessAttributeUnsigned(uint64 offset,
enum DwarfAttribute attr,
enum DwarfForm form,
uint64 data) {
if (attr == DW_AT_GNU_dwo_id) {
dwo_id_ = data;
}
else if (attr == DW_AT_GNU_addr_base) {
addr_base_ = data;
}
else if (attr == DW_AT_GNU_ranges_base) {
ranges_base_ = data;
}
// TODO(yunlian): When we add DW_AT_ranges_base from DWARF-5,
// that base will apply to DW_AT_ranges attributes in the
// skeleton CU as well as in the .dwo/.dwp files.
else if (attr == DW_AT_ranges && is_split_dwarf_) {
data += ranges_base_;
}
handler_->ProcessAttributeUnsigned(offset, attr, form, data);
}
// Called when we have an attribute with signed data to give to
// our handler. The attribute is for the DIE at OFFSET from the
// beginning of compilation unit, has a name of ATTR, a form of
// FORM, and the actual data of the attribute is in DATA.
void ProcessAttributeSigned(uint64 offset,
enum DwarfAttribute attr,
enum DwarfForm form,
int64 data) {
handler_->ProcessAttributeSigned(offset, attr, form, data);
}
// Called when we have an attribute with a buffer of data to give to
// our handler. The attribute is for the DIE at OFFSET from the
// beginning of compilation unit, has a name of ATTR, a form of
// FORM, and the actual data of the attribute is in DATA, and the
// length of the buffer is LENGTH.
void ProcessAttributeBuffer(uint64 offset,
enum DwarfAttribute attr,
enum DwarfForm form,
const uint8_t* data,
uint64 len) {
handler_->ProcessAttributeBuffer(offset, attr, form, data, len);
}
// Called when we have an attribute with string data to give to
// our handler. The attribute is for the DIE at OFFSET from the
// beginning of compilation unit, has a name of ATTR, a form of
// FORM, and the actual data of the attribute is in DATA.
// If we see a DW_AT_GNU_dwo_name attribute, save the value so
// that we can find the debug info in a .dwo or .dwp file.
void ProcessAttributeString(uint64 offset,
enum DwarfAttribute attr,
enum DwarfForm form,
const char* data) {
if (attr == DW_AT_GNU_dwo_name)
dwo_name_ = data;
handler_->ProcessAttributeString(offset, attr, form, data);
}
// Processes all DIEs for this compilation unit
void ProcessDIEs();
// Skips the die with attributes specified in ABBREV starting at
// START, and return the new place to position the stream to.
const uint8_t *SkipDIE(const uint8_t *start, const Abbrev& abbrev);
// Skips the attribute starting at START, with FORM, and return the
// new place to position the stream to.
const uint8_t *SkipAttribute(const uint8_t *start, enum DwarfForm form);
// Process the actual debug information in a split DWARF file.
void ProcessSplitDwarf();
// Read the debug sections from a .dwo file.
void ReadDebugSectionsFromDwo(ElfReader* elf_reader,
SectionMap* sections);
// Path of the file containing the debug information.
const string path_;
// Offset from section start is the offset of this compilation unit
// from the beginning of the .debug_info section.
uint64 offset_from_section_start_;
// buffer is the buffer for our CU, starting at .debug_info + offset
// passed in from constructor.
// after_header points to right after the compilation unit header.
const uint8_t *buffer_;
uint64 buffer_length_;
const uint8_t *after_header_;
// The associated ByteReader that handles endianness issues for us
ByteReader* reader_;
// The map of sections in our file to buffers containing their data
const SectionMap& sections_;
// The associated handler to call processing functions in
Dwarf2Handler* handler_;
// Set of DWARF2/3 abbreviations for this compilation unit. Indexed
// by abbreviation number, which means that abbrevs_[0] is not
// valid.
std::vector<Abbrev>* abbrevs_;
// String section buffer and length, if we have a string section.
// This is here to avoid doing a section lookup for strings in
// ProcessAttribute, which is in the hot path for DWARF2 reading.
const uint8_t *string_buffer_;
uint64 string_buffer_length_;
// String offsets section buffer and length, if we have a string offsets
// section (.debug_str_offsets or .debug_str_offsets.dwo).
const uint8_t* str_offsets_buffer_;
uint64 str_offsets_buffer_length_;
// Address section buffer and length, if we have an address section
// (.debug_addr).
const uint8_t* addr_buffer_;
uint64 addr_buffer_length_;
// Flag indicating whether this compilation unit is part of a .dwo
// or .dwp file. If true, we are reading this unit because a
// skeleton compilation unit in an executable file had a
// DW_AT_GNU_dwo_name or DW_AT_GNU_dwo_id attribute.
// In a .dwo file, we expect the string offsets section to
// have a ".dwo" suffix, and we will use the ".debug_addr" section
// associated with the skeleton compilation unit.
bool is_split_dwarf_;
// The value of the DW_AT_GNU_dwo_id attribute, if any.
uint64 dwo_id_;
// The value of the DW_AT_GNU_dwo_name attribute, if any.
const char* dwo_name_;
// If this is a split DWARF CU, the value of the DW_AT_GNU_dwo_id attribute
// from the skeleton CU.
uint64 skeleton_dwo_id_;
// The value of the DW_AT_GNU_ranges_base attribute, if any.
uint64 ranges_base_;
// The value of the DW_AT_GNU_addr_base attribute, if any.
uint64 addr_base_;
// True if we have already looked for a .dwp file.
bool have_checked_for_dwp_;
// Path to the .dwp file.
string dwp_path_;
// ByteReader for the DWP file.
std::unique_ptr<ByteReader> dwp_byte_reader_;
// DWP reader.
std::unique_ptr<DwpReader> dwp_reader_;
};
// A Reader for a .dwp file. Supports the fetching of DWARF debug
// info for a given dwo_id.
//
// There are two versions of .dwp files. In both versions, the
// .dwp file is an ELF file containing only debug sections.
// In Version 1, the file contains many copies of each debug
// section, one for each .dwo file that is packaged in the .dwp
// file, and the .debug_cu_index section maps from the dwo_id
// to a set of section indexes. In Version 2, the file contains
// one of each debug section, and the .debug_cu_index section
// maps from the dwo_id to a set of offsets and lengths that
// identify each .dwo file's contribution to the larger sections.
class DwpReader {
public:
DwpReader(const ByteReader& byte_reader, ElfReader* elf_reader);
~DwpReader();
// Read the CU index and initialize data members.
void Initialize();
// Read the debug sections for the given dwo_id.
void ReadDebugSectionsForCU(uint64 dwo_id, SectionMap* sections);
private:
// Search a v1 hash table for "dwo_id". Returns the slot index
// where the dwo_id was found, or -1 if it was not found.
int LookupCU(uint64 dwo_id);
// Search a v2 hash table for "dwo_id". Returns the row index
// in the offsets and sizes tables, or 0 if it was not found.
uint32 LookupCUv2(uint64 dwo_id);
// The ELF reader for the .dwp file.
ElfReader* elf_reader_;
// The ByteReader for the .dwp file.
const ByteReader& byte_reader_;
// Pointer to the .debug_cu_index section.
const char* cu_index_;
// Size of the .debug_cu_index section.
size_t cu_index_size_;
// Pointer to the .debug_str.dwo section.
const char* string_buffer_;
// Size of the .debug_str.dwo section.
size_t string_buffer_size_;
// Version of the .dwp file. We support versions 1 and 2 currently.
int version_;
// Number of columns in the section tables (version 2).
unsigned int ncolumns_;
// Number of units in the section tables (version 2).
unsigned int nunits_;
// Number of slots in the hash table.
unsigned int nslots_;
// Pointer to the beginning of the hash table.
const char* phash_;
// Pointer to the beginning of the index table.
const char* pindex_;
// Pointer to the beginning of the section index pool (version 1).
const char* shndx_pool_;
// Pointer to the beginning of the section offset table (version 2).
const char* offset_table_;
// Pointer to the beginning of the section size table (version 2).
const char* size_table_;
// Contents of the sections of interest (version 2).
const char* abbrev_data_;
size_t abbrev_size_;
const char* info_data_;
size_t info_size_;
const char* str_offsets_data_;
size_t str_offsets_size_;
};
// This class is a reader for DWARF's Call Frame Information. CFI
// describes how to unwind stack frames --- even for functions that do
// not follow fixed conventions for saving registers, whose frame size

View File

@ -199,7 +199,7 @@ TEST_P(DwarfHeader, Header) {
ByteReader byte_reader(GetParam().endianness == kLittleEndian ?
ENDIANNESS_LITTLE : ENDIANNESS_BIG);
CompilationUnit parser("", MakeSectionMap(), 0, &byte_reader, &handler);
CompilationUnit parser(MakeSectionMap(), 0, &byte_reader, &handler);
EXPECT_EQ(parser.Start(), info_contents.size());
}
@ -277,7 +277,7 @@ struct DwarfFormsFixture: public DIEFixture {
void ParseCompilationUnit(const DwarfHeaderParams &params, uint64 offset=0) {
ByteReader byte_reader(params.endianness == kLittleEndian ?
ENDIANNESS_LITTLE : ENDIANNESS_BIG);
CompilationUnit parser("", MakeSectionMap(), offset, &byte_reader, &handler);
CompilationUnit parser(MakeSectionMap(), offset, &byte_reader, &handler);
EXPECT_EQ(offset + parser.Start(), info_contents.size());
}

File diff suppressed because it is too large Load Diff

View File

@ -1,166 +0,0 @@
// Copyright 2005 Google Inc. All Rights Reserved.
// Author: chatham@google.com (Andrew Chatham)
// Author: satorux@google.com (Satoru Takabayashi)
//
// ElfReader handles reading in ELF. It can extract symbols from the
// current process, which may be used to symbolize stack traces
// without having to make a potentially dangerous call to fork().
//
// ElfReader dynamically allocates memory, so it is not appropriate to
// use once the address space might be corrupted, such as during
// process death.
//
// ElfReader supports both 32-bit and 64-bit ELF binaries.
#ifndef COMMON_DWARF_ELF_READER_H__
#define COMMON_DWARF_ELF_READER_H__
#include <string>
#include <vector>
#include "common/dwarf/types.h"
using std::string;
using std::vector;
using std::pair;
namespace dwarf2reader {
class SymbolMap;
class Elf32;
class Elf64;
template<typename ElfArch>
class ElfReaderImpl;
class ElfReader {
public:
explicit ElfReader(const string &path);
~ElfReader();
// Parse the ELF prologue of this file and return whether it was
// successfully parsed and matches the word size and byte order of
// the current process.
bool IsNativeElfFile() const;
// Similar to IsNativeElfFile but checks if it's a 32-bit ELF file.
bool IsElf32File() const;
// Similar to IsNativeElfFile but checks if it's a 64-bit ELF file.
bool IsElf64File() const;
// Checks if it's an ELF file of type ET_DYN (shared object file).
bool IsDynamicSharedObject();
// Add symbols in the given ELF file into the provided SymbolMap,
// assuming that the file has been loaded into the specified
// offset.
//
// The remaining arguments are typically taken from a
// ProcMapsIterator (base/sysinfo.h) and describe which portions of
// the ELF file are mapped into which parts of memory:
//
// mem_offset - position at which the segment is mapped into memory
// file_offset - offset in the file where the mapping begins
// length - length of the mapped segment
void AddSymbols(SymbolMap *symbols,
uint64 mem_offset, uint64 file_offset,
uint64 length);
class SymbolSink {
public:
virtual ~SymbolSink() {}
virtual void AddSymbol(const char *name, uint64 address, uint64 size) = 0;
};
// Like AddSymbols above, but with no address correction.
// Processes any SHT_SYMTAB section, followed by any SHT_DYNSYM section.
void VisitSymbols(SymbolSink *sink);
// Like VisitSymbols above, but for a specific symbol binding/type.
// A negative value for the binding and type parameters means any
// binding or type.
void VisitSymbols(SymbolSink *sink, int symbol_binding, int symbol_type);
// Like VisitSymbols above but can optionally export raw symbol values instead
// of adjusted ones.
void VisitSymbols(SymbolSink *sink, int symbol_binding, int symbol_type,
bool get_raw_symbol_values);
// p_vaddr of the first PT_LOAD segment (if any), or 0 if no PT_LOAD
// segments are present. This is the address an ELF image was linked
// (by static linker) to be loaded at. Usually (but not always) 0 for
// shared libraries and position-independent executables.
uint64 VaddrOfFirstLoadSegment();
// Return the name of section "shndx". Returns NULL if the section
// is not found.
const char *GetSectionName(int shndx);
// Return the number of sections in the given ELF file.
uint64 GetNumSections();
// Get section "shndx" from the given ELF file. On success, return
// the pointer to the section and store the size in "size".
// On error, return NULL. The returned section data is only valid
// until the ElfReader gets destroyed.
const char *GetSectionByIndex(int shndx, size_t *size);
// Get section with "section_name" (ex. ".text", ".symtab") in the
// given ELF file. On success, return the pointer to the section
// and store the size in "size". On error, return NULL. The
// returned section data is only valid until the ElfReader gets
// destroyed.
const char *GetSectionByName(const string &section_name, size_t *size);
// This is like GetSectionByName() but it returns a lot of extra information
// about the section. The SectionInfo structure is almost identical to
// the typedef struct Elf64_Shdr defined in <elf.h>, but is redefined
// here so that the many short macro names in <elf.h> don't have to be
// added to our already cluttered namespace.
struct SectionInfo {
uint32 type; // Section type (SHT_xxx constant from elf.h).
uint64 flags; // Section flags (SHF_xxx constants from elf.h).
uint64 addr; // Section virtual address at execution.
uint64 offset; // Section file offset.
uint64 size; // Section size in bytes.
uint32 link; // Link to another section.
uint32 info; // Additional section information.
uint64 addralign; // Section alignment.
uint64 entsize; // Entry size if section holds a table.
};
const char *GetSectionInfoByName(const string &section_name,
SectionInfo *info);
// Check if "path" is an ELF binary that has not been stripped of symbol
// tables. This function supports both 32-bit and 64-bit ELF binaries.
static bool IsNonStrippedELFBinary(const string &path);
// Check if "path" is an ELF binary that has not been stripped of debug
// info. Unlike IsNonStrippedELFBinary, this function will return
// false for binaries passed through "strip -S".
static bool IsNonDebugStrippedELFBinary(const string &path);
// Match a requested section name with the section name as it
// appears in the elf-file, adjusting for compressed debug section
// names. For example, returns true if name == ".debug_abbrev" and
// sh_name == ".zdebug_abbrev"
static bool SectionNamesMatch(const string &name, const string &sh_name);
private:
// Lazily initialize impl32_ and return it.
ElfReaderImpl<Elf32> *GetImpl32();
// Ditto for impl64_.
ElfReaderImpl<Elf64> *GetImpl64();
// Path of the file we're reading.
const string path_;
// Read-only file descriptor for the file. May be -1 if there was an
// error during open.
int fd_;
ElfReaderImpl<Elf32> *impl32_;
ElfReaderImpl<Elf64> *impl64_;
};
} // namespace dwarf2reader
#endif // COMMON_DWARF_ELF_READER_H__

View File

@ -384,17 +384,17 @@ string DwarfCUToModule::GenericDIEHandler::ComputeQualifiedName() {
qualified_name = &specification_->qualified_name;
}
const string *unqualified_name = NULL;
const string *unqualified_name;
const string *enclosing_name;
if (!qualified_name) {
// Find the unqualified name. If the DIE has its own DW_AT_name
// attribute, then use that; otherwise, check the specification.
if (!name_attribute_.empty())
unqualified_name = &name_attribute_;
else if (specification_)
// Find our unqualified name. If the DIE has its own DW_AT_name
// attribute, then use that; otherwise, check our specification.
if (name_attribute_.empty() && specification_)
unqualified_name = &specification_->unqualified_name;
else
unqualified_name = &name_attribute_;
// Find the name of the enclosing context. If this DIE has a
// Find the name of our enclosing context. If we have a
// specification, it's the specification's enclosing context that
// counts; otherwise, use this DIE's context.
if (specification_)
@ -408,7 +408,7 @@ string DwarfCUToModule::GenericDIEHandler::ComputeQualifiedName() {
string return_value;
if (qualified_name) {
return_value = *qualified_name;
} else if (unqualified_name && enclosing_name) {
} else {
// Combine the enclosing name and unqualified name to produce our
// own fully-qualified name.
return_value = cu_context_->language->MakeQualifiedName(*enclosing_name,
@ -417,8 +417,7 @@ string DwarfCUToModule::GenericDIEHandler::ComputeQualifiedName() {
// If this DIE was marked as a declaration, record its names in the
// specification table.
if ((declaration_ && qualified_name) ||
(unqualified_name && enclosing_name)) {
if (declaration_) {
Specification spec;
if (qualified_name) {
spec.qualified_name = *qualified_name;

View File

@ -1323,29 +1323,6 @@ TEST_F(Specifications, InlineFunction) {
0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL);
}
// An inline function in a namespace should correctly derive its
// name from its abstract origin, and not just the namespace name.
TEST_F(Specifications, InlineFunctionInNamespace) {
PushLine(0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL, "line-file", 75173118);
StartCU();
DIEHandler* space_handler
= StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_namespace,
"Namespace");
ASSERT_TRUE(space_handler != NULL);
AbstractInstanceDIE(space_handler, 0x1e8dac5d507ed7abULL,
dwarf2reader::DW_INL_inlined, 0LL, "func-name");
DefineInlineInstanceDIE(space_handler, "", 0x1e8dac5d507ed7abULL,
0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL);
space_handler->Finish();
delete space_handler;
root_handler_.Finish();
TestFunctionCount(1);
TestFunction(0, "Namespace::func-name",
0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL);
}
// Check name construction for a long chain containing each combination of:
// - struct, union, class, namespace
// - direct and definition

View File

@ -64,7 +64,6 @@
#include "common/linux/elfutils-inl.h"
#include "common/linux/elf_symbols_to_module.h"
#include "common/linux/file_id.h"
#include "common/memory.h"
#include "common/module.h"
#include "common/scoped_ptr.h"
#ifndef NO_STABS_SUPPORT
@ -83,18 +82,14 @@ using google_breakpad::DwarfLineToModule;
using google_breakpad::ElfClass;
using google_breakpad::ElfClass32;
using google_breakpad::ElfClass64;
using google_breakpad::FileID;
using google_breakpad::FindElfSectionByName;
using google_breakpad::GetOffset;
using google_breakpad::IsValidElf;
using google_breakpad::kDefaultBuildIdSize;
using google_breakpad::Module;
using google_breakpad::PageAllocator;
#ifndef NO_STABS_SUPPORT
using google_breakpad::StabsToModule;
#endif
using google_breakpad::scoped_ptr;
using google_breakpad::wasteful_vector;
// Define AARCH64 ELF architecture if host machine does not include this define.
#ifndef EM_AARCH64
@ -288,8 +283,7 @@ bool LoadDwarf(const string& dwarf_filename,
// Make a Dwarf2Handler that drives the DIEHandler.
dwarf2reader::DIEDispatcher die_dispatcher(&root_handler);
// Make a DWARF parser for the compilation unit at OFFSET.
dwarf2reader::CompilationUnit reader(dwarf_filename,
file_context.section_map(),
dwarf2reader::CompilationUnit reader(file_context.section_map(),
offset,
&byte_reader,
&die_dispatcher);
@ -690,61 +684,32 @@ bool LoadSymbols(const string& obj_file,
}
// See if there are export symbols available.
const Shdr* symtab_section =
FindElfSectionByName<ElfClass>(".symtab", SHT_SYMTAB,
sections, names, names_end,
elf_header->e_shnum);
const Shdr* strtab_section =
FindElfSectionByName<ElfClass>(".strtab", SHT_STRTAB,
sections, names, names_end,
elf_header->e_shnum);
if (symtab_section && strtab_section) {
info->LoadedSection(".symtab");
const Shdr* dynsym_section =
FindElfSectionByName<ElfClass>(".dynsym", SHT_DYNSYM,
sections, names, names_end,
elf_header->e_shnum);
const Shdr* dynstr_section =
FindElfSectionByName<ElfClass>(".dynstr", SHT_STRTAB,
sections, names, names_end,
elf_header->e_shnum);
if (dynsym_section && dynstr_section) {
info->LoadedSection(".dynsym");
const uint8_t* symtab =
const uint8_t* dynsyms =
GetOffset<ElfClass, uint8_t>(elf_header,
symtab_section->sh_offset);
const uint8_t* strtab =
dynsym_section->sh_offset);
const uint8_t* dynstrs =
GetOffset<ElfClass, uint8_t>(elf_header,
strtab_section->sh_offset);
dynstr_section->sh_offset);
bool result =
ELFSymbolsToModule(symtab,
symtab_section->sh_size,
strtab,
strtab_section->sh_size,
ELFSymbolsToModule(dynsyms,
dynsym_section->sh_size,
dynstrs,
dynstr_section->sh_size,
big_endian,
ElfClass::kAddrSize,
module);
found_usable_info = found_usable_info || result;
} else {
// Look in dynsym only if full symbol table was not available.
const Shdr* dynsym_section =
FindElfSectionByName<ElfClass>(".dynsym", SHT_DYNSYM,
sections, names, names_end,
elf_header->e_shnum);
const Shdr* dynstr_section =
FindElfSectionByName<ElfClass>(".dynstr", SHT_STRTAB,
sections, names, names_end,
elf_header->e_shnum);
if (dynsym_section && dynstr_section) {
info->LoadedSection(".dynsym");
const uint8_t* dynsyms =
GetOffset<ElfClass, uint8_t>(elf_header,
dynsym_section->sh_offset);
const uint8_t* dynstrs =
GetOffset<ElfClass, uint8_t>(elf_header,
dynstr_section->sh_offset);
bool result =
ELFSymbolsToModule(dynsyms,
dynsym_section->sh_size,
dynstrs,
dynstr_section->sh_size,
big_endian,
ElfClass::kAddrSize,
module);
found_usable_info = found_usable_info || result;
}
}
}
@ -860,6 +825,25 @@ const char* ElfArchitecture(const typename ElfClass::Ehdr* elf_header) {
}
}
// Format the Elf file identifier in IDENTIFIER as a UUID with the
// dashes removed.
string FormatIdentifier(unsigned char identifier[16]) {
char identifier_str[40];
google_breakpad::FileID::ConvertIdentifierToString(
identifier,
identifier_str,
sizeof(identifier_str));
string id_no_dash;
for (int i = 0; identifier_str[i] != '\0'; ++i)
if (identifier_str[i] != '-')
id_no_dash += identifier_str[i];
// Add an extra "0" by the end. PDB files on Windows have an 'age'
// number appended to the end of the file identifier; this isn't
// really used or necessary on other platforms, but be consistent.
id_no_dash += '0';
return id_no_dash;
}
// Return the non-directory portion of FILENAME: the portion after the
// last slash, or the whole filename if there are no slashes.
string BaseFileName(const string &filename) {
@ -902,12 +886,18 @@ bool SanitizeDebugFile(const typename ElfClass::Ehdr* debug_elf_header,
}
template<typename ElfClass>
bool InitModuleForElfClass(const typename ElfClass::Ehdr* elf_header,
const string& obj_filename,
scoped_ptr<Module>& module) {
PageAllocator allocator;
wasteful_vector<uint8_t> identifier(&allocator, kDefaultBuildIdSize);
if (!FileID::ElfFileIdentifierFromMappedFile(elf_header, identifier)) {
bool ReadSymbolDataElfClass(const typename ElfClass::Ehdr* elf_header,
const string& obj_filename,
const std::vector<string>& debug_dirs,
const DumpOptions& options,
Module** out_module) {
typedef typename ElfClass::Ehdr Ehdr;
*out_module = NULL;
unsigned char identifier[16];
if (!google_breakpad::FileID::ElfFileIdentifierFromMappedFile(elf_header,
identifier)) {
fprintf(stderr, "%s: unable to generate file identifier\n",
obj_filename.c_str());
return false;
@ -920,39 +910,17 @@ bool InitModuleForElfClass(const typename ElfClass::Ehdr* elf_header,
return false;
}
string name = BaseFileName(obj_filename);
string os = "Linux";
// Add an extra "0" at the end. PDB files on Windows have an 'age'
// number appended to the end of the file identifier; this isn't
// really used or necessary on other platforms, but be consistent.
string id = FileID::ConvertIdentifierToUUIDString(identifier) + "0";
module.reset(new Module(name, os, architecture, id));
return true;
}
template<typename ElfClass>
bool ReadSymbolDataElfClass(const typename ElfClass::Ehdr* elf_header,
const string& obj_filename,
const std::vector<string>& debug_dirs,
const DumpOptions& options,
Module** out_module) {
typedef typename ElfClass::Ehdr Ehdr;
*out_module = NULL;
scoped_ptr<Module> module;
if (!InitModuleForElfClass<ElfClass>(elf_header, obj_filename, module)) {
return false;
}
// Figure out what endianness this file is.
bool big_endian;
if (!ElfEndianness<ElfClass>(elf_header, &big_endian))
return false;
string name = BaseFileName(obj_filename);
string os = "Linux";
string id = FormatIdentifier(identifier);
LoadSymbolsInfo<ElfClass> info(debug_dirs);
scoped_ptr<Module> module(new Module(name, os, architecture, id));
if (!LoadSymbols<ElfClass>(obj_filename, big_endian, elf_header,
!debug_dirs.empty(), &info,
options, module.get())) {
@ -967,9 +935,7 @@ bool ReadSymbolDataElfClass(const typename ElfClass::Ehdr* elf_header,
if (!LoadELF(debuglink_file, &debug_map_wrapper,
reinterpret_cast<void**>(&debug_elf_header)) ||
!SanitizeDebugFile<ElfClass>(debug_elf_header, debuglink_file,
obj_filename,
module->architecture().c_str(),
big_endian)) {
obj_filename, architecture, big_endian)) {
return false;
}
@ -1027,45 +993,6 @@ bool WriteSymbolFile(const string &obj_file,
return result;
}
// Read the selected object file's debugging information, and write out the
// header only to |stream|. Return true on success; if an error occurs, report
// it and return false.
bool WriteSymbolFileHeader(const string& obj_file,
std::ostream &sym_stream) {
MmapWrapper map_wrapper;
void* elf_header = NULL;
if (!LoadELF(obj_file, &map_wrapper, &elf_header)) {
fprintf(stderr, "Could not load ELF file: %s\n", obj_file.c_str());
return false;
}
if (!IsValidElf(elf_header)) {
fprintf(stderr, "Not a valid ELF file: %s\n", obj_file.c_str());
return false;
}
int elfclass = ElfClass(elf_header);
scoped_ptr<Module> module;
if (elfclass == ELFCLASS32) {
if (!InitModuleForElfClass<ElfClass32>(
reinterpret_cast<const Elf32_Ehdr*>(elf_header), obj_file, module)) {
fprintf(stderr, "Failed to load ELF module: %s\n", obj_file.c_str());
return false;
}
} else if (elfclass == ELFCLASS64) {
if (!InitModuleForElfClass<ElfClass64>(
reinterpret_cast<const Elf64_Ehdr*>(elf_header), obj_file, module)) {
fprintf(stderr, "Failed to load ELF module: %s\n", obj_file.c_str());
return false;
}
} else {
fprintf(stderr, "Unsupported module file: %s\n", obj_file.c_str());
return false;
}
return module->Write(sym_stream, ALL_SYMBOL_DATA);
}
bool ReadSymbolData(const string& obj_file,
const std::vector<string>& debug_dirs,
const DumpOptions& options,

View File

@ -67,12 +67,6 @@ bool WriteSymbolFile(const string &obj_file,
const DumpOptions& options,
std::ostream &sym_stream);
// Read the selected object file's debugging information, and write out the
// header only to |stream|. Return true on success; if an error occurs, report
// it and return false.
bool WriteSymbolFileHeader(const string& obj_file,
std::ostream &sym_stream);
// As above, but simply return the debugging information in MODULE
// instead of writing it to a stream. The caller owns the resulting
// Module object and must delete it when finished.

View File

@ -39,7 +39,6 @@
#include <string.h>
#include <algorithm>
#include <string>
#include "common/linux/elf_gnu_compat.h"
#include "common/linux/elfutils.h"
@ -47,13 +46,8 @@
#include "common/linux/memory_mapped_file.h"
#include "third_party/lss/linux_syscall_support.h"
using std::string;
namespace google_breakpad {
// Used in a few places for backwards-compatibility.
const size_t kMDGUIDSize = sizeof(MDGUID);
FileID::FileID(const char* path) : path_(path) {}
// ELF note name and desc are 32-bits word padded.
@ -64,7 +58,7 @@ FileID::FileID(const char* path) : path_(path) {}
template<typename ElfClass>
static bool ElfClassBuildIDNoteIdentifier(const void *section, size_t length,
wasteful_vector<uint8_t>& identifier) {
uint8_t identifier[kMDGUIDSize]) {
typedef typename ElfClass::Nhdr Nhdr;
const void* section_end = reinterpret_cast<const char*>(section) + length;
@ -82,19 +76,21 @@ static bool ElfClassBuildIDNoteIdentifier(const void *section, size_t length,
return false;
}
const uint8_t* build_id = reinterpret_cast<const uint8_t*>(note_header) +
const char* build_id = reinterpret_cast<const char*>(note_header) +
sizeof(Nhdr) + NOTE_PADDING(note_header->n_namesz);
identifier.insert(identifier.end(),
build_id,
build_id + note_header->n_descsz);
// Copy as many bits of the build ID as will fit
// into the GUID space.
my_memset(identifier, 0, kMDGUIDSize);
memcpy(identifier, build_id,
std::min(kMDGUIDSize, (size_t)note_header->n_descsz));
return true;
}
// Attempt to locate a .note.gnu.build-id section in an ELF binary
// and copy it into |identifier|.
static bool FindElfBuildIDNote(const void* elf_mapped_base,
wasteful_vector<uint8_t>& identifier) {
// and copy as many bytes of it as will fit into |identifier|.
static bool FindElfBuildIDNote(const void *elf_mapped_base,
uint8_t identifier[kMDGUIDSize]) {
void* note_section;
size_t note_size;
int elfclass;
@ -120,10 +116,8 @@ static bool FindElfBuildIDNote(const void* elf_mapped_base,
// Attempt to locate the .text section of an ELF binary and generate
// a simple hash by XORing the first page worth of bytes into |identifier|.
static bool HashElfTextSection(const void* elf_mapped_base,
wasteful_vector<uint8_t>& identifier) {
identifier.resize(kMDGUIDSize);
static bool HashElfTextSection(const void *elf_mapped_base,
uint8_t identifier[kMDGUIDSize]) {
void* text_section;
size_t text_size;
if (!FindElfSection(elf_mapped_base, ".text", SHT_PROGBITS,
@ -132,9 +126,7 @@ static bool HashElfTextSection(const void* elf_mapped_base,
return false;
}
// Only provide |kMDGUIDSize| bytes to keep identifiers produced by this
// function backwards-compatible.
my_memset(&identifier[0], 0, kMDGUIDSize);
my_memset(identifier, 0, kMDGUIDSize);
const uint8_t* ptr = reinterpret_cast<const uint8_t*>(text_section);
const uint8_t* ptr_end = ptr + std::min(text_size, static_cast<size_t>(4096));
while (ptr < ptr_end) {
@ -147,7 +139,7 @@ static bool HashElfTextSection(const void* elf_mapped_base,
// static
bool FileID::ElfFileIdentifierFromMappedFile(const void* base,
wasteful_vector<uint8_t>& identifier) {
uint8_t identifier[kMDGUIDSize]) {
// Look for a build id note first.
if (FindElfBuildIDNote(base, identifier))
return true;
@ -156,7 +148,7 @@ bool FileID::ElfFileIdentifierFromMappedFile(const void* base,
return HashElfTextSection(base, identifier);
}
bool FileID::ElfFileIdentifier(wasteful_vector<uint8_t>& identifier) {
bool FileID::ElfFileIdentifier(uint8_t identifier[kMDGUIDSize]) {
MemoryMappedFile mapped_file(path_.c_str(), 0);
if (!mapped_file.data()) // Should probably check if size >= ElfW(Ehdr)?
return false;
@ -164,16 +156,13 @@ bool FileID::ElfFileIdentifier(wasteful_vector<uint8_t>& identifier) {
return ElfFileIdentifierFromMappedFile(mapped_file.data(), identifier);
}
// This function is not ever called in an unsafe context, so it's OK
// to allocate memory and use libc.
// static
string FileID::ConvertIdentifierToUUIDString(
const wasteful_vector<uint8_t>& identifier) {
uint8_t identifier_swapped[kMDGUIDSize] = { 0 };
void FileID::ConvertIdentifierToString(const uint8_t identifier[kMDGUIDSize],
char* buffer, int buffer_length) {
uint8_t identifier_swapped[kMDGUIDSize];
// Endian-ness swap to match dump processor expectation.
memcpy(identifier_swapped, &identifier[0],
std::min(kMDGUIDSize, identifier.size()));
memcpy(identifier_swapped, identifier, kMDGUIDSize);
uint32_t* data1 = reinterpret_cast<uint32_t*>(identifier_swapped);
*data1 = htonl(*data1);
uint16_t* data2 = reinterpret_cast<uint16_t*>(identifier_swapped + 4);
@ -181,13 +170,22 @@ string FileID::ConvertIdentifierToUUIDString(
uint16_t* data3 = reinterpret_cast<uint16_t*>(identifier_swapped + 6);
*data3 = htons(*data3);
string result;
for (unsigned int idx = 0; idx < kMDGUIDSize; ++idx) {
char buf[3];
snprintf(buf, sizeof(buf), "%02X", identifier_swapped[idx]);
result.append(buf);
int buffer_idx = 0;
for (unsigned int idx = 0;
(buffer_idx < buffer_length) && (idx < kMDGUIDSize);
++idx) {
int hi = (identifier_swapped[idx] >> 4) & 0x0F;
int lo = (identifier_swapped[idx]) & 0x0F;
if (idx == 4 || idx == 6 || idx == 8 || idx == 10)
buffer[buffer_idx++] = '-';
buffer[buffer_idx++] = (hi >= 10) ? 'A' + hi - 10 : '0' + hi;
buffer[buffer_idx++] = (lo >= 10) ? 'A' + lo - 10 : '0' + lo;
}
return result;
// NULL terminate
buffer[(buffer_idx < buffer_length) ? buffer_idx : buffer_idx - 1] = 0;
}
} // namespace google_breakpad

View File

@ -37,15 +37,10 @@
#include <string>
#include "common/linux/guid_creator.h"
#include "common/memory.h"
namespace google_breakpad {
// GNU binutils' ld defaults to 'sha1', which is 160 bits == 20 bytes,
// so this is enough to fit that, which most binaries will use.
// This is just a sensible default for auto_wasteful_vector so most
// callers can get away with stack allocation.
static const size_t kDefaultBuildIdSize = 20;
static const size_t kMDGUIDSize = sizeof(MDGUID);
class FileID {
public:
@ -53,25 +48,25 @@ class FileID {
~FileID() {}
// Load the identifier for the elf file path specified in the constructor into
// |identifier|.
//
// |identifier|. Return false if the identifier could not be created for the
// file.
// The current implementation will look for a .note.gnu.build-id
// section and use that as the file id, otherwise it falls back to
// XORing the first 4096 bytes of the .text section to generate an identifier.
bool ElfFileIdentifier(wasteful_vector<uint8_t>& identifier);
bool ElfFileIdentifier(uint8_t identifier[kMDGUIDSize]);
// Load the identifier for the elf file mapped into memory at |base| into
// |identifier|. Return false if the identifier could not be created for this
// |identifier|. Return false if the identifier could not be created for the
// file.
static bool ElfFileIdentifierFromMappedFile(
const void* base,
wasteful_vector<uint8_t>& identifier);
static bool ElfFileIdentifierFromMappedFile(const void* base,
uint8_t identifier[kMDGUIDSize]);
// Convert the |identifier| data to a string. The string will
// be formatted as a UUID in all uppercase without dashes.
// (e.g., 22F065BBFC9C49F780FE26A7CEBD7BCE).
static std::string ConvertIdentifierToUUIDString(
const wasteful_vector<uint8_t>& identifier);
// Convert the |identifier| data to a NULL terminated string. The string will
// be formatted as a UUID (e.g., 22F065BB-FC9C-49F7-80FE-26A7CEBD7BCE).
// The |buffer| should be at least 37 bytes long to receive all of the data
// and termination. Shorter buffers will contain truncated data.
static void ConvertIdentifierToString(const uint8_t identifier[kMDGUIDSize],
char* buffer, int buffer_length);
private:
// Storage for the path specified

View File

@ -33,7 +33,6 @@
#include <stdlib.h>
#include <string>
#include <vector>
#include "common/linux/elf_gnu_compat.h"
#include "common/linux/elfutils.h"
@ -46,11 +45,13 @@
#include "breakpad_googletest_includes.h"
using namespace google_breakpad;
using google_breakpad::ElfClass32;
using google_breakpad::ElfClass64;
using google_breakpad::SafeReadLink;
using google_breakpad::synth_elf::ELF;
using google_breakpad::synth_elf::Notes;
using google_breakpad::test_assembler::kLittleEndian;
using google_breakpad::test_assembler::Section;
using std::vector;
using ::testing::Types;
namespace {
@ -63,8 +64,6 @@ void PopulateSection(Section* section, int size, int prime_number) {
section->Append(1, (i % prime_number) % 256);
}
typedef wasteful_vector<uint8_t> id_vector;
} // namespace
#ifndef __ANDROID__
@ -88,20 +87,19 @@ TEST(FileIDStripTest, StripSelf) {
sprintf(cmdline, "strip \"%s\"", templ.c_str());
ASSERT_EQ(0, system(cmdline)) << "Failed to execute: " << cmdline;
PageAllocator allocator;
id_vector identifier1(&allocator, kDefaultBuildIdSize);
id_vector identifier2(&allocator, kDefaultBuildIdSize);
uint8_t identifier1[sizeof(MDGUID)];
uint8_t identifier2[sizeof(MDGUID)];
FileID fileid1(exe_name);
EXPECT_TRUE(fileid1.ElfFileIdentifier(identifier1));
FileID fileid2(templ.c_str());
EXPECT_TRUE(fileid2.ElfFileIdentifier(identifier2));
string identifier_string1 =
FileID::ConvertIdentifierToUUIDString(identifier1);
string identifier_string2 =
FileID::ConvertIdentifierToUUIDString(identifier2);
EXPECT_EQ(identifier_string1, identifier_string2);
char identifier_string1[37];
char identifier_string2[37];
FileID::ConvertIdentifierToString(identifier1, identifier_string1,
37);
FileID::ConvertIdentifierToString(identifier2, identifier_string2,
37);
EXPECT_STREQ(identifier_string1, identifier_string2);
}
#endif // !__ANDROID__
@ -118,22 +116,8 @@ public:
elfdata = &elfdata_v[0];
}
id_vector make_vector() {
return id_vector(&allocator, kDefaultBuildIdSize);
}
template<size_t N>
string get_file_id(const uint8_t (&data)[N]) {
id_vector expected_identifier(make_vector());
expected_identifier.insert(expected_identifier.end(),
&data[0],
data + N);
return FileID::ConvertIdentifierToUUIDString(expected_identifier);
}
vector<uint8_t> elfdata_v;
uint8_t* elfdata;
PageAllocator allocator;
};
typedef Types<ElfClass32, ElfClass64> ElfClasses;
@ -141,8 +125,10 @@ typedef Types<ElfClass32, ElfClass64> ElfClasses;
TYPED_TEST_CASE(FileIDTest, ElfClasses);
TYPED_TEST(FileIDTest, ElfClass) {
uint8_t identifier[sizeof(MDGUID)];
const char expected_identifier_string[] =
"80808080808000000000008080808080";
"80808080-8080-0000-0000-008080808080";
char identifier_string[sizeof(expected_identifier_string)];
const size_t kTextSectionSize = 128;
ELF elf(EM_386, TypeParam::kClass, kLittleEndian);
@ -154,106 +140,58 @@ TYPED_TEST(FileIDTest, ElfClass) {
elf.Finish();
this->GetElfContents(elf);
id_vector identifier(this->make_vector());
EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata,
identifier));
string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier);
EXPECT_EQ(expected_identifier_string, identifier_string);
FileID::ConvertIdentifierToString(identifier, identifier_string,
sizeof(identifier_string));
EXPECT_STREQ(expected_identifier_string, identifier_string);
}
TYPED_TEST(FileIDTest, BuildID) {
const uint8_t kExpectedIdentifierBytes[] =
const uint8_t kExpectedIdentifier[sizeof(MDGUID)] =
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13};
const string expected_identifier_string =
this->get_file_id(kExpectedIdentifierBytes);
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
char expected_identifier_string[] =
"00000000-0000-0000-0000-000000000000";
FileID::ConvertIdentifierToString(kExpectedIdentifier,
expected_identifier_string,
sizeof(expected_identifier_string));
uint8_t identifier[sizeof(MDGUID)];
char identifier_string[sizeof(expected_identifier_string)];
ELF elf(EM_386, TypeParam::kClass, kLittleEndian);
Section text(kLittleEndian);
text.Append(4096, 0);
elf.AddSection(".text", text, SHT_PROGBITS);
Notes notes(kLittleEndian);
notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifierBytes,
sizeof(kExpectedIdentifierBytes));
notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifier,
sizeof(kExpectedIdentifier));
elf.AddSection(".note.gnu.build-id", notes, SHT_NOTE);
elf.Finish();
this->GetElfContents(elf);
id_vector identifier(this->make_vector());
EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata,
identifier));
EXPECT_EQ(sizeof(kExpectedIdentifierBytes), identifier.size());
string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier);
EXPECT_EQ(expected_identifier_string, identifier_string);
}
// Test that a build id note with fewer bytes than usual is handled.
TYPED_TEST(FileIDTest, BuildIDShort) {
const uint8_t kExpectedIdentifierBytes[] =
{0x00, 0x01, 0x02, 0x03};
const string expected_identifier_string =
this->get_file_id(kExpectedIdentifierBytes);
ELF elf(EM_386, TypeParam::kClass, kLittleEndian);
Section text(kLittleEndian);
text.Append(4096, 0);
elf.AddSection(".text", text, SHT_PROGBITS);
Notes notes(kLittleEndian);
notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifierBytes,
sizeof(kExpectedIdentifierBytes));
elf.AddSection(".note.gnu.build-id", notes, SHT_NOTE);
elf.Finish();
this->GetElfContents(elf);
id_vector identifier(this->make_vector());
EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata,
identifier));
EXPECT_EQ(sizeof(kExpectedIdentifierBytes), identifier.size());
string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier);
EXPECT_EQ(expected_identifier_string, identifier_string);
}
// Test that a build id note with more bytes than usual is handled.
TYPED_TEST(FileIDTest, BuildIDLong) {
const uint8_t kExpectedIdentifierBytes[] =
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
const string expected_identifier_string =
this->get_file_id(kExpectedIdentifierBytes);
ELF elf(EM_386, TypeParam::kClass, kLittleEndian);
Section text(kLittleEndian);
text.Append(4096, 0);
elf.AddSection(".text", text, SHT_PROGBITS);
Notes notes(kLittleEndian);
notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifierBytes,
sizeof(kExpectedIdentifierBytes));
elf.AddSection(".note.gnu.build-id", notes, SHT_NOTE);
elf.Finish();
this->GetElfContents(elf);
id_vector identifier(this->make_vector());
EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata,
identifier));
EXPECT_EQ(sizeof(kExpectedIdentifierBytes), identifier.size());
string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier);
EXPECT_EQ(expected_identifier_string, identifier_string);
FileID::ConvertIdentifierToString(identifier, identifier_string,
sizeof(identifier_string));
EXPECT_STREQ(expected_identifier_string, identifier_string);
}
TYPED_TEST(FileIDTest, BuildIDPH) {
const uint8_t kExpectedIdentifierBytes[] =
const uint8_t kExpectedIdentifier[sizeof(MDGUID)] =
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13};
const string expected_identifier_string =
this->get_file_id(kExpectedIdentifierBytes);
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
char expected_identifier_string[] =
"00000000-0000-0000-0000-000000000000";
FileID::ConvertIdentifierToString(kExpectedIdentifier,
expected_identifier_string,
sizeof(expected_identifier_string));
uint8_t identifier[sizeof(MDGUID)];
char identifier_string[sizeof(expected_identifier_string)];
ELF elf(EM_386, TypeParam::kClass, kLittleEndian);
Section text(kLittleEndian);
@ -262,25 +200,31 @@ TYPED_TEST(FileIDTest, BuildIDPH) {
Notes notes(kLittleEndian);
notes.AddNote(0, "Linux",
reinterpret_cast<const uint8_t *>("\0x42\0x02\0\0"), 4);
notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifierBytes,
sizeof(kExpectedIdentifierBytes));
notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifier,
sizeof(kExpectedIdentifier));
int note_idx = elf.AddSection(".note", notes, SHT_NOTE);
elf.AddSegment(note_idx, note_idx, PT_NOTE);
elf.Finish();
this->GetElfContents(elf);
id_vector identifier(this->make_vector());
EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata,
identifier));
EXPECT_EQ(sizeof(kExpectedIdentifierBytes), identifier.size());
string identifier_string = FileID::ConvertIdentifierToUUIDString(identifier);
EXPECT_EQ(expected_identifier_string, identifier_string);
FileID::ConvertIdentifierToString(identifier, identifier_string,
sizeof(identifier_string));
EXPECT_STREQ(expected_identifier_string, identifier_string);
}
// Test to make sure two files with different text sections produce
// different hashes when not using a build id.
TYPED_TEST(FileIDTest, UniqueHashes) {
char identifier_string_1[] =
"00000000-0000-0000-0000-000000000000";
char identifier_string_2[] =
"00000000-0000-0000-0000-000000000000";
uint8_t identifier_1[sizeof(MDGUID)];
uint8_t identifier_2[sizeof(MDGUID)];
{
ELF elf1(EM_386, TypeParam::kClass, kLittleEndian);
Section foo_1(kLittleEndian);
@ -293,11 +237,10 @@ TYPED_TEST(FileIDTest, UniqueHashes) {
this->GetElfContents(elf1);
}
id_vector identifier_1(this->make_vector());
EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata,
identifier_1));
string identifier_string_1 =
FileID::ConvertIdentifierToUUIDString(identifier_1);
FileID::ConvertIdentifierToString(identifier_1, identifier_string_1,
sizeof(identifier_string_1));
{
ELF elf2(EM_386, TypeParam::kClass, kLittleEndian);
@ -311,11 +254,10 @@ TYPED_TEST(FileIDTest, UniqueHashes) {
this->GetElfContents(elf2);
}
id_vector identifier_2(this->make_vector());
EXPECT_TRUE(FileID::ElfFileIdentifierFromMappedFile(this->elfdata,
identifier_2));
string identifier_string_2 =
FileID::ConvertIdentifierToUUIDString(identifier_2);
FileID::ConvertIdentifierToString(identifier_2, identifier_string_2,
sizeof(identifier_string_2));
EXPECT_NE(identifier_string_1, identifier_string_2);
EXPECT_STRNE(identifier_string_1, identifier_string_2);
}

View File

@ -72,9 +72,7 @@ bool HTTPUpload::SendRequest(const string &url,
// We may have been linked statically; if curl_easy_init is in the
// current binary, no need to search for a dynamic version.
void* curl_lib = dlopen(NULL, RTLD_NOW);
if (!CheckCurlLib(curl_lib)) {
fprintf(stderr,
"Failed to open curl lib from binary, use libcurl.so instead\n");
if (!curl_lib || dlsym(curl_lib, "curl_easy_init") == NULL) {
dlerror(); // Clear dlerror before attempting to open libraries.
dlclose(curl_lib);
curl_lib = NULL;
@ -115,10 +113,6 @@ bool HTTPUpload::SendRequest(const string &url,
*(void**) (&curl_easy_setopt) = dlsym(curl_lib, "curl_easy_setopt");
(*curl_easy_setopt)(curl, CURLOPT_URL, url.c_str());
(*curl_easy_setopt)(curl, CURLOPT_USERAGENT, kUserAgent);
// Support multithread by disabling timeout handling, would get SIGSEGV with
// Curl_resolv_timeout in stack trace otherwise.
// See https://curl.haxx.se/libcurl/c/threadsafe.html
(*curl_easy_setopt)(curl, CURLOPT_NOSIGNAL, 1);
// Set proxy information if necessary.
if (!proxy.empty())
(*curl_easy_setopt)(curl, CURLOPT_PROXY, proxy.c_str());
@ -203,13 +197,6 @@ bool HTTPUpload::SendRequest(const string &url,
return err_code == CURLE_OK;
}
// static
bool HTTPUpload::CheckCurlLib(void* curl_lib) {
return curl_lib &&
dlsym(curl_lib, "curl_easy_init") &&
dlsym(curl_lib, "curl_easy_setopt");
}
// static
bool HTTPUpload::CheckParameters(const map<string, string> &parameters) {
for (map<string, string>::const_iterator pos = parameters.begin();

View File

@ -74,9 +74,6 @@ class HTTPUpload {
// any quote (") characters. Returns true if so.
static bool CheckParameters(const map<string, string> &parameters);
// Checks the curl_lib parameter points to a valid curl lib.
static bool CheckCurlLib(void* curl_lib);
// No instances of this class should be created.
// Disallow all constructors, destructors, and operator=.
HTTPUpload();

View File

@ -35,6 +35,6 @@
// the call fails, IGNORE_RET() can be used to mark the return code as ignored.
// This avoids spurious compiler warnings.
#define IGNORE_RET(x) do { if (x) {} } while (0)
#define IGNORE_RET(x) do { if (x); } while (0)
#endif // COMMON_LINUX_IGNORE_RET_H_

View File

@ -1,155 +0,0 @@
// Copyright (c) 2011 Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// symbol_upload.cc: implemented google_breakpad::sym_upload::Start, a helper
// function for linux symbol upload tool.
#include "common/linux/http_upload.h"
#include "common/linux/symbol_upload.h"
#include <assert.h>
#include <stdio.h>
#include <functional>
#include <vector>
namespace google_breakpad {
namespace sym_upload {
void TokenizeByChar(const string &source_string, int c,
std::vector<string> *results) {
assert(results);
string::size_type cur_pos = 0, next_pos = 0;
while ((next_pos = source_string.find(c, cur_pos)) != string::npos) {
if (next_pos != cur_pos)
results->push_back(source_string.substr(cur_pos, next_pos - cur_pos));
cur_pos = next_pos + 1;
}
if (cur_pos < source_string.size() && next_pos != cur_pos)
results->push_back(source_string.substr(cur_pos));
}
//=============================================================================
// Parse out the module line which have 5 parts.
// MODULE <os> <cpu> <uuid> <module-name>
bool ModuleDataForSymbolFile(const string &file,
std::vector<string> *module_parts) {
assert(module_parts);
const size_t kModulePartNumber = 5;
FILE* fp = fopen(file.c_str(), "r");
if (fp) {
char buffer[1024];
if (fgets(buffer, sizeof(buffer), fp)) {
string line(buffer);
string::size_type line_break_pos = line.find_first_of('\n');
if (line_break_pos == string::npos) {
assert(0 && "The file is invalid!");
fclose(fp);
return false;
}
line.resize(line_break_pos);
const char kDelimiter = ' ';
TokenizeByChar(line, kDelimiter, module_parts);
if (module_parts->size() != kModulePartNumber)
module_parts->clear();
}
fclose(fp);
}
return module_parts->size() == kModulePartNumber;
}
//=============================================================================
string CompactIdentifier(const string &uuid) {
std::vector<string> components;
TokenizeByChar(uuid, '-', &components);
string result;
for (size_t i = 0; i < components.size(); ++i)
result += components[i];
return result;
}
//=============================================================================
void Start(Options *options) {
std::map<string, string> parameters;
options->success = false;
std::vector<string> module_parts;
if (!ModuleDataForSymbolFile(options->symbolsPath, &module_parts)) {
fprintf(stderr, "Failed to parse symbol file!\n");
return;
}
string compacted_id = CompactIdentifier(module_parts[3]);
// Add parameters
if (!options->version.empty())
parameters["version"] = options->version;
// MODULE <os> <cpu> <uuid> <module-name>
// 0 1 2 3 4
parameters["os"] = module_parts[1];
parameters["cpu"] = module_parts[2];
parameters["debug_file"] = module_parts[4];
parameters["code_file"] = module_parts[4];
parameters["debug_identifier"] = compacted_id;
std::map<string, string> files;
files["symbol_file"] = options->symbolsPath;
string response, error;
long response_code;
bool success = HTTPUpload::SendRequest(options->uploadURLStr,
parameters,
files,
options->proxy,
options->proxy_user_pwd,
"",
&response,
&response_code,
&error);
if (!success) {
printf("Failed to send symbol file: %s\n", error.c_str());
printf("Response code: %ld\n", response_code);
printf("Response:\n");
printf("%s\n", response.c_str());
} else if (response_code == 0) {
printf("Failed to send symbol file: No response code\n");
} else if (response_code != 200) {
printf("Failed to send symbol file: Response code %ld\n", response_code);
printf("Response:\n");
printf("%s\n", response.c_str());
} else {
printf("Successfully sent the symbol file.\n");
}
options->success = success;
}
} // namespace sym_upload
} // namespace google_breakpad

View File

@ -1,59 +0,0 @@
// -*- mode: c++ -*-
// Copyright (c) 2011 Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// symbol_upload.h: helper functions for linux symbol upload tool.
#ifndef COMMON_LINUX_SYMBOL_UPLOAD_H_
#define COMMON_LINUX_SYMBOL_UPLOAD_H_
#include <string>
#include "common/using_std_string.h"
namespace google_breakpad {
namespace sym_upload {
typedef struct {
string symbolsPath;
string uploadURLStr;
string proxy;
string proxy_user_pwd;
string version;
bool success;
} Options;
// Starts upload to symbol server with options.
void Start(Options* options);
} // namespace sym_upload
} // namespace google_breakpad
#endif // COMMON_LINUX_SYMBOL_UPLOAD_H_

View File

@ -27,6 +27,12 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ARCHS = $(ARCHS_STANDARD_32_64_BIT)
SDKROOT = macosx10.5
GCC_VERSION = 4.2
GCC_VERSION[sdk=macosx10.4][arch=*] = 4.0
GCC_C_LANGUAGE_STANDARD = c99
GCC_WARN_CHECK_SWITCH_STATEMENTS = YES
@ -35,10 +41,7 @@ GCC_WARN_64_TO_32_BIT_CONVERSION = NO
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES
GCC_WARN_ABOUT_RETURN_TYPE = YES
GCC_WARN_MISSING_PARENTHESES = YES
// Once https://bugs.chromium.org/p/google-breakpad/issues/detail?id=697
// is fixed this should be reenabled.
//GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES
GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES
GCC_WARN_ABOUT_MISSING_NEWLINE = YES
GCC_WARN_SIGN_COMPARE = YES
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES
@ -48,5 +51,6 @@ GCC_WARN_UNUSED_VARIABLE = YES
GCC_TREAT_WARNINGS_AS_ERRORS = YES
DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
DEBUG_INFORMATION_FORMAT[sdk=macosx10.4][arch=*] = stabs
ALWAYS_SEARCH_USER_PATHS = NO

View File

@ -328,65 +328,6 @@ class DumpSymbols::DumperLineToModule:
dwarf2reader::ByteReader *byte_reader_; // WEAK
};
bool DumpSymbols::CreateEmptyModule(scoped_ptr<Module>& module) {
// Select an object file, if SetArchitecture hasn't been called to set one
// explicitly.
if (!selected_object_file_) {
// If there's only one architecture, that's the one.
if (object_files_.size() == 1)
selected_object_file_ = &object_files_[0];
else {
// Look for an object file whose architecture matches our own.
const NXArchInfo *local_arch = NXGetLocalArchInfo();
if (!SetArchitecture(local_arch->cputype, local_arch->cpusubtype)) {
fprintf(stderr, "%s: object file contains more than one"
" architecture, none of which match the current"
" architecture; specify an architecture explicitly"
" with '-a ARCH' to resolve the ambiguity\n",
object_filename_.c_str());
return false;
}
}
}
assert(selected_object_file_);
// Find the name of the selected file's architecture, to appear in
// the MODULE record and in error messages.
const NXArchInfo *selected_arch_info =
google_breakpad::BreakpadGetArchInfoFromCpuType(
selected_object_file_->cputype, selected_object_file_->cpusubtype);
const char *selected_arch_name = selected_arch_info->name;
if (strcmp(selected_arch_name, "i386") == 0)
selected_arch_name = "x86";
// Produce a name to use in error messages that includes the
// filename, and the architecture, if there is more than one.
selected_object_name_ = object_filename_;
if (object_files_.size() > 1) {
selected_object_name_ += ", architecture ";
selected_object_name_ + selected_arch_name;
}
// Compute a module name, to appear in the MODULE record.
string module_name = object_filename_;
module_name = basename(&module_name[0]);
// Choose an identifier string, to appear in the MODULE record.
string identifier = Identifier();
if (identifier.empty())
return false;
identifier += "0";
// Create a module to hold the debugging information.
module.reset(new Module(module_name,
"mac",
selected_arch_name,
identifier));
return true;
}
bool DumpSymbols::ReadDwarf(google_breakpad::Module *module,
const mach_o::Reader &macho_reader,
const mach_o::SectionMap &dwarf_sections,
@ -437,8 +378,7 @@ bool DumpSymbols::ReadDwarf(google_breakpad::Module *module,
// Make a Dwarf2Handler that drives our DIEHandler.
dwarf2reader::DIEDispatcher die_dispatcher(&root_handler);
// Make a DWARF parser for the compilation unit at OFFSET.
dwarf2reader::CompilationUnit dwarf_reader(selected_object_name_,
file_context.section_map(),
dwarf2reader::CompilationUnit dwarf_reader(file_context.section_map(),
offset,
&byte_reader,
&die_dispatcher);
@ -595,9 +535,61 @@ bool DumpSymbols::LoadCommandDumper::SymtabCommand(const ByteBuffer &entries,
}
bool DumpSymbols::ReadSymbolData(Module** out_module) {
scoped_ptr<Module> module;
if (!CreateEmptyModule(module))
// Select an object file, if SetArchitecture hasn't been called to set one
// explicitly.
if (!selected_object_file_) {
// If there's only one architecture, that's the one.
if (object_files_.size() == 1)
selected_object_file_ = &object_files_[0];
else {
// Look for an object file whose architecture matches our own.
const NXArchInfo *local_arch = NXGetLocalArchInfo();
if (!SetArchitecture(local_arch->cputype, local_arch->cpusubtype)) {
fprintf(stderr, "%s: object file contains more than one"
" architecture, none of which match the current"
" architecture; specify an architecture explicitly"
" with '-a ARCH' to resolve the ambiguity\n",
object_filename_.c_str());
return false;
}
}
}
assert(selected_object_file_);
// Find the name of the selected file's architecture, to appear in
// the MODULE record and in error messages.
const NXArchInfo *selected_arch_info =
google_breakpad::BreakpadGetArchInfoFromCpuType(
selected_object_file_->cputype, selected_object_file_->cpusubtype);
const char *selected_arch_name = selected_arch_info->name;
if (strcmp(selected_arch_name, "i386") == 0)
selected_arch_name = "x86";
// Produce a name to use in error messages that includes the
// filename, and the architecture, if there is more than one.
selected_object_name_ = object_filename_;
if (object_files_.size() > 1) {
selected_object_name_ += ", architecture ";
selected_object_name_ + selected_arch_name;
}
// Compute a module name, to appear in the MODULE record.
string module_name = object_filename_;
module_name = basename(&module_name[0]);
// Choose an identifier string, to appear in the MODULE record.
string identifier = Identifier();
if (identifier.empty())
return false;
identifier += "0";
// Create a module to hold the debugging information.
scoped_ptr<Module> module(new Module(module_name,
"mac",
selected_arch_name,
identifier));
// Parse the selected object file.
mach_o::Reader::Reporter reporter(selected_object_name_);
@ -632,15 +624,4 @@ bool DumpSymbols::WriteSymbolFile(std::ostream &stream) {
return false;
}
// Read the selected object file's debugging information, and write out the
// header only to |stream|. Return true on success; if an error occurs, report
// it and return false.
bool DumpSymbols::WriteSymbolFileHeader(std::ostream &stream) {
scoped_ptr<Module> module;
if (!CreateEmptyModule(module))
return false;
return module->Write(stream, symbol_data_);
}
} // namespace google_breakpad

View File

@ -112,11 +112,6 @@ class DumpSymbols {
// return false.
bool WriteSymbolFile(std::ostream &stream);
// Read the selected object file's debugging information, and write out the
// header only to |stream|. Return true on success; if an error occurs, report
// it and return false.
bool WriteSymbolFileHeader(std::ostream &stream);
// As above, but simply return the debugging information in module
// instead of writing it to a stream. The caller owns the resulting
// module object and must delete it when finished.
@ -135,10 +130,6 @@ class DumpSymbols {
// Return an identifier string for the file this DumpSymbols is dumping.
std::string Identifier();
// Creates an empty module object.
bool CreateEmptyModule(scoped_ptr<Module>& module);
// Read debugging information from |dwarf_sections|, which was taken from
// |macho_reader|, and add it to |module|. On success, return true;
// on failure, report the problem and return false.

View File

@ -181,15 +181,15 @@ void Reader::Reporter::LoadCommandRegionTruncated() {
void Reader::Reporter::LoadCommandsOverrun(size_t claimed, size_t i,
LoadCommandType type) {
fprintf(stderr, "%s: file's header claims there are %zu"
" load commands, but load command #%zu",
fprintf(stderr, "%s: file's header claims there are %ld"
" load commands, but load command #%ld",
filename_.c_str(), claimed, i);
if (type) fprintf(stderr, ", of type %d,", type);
fprintf(stderr, " extends beyond the end of the load command region\n");
}
void Reader::Reporter::LoadCommandTooShort(size_t i, LoadCommandType type) {
fprintf(stderr, "%s: the contents of load command #%zu, of type %d,"
fprintf(stderr, "%s: the contents of load command #%ld, of type %d,"
" extend beyond the size given in the load command's header\n",
filename_.c_str(), i, type);
}

View File

@ -26,6 +26,10 @@
#import "GTMObjC2Runtime.h"
#import "GTMUnitTestDevLog.h"
#if !GTM_IPHONE_SDK
#import "GTMGarbageCollection.h"
#endif // !GTM_IPHONE_SDK
#if GTM_IPHONE_SDK && !GTM_IPHONE_USE_SENTEST
#import <stdarg.h>
@ -426,3 +430,71 @@ static int MethodSort(id a, id b, void *context) {
}
@end
// Leak detection
#if !GTM_IPHONE_DEVICE && !GTM_SUPPRESS_RUN_LEAKS_HOOK
// Don't want to get leaks on the iPhone Device as the device doesn't
// have 'leaks'. The simulator does though.
// COV_NF_START
// We don't have leak checking on by default, so this won't be hit.
static void _GTMRunLeaks(void) {
// This is an atexit handler. It runs leaks for us to check if we are
// leaking anything in our tests.
const char* cExclusionsEnv = getenv("GTM_LEAKS_SYMBOLS_TO_IGNORE");
NSMutableString *exclusions = [NSMutableString string];
if (cExclusionsEnv) {
NSString *exclusionsEnv = [NSString stringWithUTF8String:cExclusionsEnv];
NSArray *exclusionsArray = [exclusionsEnv componentsSeparatedByString:@","];
NSString *exclusion;
NSCharacterSet *wcSet = [NSCharacterSet whitespaceCharacterSet];
GTM_FOREACH_OBJECT(exclusion, exclusionsArray) {
exclusion = [exclusion stringByTrimmingCharactersInSet:wcSet];
[exclusions appendFormat:@"-exclude \"%@\" ", exclusion];
}
}
// Clearing out DYLD_ROOT_PATH because iPhone Simulator framework libraries
// are different from regular OS X libraries and leaks will fail to run
// because of missing symbols. Also capturing the output of leaks and then
// pipe rather than a direct pipe, because otherwise if leaks failed,
// the system() call will still be successful. Bug:
// http://code.google.com/p/google-toolbox-for-mac/issues/detail?id=56
NSString *string
= [NSString stringWithFormat:
@"LeakOut=`DYLD_ROOT_PATH='' /usr/bin/leaks %@%d` &&"
@"echo \"$LeakOut\"|/usr/bin/sed -e 's/Leak: /Leaks:0: warning: Leak /'",
exclusions, getpid()];
int ret = system([string UTF8String]);
if (ret) {
fprintf(stderr,
"%s:%d: Error: Unable to run leaks. 'system' returned: %d\n",
__FILE__, __LINE__, ret);
fflush(stderr);
}
}
// COV_NF_END
static __attribute__((constructor)) void _GTMInstallLeaks(void) {
BOOL checkLeaks = YES;
#if !GTM_IPHONE_SDK
checkLeaks = GTMIsGarbageCollectionEnabled() ? NO : YES;
#endif // !GTM_IPHONE_SDK
if (checkLeaks) {
checkLeaks = getenv("GTM_ENABLE_LEAKS") ? YES : NO;
if (checkLeaks) {
// COV_NF_START
// We don't have leak checking on by default, so this won't be hit.
fprintf(stderr, "Leak Checking Enabled\n");
fflush(stderr);
int ret = atexit(&_GTMRunLeaks);
// To avoid unused variable warning when _GTMDevAssert is stripped.
(void)ret;
_GTMDevAssert(ret == 0,
@"Unable to install _GTMRunLeaks as an atexit handler (%d)",
errno);
// COV_NF_END
}
}
}
#endif // !GTM_IPHONE_DEVICE && !GTM_SUPPRESS_RUN_LEAKS_HOOK

View File

@ -64,8 +64,7 @@ class PageAllocator {
: page_size_(getpagesize()),
last_(NULL),
current_page_(NULL),
page_offset_(0),
pages_allocated_(0) {
page_offset_(0) {
}
~PageAllocator() {
@ -113,8 +112,6 @@ class PageAllocator {
return false;
}
unsigned long pages_allocated() { return pages_allocated_; }
private:
uint8_t *GetNPages(size_t num_pages) {
#if defined(__x86_64__) || defined(__aarch64__) || defined(__aarch64__) || \
@ -139,8 +136,6 @@ class PageAllocator {
header->num_pages = num_pages;
last_ = header;
pages_allocated_ += num_pages;
return reinterpret_cast<uint8_t*>(a);
}
@ -162,7 +157,6 @@ class PageAllocator {
PageHeader *last_;
uint8_t *current_page_;
size_t page_offset_;
unsigned long pages_allocated_;
};
// Wrapper to use with STL containers
@ -171,30 +165,12 @@ struct PageStdAllocator : public std::allocator<T> {
typedef typename std::allocator<T>::pointer pointer;
typedef typename std::allocator<T>::size_type size_type;
explicit PageStdAllocator(PageAllocator& allocator) : allocator_(allocator),
stackdata_(NULL),
stackdata_size_(0)
{}
explicit PageStdAllocator(PageAllocator& allocator): allocator_(allocator) {}
template <class Other> PageStdAllocator(const PageStdAllocator<Other>& other)
: allocator_(other.allocator_),
stackdata_(nullptr),
stackdata_size_(0)
{}
explicit PageStdAllocator(PageAllocator& allocator,
pointer stackdata,
size_type stackdata_size) : allocator_(allocator),
stackdata_(stackdata),
stackdata_size_(stackdata_size)
{}
: allocator_(other.allocator_) {}
inline pointer allocate(size_type n, const void* = 0) {
const size_type size = sizeof(T) * n;
if (size <= stackdata_size_) {
return stackdata_;
}
return static_cast<pointer>(allocator_.Alloc(size));
return static_cast<pointer>(allocator_.Alloc(sizeof(T) * n));
}
inline void deallocate(pointer, size_type) {
@ -212,8 +188,6 @@ struct PageStdAllocator : public std::allocator<T> {
template<typename Other> friend struct PageStdAllocator;
PageAllocator& allocator_;
pointer stackdata_;
size_type stackdata_size_;
};
// A wasteful vector is a std::vector, except that it allocates memory from a
@ -226,24 +200,6 @@ class wasteful_vector : public std::vector<T, PageStdAllocator<T> > {
: std::vector<T, PageStdAllocator<T> >(PageStdAllocator<T>(*allocator)) {
std::vector<T, PageStdAllocator<T> >::reserve(size_hint);
}
protected:
wasteful_vector(PageStdAllocator<T> allocator)
: std::vector<T, PageStdAllocator<T> >(allocator) {}
};
// auto_wasteful_vector allocates space on the stack for N entries to avoid
// using the PageAllocator for small data, while still allowing for larger data.
template<class T, unsigned int N>
class auto_wasteful_vector : public wasteful_vector<T> {
T stackdata_[N];
public:
auto_wasteful_vector(PageAllocator* allocator)
: wasteful_vector<T>(
PageStdAllocator<T>(*allocator,
&stackdata_[0],
sizeof(stackdata_))) {
std::vector<T, PageStdAllocator<T> >::reserve(N);
}
};
} // namespace google_breakpad

View File

@ -38,13 +38,11 @@ typedef testing::Test PageAllocatorTest;
TEST(PageAllocatorTest, Setup) {
PageAllocator allocator;
EXPECT_EQ(0U, allocator.pages_allocated());
}
TEST(PageAllocatorTest, SmallObjects) {
PageAllocator allocator;
EXPECT_EQ(0U, allocator.pages_allocated());
for (unsigned i = 1; i < 1024; ++i) {
uint8_t *p = reinterpret_cast<uint8_t*>(allocator.Alloc(i));
ASSERT_FALSE(p == NULL);
@ -55,10 +53,8 @@ TEST(PageAllocatorTest, SmallObjects) {
TEST(PageAllocatorTest, LargeObject) {
PageAllocator allocator;
EXPECT_EQ(0U, allocator.pages_allocated());
uint8_t *p = reinterpret_cast<uint8_t*>(allocator.Alloc(10000));
ASSERT_FALSE(p == NULL);
EXPECT_EQ(3U, allocator.pages_allocated());
for (unsigned i = 1; i < 10; ++i) {
uint8_t *p = reinterpret_cast<uint8_t*>(allocator.Alloc(i));
ASSERT_FALSE(p == NULL);
@ -79,7 +75,6 @@ TEST(WastefulVectorTest, Setup) {
TEST(WastefulVectorTest, Simple) {
PageAllocator allocator_;
EXPECT_EQ(0U, allocator_.pages_allocated());
wasteful_vector<unsigned> v(&allocator_);
for (unsigned i = 0; i < 256; ++i) {
@ -89,7 +84,6 @@ TEST(WastefulVectorTest, Simple) {
}
ASSERT_FALSE(v.empty());
ASSERT_EQ(v.size(), 256u);
EXPECT_EQ(1U, allocator_.pages_allocated());
for (unsigned i = 0; i < 256; ++i)
ASSERT_EQ(v[i], i);
}
@ -97,28 +91,7 @@ TEST(WastefulVectorTest, Simple) {
TEST(WastefulVectorTest, UsesPageAllocator) {
PageAllocator allocator_;
wasteful_vector<unsigned> v(&allocator_);
EXPECT_EQ(1U, allocator_.pages_allocated());
v.push_back(1);
ASSERT_TRUE(allocator_.OwnsPointer(&v[0]));
}
TEST(WastefulVectorTest, AutoWastefulVector) {
PageAllocator allocator_;
EXPECT_EQ(0U, allocator_.pages_allocated());
auto_wasteful_vector<unsigned, 4> v(&allocator_);
EXPECT_EQ(0U, allocator_.pages_allocated());
v.push_back(1);
EXPECT_EQ(0U, allocator_.pages_allocated());
EXPECT_FALSE(allocator_.OwnsPointer(&v[0]));
v.resize(4);
EXPECT_EQ(0U, allocator_.pages_allocated());
EXPECT_FALSE(allocator_.OwnsPointer(&v[0]));
v.resize(10);
EXPECT_EQ(1U, allocator_.pages_allocated());
EXPECT_TRUE(allocator_.OwnsPointer(&v[0]));
}

View File

@ -27,8 +27,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_BREAKPAD_COMMON_STDIO_WRAPPER_H
#define GOOGLE_BREAKPAD_COMMON_STDIO_WRAPPER_H
#ifndef GOOGLE_BREAKPAD_COMMON_STDIO_H
#define GOOGLE_BREAKPAD_COMMON_STDIO_H
#include <stdio.h>
@ -40,4 +40,4 @@ typedef SSIZE_T ssize_t;
#endif
#endif // GOOGLE_BREAKPAD_COMMON_STDIO_WRAPPER_H
#endif // GOOGLE_BREAKPAD_COMMON_STDIO_H

View File

@ -210,7 +210,7 @@ bool FindAndLoadOmapTable(const wchar_t* name,
reinterpret_cast<BYTE*>(&table->at(0)),
&count_read))) {
fprintf(stderr, "IDiaEnumDebugStreamData::Next failed while reading "
"data from stream \"%ws\"\n", name);
"data from stream \"%ws\"\n");
return false;
}

View File

@ -975,16 +975,6 @@ bool PDBSourceLineWriter::GetSymbolFunctionName(IDiaSymbol *function,
fprintf(stderr, "failed to get function name\n");
return false;
}
// It's possible for get_name to return an empty string, so
// special-case that.
if (wcscmp(*name, L"") == 0) {
SysFreeString(*name);
// dwarf_cu_to_module.cc uses "<name omitted>", so match that.
*name = SysAllocString(L"<name omitted>");
return true;
}
// If a name comes from get_name because no undecorated form existed,
// it's already formatted properly to be used as output. Don't do any
// additional processing.

View File

@ -3,9 +3,6 @@
/* Define to 1 if you have the <a.out.h> header file. */
#undef HAVE_A_OUT_H
/* define if the compiler supports basic C++11 syntax */
#undef HAVE_CXX11
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H

View File

@ -328,10 +328,6 @@ typedef enum {
MD_MEMORY_INFO_LIST_STREAM = 16, /* MDRawMemoryInfoList */
MD_THREAD_INFO_LIST_STREAM = 17,
MD_HANDLE_OPERATION_LIST_STREAM = 18,
MD_TOKEN_STREAM = 19,
MD_JAVASCRIPT_DATA_STREAM = 20,
MD_SYSTEM_MEMORY_INFO_STREAM = 21,
MD_PROCESS_VM_COUNTERS_STREAM = 22,
MD_LAST_RESERVED_STREAM = 0x0000ffff,
/* Breakpad extension types. 0x4767 = "Gg" */

View File

@ -45,7 +45,6 @@
#ifndef GOOGLE_BREAKPAD_PROCESSOR_CALL_STACK_H__
#define GOOGLE_BREAKPAD_PROCESSOR_CALL_STACK_H__
#include <cstdint>
#include <vector>
namespace google_breakpad {
@ -62,24 +61,15 @@ class CallStack {
// Resets the CallStack to its initial empty state
void Clear();
const vector<StackFrame*>* frames() const { return &frames_; }
// Set the TID associated with this call stack.
void set_tid(uint32_t tid) { tid_ = tid; }
uint32_t tid() const { return tid_; }
private:
// Stackwalker is responsible for building the frames_ vector.
friend class Stackwalker;
// Storage for pushed frames.
vector<StackFrame*> frames_;
// The TID associated with this call stack. Default to 0 if it's not
// available.
uint32_t tid_;
};
} // namespace google_breakpad

View File

@ -67,8 +67,6 @@ class MicrodumpContext : public DumpContext {
virtual void SetContextARM(MDRawContextARM* arm);
virtual void SetContextARM64(MDRawContextARM64* arm64);
virtual void SetContextX86(MDRawContextX86* x86);
virtual void SetContextMIPS(MDRawContextMIPS* mips32);
virtual void SetContextMIPS64(MDRawContextMIPS* mips64);
};
// This class provides access to microdump memory regions.

View File

@ -46,7 +46,8 @@
namespace google_breakpad {
BasicCodeModules::BasicCodeModules(const CodeModules *that)
: main_address_(0), map_() {
: main_address_(0),
map_(new RangeMap<uint64_t, linked_ptr<const CodeModule> >()) {
BPLOG_IF(ERROR, !that) << "BasicCodeModules::BasicCodeModules requires "
"|that|";
assert(that);
@ -65,27 +66,30 @@ BasicCodeModules::BasicCodeModules(const CodeModules *that)
// GetModuleAtSequence.
linked_ptr<const CodeModule> module(
that->GetModuleAtIndex(module_sequence)->Copy());
if (!map_.StoreRange(module->base_address(), module->size(), module)) {
if (!map_->StoreRange(module->base_address(), module->size(), module)) {
BPLOG(ERROR) << "Module " << module->code_file() <<
" could not be stored";
}
}
}
BasicCodeModules::BasicCodeModules() : main_address_(0), map_() { }
BasicCodeModules::BasicCodeModules()
: main_address_(0),
map_(new RangeMap<uint64_t, linked_ptr<const CodeModule> >()) {
}
BasicCodeModules::~BasicCodeModules() {
delete map_;
}
unsigned int BasicCodeModules::module_count() const {
return map_.GetCount();
return map_->GetCount();
}
const CodeModule* BasicCodeModules::GetModuleForAddress(
uint64_t address) const {
linked_ptr<const CodeModule> module;
if (!map_.RetrieveRange(address, &module, NULL /* base */, NULL /* delta */,
NULL /* size */)) {
if (!map_->RetrieveRange(address, &module, NULL, NULL)) {
BPLOG(INFO) << "No module at " << HexString(address);
return NULL;
}
@ -100,8 +104,7 @@ const CodeModule* BasicCodeModules::GetMainModule() const {
const CodeModule* BasicCodeModules::GetModuleAtSequence(
unsigned int sequence) const {
linked_ptr<const CodeModule> module;
if (!map_.RetrieveRangeAtIndex(sequence, &module, NULL /* base */,
NULL /* delta */, NULL /* size */)) {
if (!map_->RetrieveRangeAtIndex(sequence, &module, NULL, NULL)) {
BPLOG(ERROR) << "RetrieveRangeAtIndex failed for sequence " << sequence;
return NULL;
}

View File

@ -41,14 +41,13 @@
#ifndef PROCESSOR_BASIC_CODE_MODULES_H__
#define PROCESSOR_BASIC_CODE_MODULES_H__
#include <stddef.h>
#include "google_breakpad/processor/code_modules.h"
#include "processor/linked_ptr.h"
#include "processor/range_map.h"
namespace google_breakpad {
template<typename T> class linked_ptr;
template<typename AddressType, typename EntryType> class RangeMap;
class BasicCodeModules : public CodeModules {
public:
// Creates a new BasicCodeModules object given any existing CodeModules
@ -76,7 +75,7 @@ class BasicCodeModules : public CodeModules {
// The map used to contain each CodeModule, keyed by each CodeModule's
// address range.
RangeMap<uint64_t, linked_ptr<const CodeModule> > map_;
RangeMap<uint64_t, linked_ptr<const CodeModule> > *map_;
private:
// Disallow copy constructor and assignment operator.

View File

@ -203,16 +203,15 @@ void BasicSourceLineResolver::Module::LookupAddress(StackFrame *frame) const {
MemAddr function_base;
MemAddr function_size;
MemAddr public_address;
if (functions_.RetrieveNearestRange(address, &func, &function_base,
NULL /* delta */, &function_size) &&
if (functions_.RetrieveNearestRange(address, &func,
&function_base, &function_size) &&
address >= function_base && address - function_base < function_size) {
frame->function_name = func->name;
frame->function_base = frame->module->base_address() + function_base;
linked_ptr<Line> line;
MemAddr line_base;
if (func->lines.RetrieveRange(address, &line, &line_base, NULL /* delta */,
NULL /* size */)) {
if (func->lines.RetrieveRange(address, &line, &line_base, NULL)) {
FileMap::const_iterator it = files_.find(line->source_file_id);
if (it != files_.end()) {
frame->source_file_name = files_.find(line->source_file_id)->second;
@ -257,8 +256,8 @@ WindowsFrameInfo *BasicSourceLineResolver::Module::FindWindowsFrameInfo(
// comparison in an overflow-friendly way.
linked_ptr<Function> function;
MemAddr function_base, function_size;
if (functions_.RetrieveNearestRange(address, &function, &function_base,
NULL /* delta */, &function_size) &&
if (functions_.RetrieveNearestRange(address, &function,
&function_base, &function_size) &&
address >= function_base && address - function_base < function_size) {
result->parameter_size = function->parameter_size;
result->valid |= WindowsFrameInfo::VALID_PARAMETER_SIZE;
@ -287,8 +286,8 @@ CFIFrameInfo *BasicSourceLineResolver::Module::FindCFIFrameInfo(
// provides an initial set of register recovery rules. Then, walk
// forward from the initial rule's starting address to frame's
// instruction address, applying delta rules.
if (!cfi_initial_rules_.RetrieveRange(address, &initial_rules, &initial_base,
NULL /* delta */, &initial_size)) {
if (!cfi_initial_rules_.RetrieveRange(address, &initial_rules,
&initial_base, &initial_size)) {
return NULL;
}
@ -483,7 +482,7 @@ bool SymbolParseHelper::ParseFile(char *file_line, long *index,
}
*filename = tokens[1];
if (!*filename) {
if (!filename) {
return false;
}
@ -596,7 +595,7 @@ bool SymbolParseHelper::ParsePublicSymbol(char *public_line,
*stack_param_size < 0) {
return false;
}
*name = tokens[2];
*name = tokens[2];
return true;
}

View File

@ -48,7 +48,6 @@ void CallStack::Clear() {
++iterator) {
delete *iterator;
}
tid_ = 0;
}
} // namespace google_breakpad

View File

@ -54,7 +54,7 @@ class MemoryRegion;
// values, when the PC is at a given address in the current frame's
// function. See the description of 'STACK CFI' records at:
//
// https://chromium.googlesource.com/breakpad/breakpad/+/master/docs/symbol_files.md
// http://code.google.com/p/google-breakpad/wiki/SymbolFiles
//
// To prepare an instance of CFIFrameInfo for use at a given
// instruction, first populate it with the rules from the 'STACK CFI

View File

@ -41,7 +41,7 @@
#include <unistd.h>
#endif // _WIN32
#include "common/stdio_wrapper.h"
#include "common/stdio.h"
#include "processor/logging.h"
namespace google_breakpad {

View File

@ -40,7 +40,7 @@
#include <string>
#include "common/stdio_wrapper.h"
#include "common/stdio.h"
#include "common/using_std_string.h"
#include "processor/logging.h"
#include "processor/pathname_stripper.h"

View File

@ -61,8 +61,6 @@ static const char kStackFirstLineKey[] = ": S 0 ";
static const char kArmArchitecture[] = "arm";
static const char kArm64Architecture[] = "arm64";
static const char kX86Architecture[] = "x86";
static const char kMipsArchitecture[] = "mips";
static const char kMips64Architecture[] = "mips64";
static const char kGpuUnknown[] = "UNKNOWN";
template<typename T>
@ -104,7 +102,7 @@ namespace google_breakpad {
void MicrodumpModules::Add(const CodeModule* module) {
linked_ptr<const CodeModule> module_ptr(module);
if (!map_.StoreRange(module->base_address(), module->size(), module_ptr)) {
if (!map_->StoreRange(module->base_address(), module->size(), module_ptr)) {
BPLOG(ERROR) << "Module " << module->code_file() <<
" could not be stored";
}
@ -133,18 +131,6 @@ void MicrodumpContext::SetContextX86(MDRawContextX86* x86) {
valid_ = true;
}
void MicrodumpContext::SetContextMIPS(MDRawContextMIPS* mips32) {
DumpContext::SetContextFlags(MD_CONTEXT_MIPS);
DumpContext::SetContextMIPS(mips32);
valid_ = true;
}
void MicrodumpContext::SetContextMIPS64(MDRawContextMIPS* mips64) {
DumpContext::SetContextFlags(MD_CONTEXT_MIPS64);
DumpContext::SetContextMIPS(mips64);
valid_ = true;
}
//
// MicrodumpMemoryRegion
@ -295,9 +281,8 @@ Microdump::Microdump(const string& contents)
std::vector<uint8_t> cpu_state_raw = ParseHexBuf(cpu_state_str);
if (strcmp(arch.c_str(), kArmArchitecture) == 0) {
if (cpu_state_raw.size() != sizeof(MDRawContextARM)) {
std::cerr << "Malformed CPU context. Got " << cpu_state_raw.size()
<< " bytes instead of " << sizeof(MDRawContextARM)
<< std::endl;
std::cerr << "Malformed CPU context. Got " << cpu_state_raw.size() <<
" bytes instead of " << sizeof(MDRawContextARM) << std::endl;
continue;
}
MDRawContextARM* arm = new MDRawContextARM();
@ -305,9 +290,8 @@ Microdump::Microdump(const string& contents)
context_->SetContextARM(arm);
} else if (strcmp(arch.c_str(), kArm64Architecture) == 0) {
if (cpu_state_raw.size() != sizeof(MDRawContextARM64)) {
std::cerr << "Malformed CPU context. Got " << cpu_state_raw.size()
<< " bytes instead of " << sizeof(MDRawContextARM64)
<< std::endl;
std::cerr << "Malformed CPU context. Got " << cpu_state_raw.size() <<
" bytes instead of " << sizeof(MDRawContextARM64) << std::endl;
continue;
}
MDRawContextARM64* arm = new MDRawContextARM64();
@ -315,34 +299,13 @@ Microdump::Microdump(const string& contents)
context_->SetContextARM64(arm);
} else if (strcmp(arch.c_str(), kX86Architecture) == 0) {
if (cpu_state_raw.size() != sizeof(MDRawContextX86)) {
std::cerr << "Malformed CPU context. Got " << cpu_state_raw.size()
<< " bytes instead of " << sizeof(MDRawContextX86)
<< std::endl;
std::cerr << "Malformed CPU context. Got " << cpu_state_raw.size() <<
" bytes instead of " << sizeof(MDRawContextX86) << std::endl;
continue;
}
MDRawContextX86* x86 = new MDRawContextX86();
memcpy(x86, &cpu_state_raw[0], cpu_state_raw.size());
context_->SetContextX86(x86);
} else if (strcmp(arch.c_str(), kMipsArchitecture) == 0) {
if (cpu_state_raw.size() != sizeof(MDRawContextMIPS)) {
std::cerr << "Malformed CPU context. Got " << cpu_state_raw.size()
<< " bytes instead of " << sizeof(MDRawContextMIPS)
<< std::endl;
continue;
}
MDRawContextMIPS* mips32 = new MDRawContextMIPS();
memcpy(mips32, &cpu_state_raw[0], cpu_state_raw.size());
context_->SetContextMIPS(mips32);
} else if (strcmp(arch.c_str(), kMips64Architecture) == 0) {
if (cpu_state_raw.size() != sizeof(MDRawContextMIPS)) {
std::cerr << "Malformed CPU context. Got " << cpu_state_raw.size()
<< " bytes instead of " << sizeof(MDRawContextMIPS)
<< std::endl;
continue;
}
MDRawContextMIPS* mips64 = new MDRawContextMIPS();
memcpy(mips64, &cpu_state_raw[0], cpu_state_raw.size());
context_->SetContextMIPS64(mips64);
} else {
std::cerr << "Unsupported architecture: " << arch << std::endl;
}

View File

@ -223,48 +223,6 @@ TEST_F(MicrodumpProcessorTest, TestProcessMultiple) {
ASSERT_EQ(2U, state.threads()->at(0)->frames()->size());
}
TEST_F(MicrodumpProcessorTest, TestProcessMips) {
ProcessState state;
AnalyzeDump("microdump-mips32.dmp", false /* omit_symbols */,
2 /* expected_cpu_count */, &state);
ASSERT_EQ(7U, state.modules()->module_count());
ASSERT_EQ("mips", state.system_info()->cpu);
ASSERT_EQ("3.0.8-g893bf16 #7 SMP PREEMPT Fri Jul 10 15:20:59 PDT 2015",
state.system_info()->os_version);
ASSERT_EQ(4U, state.threads()->at(0)->frames()->size());
ASSERT_EQ("blaTest",
state.threads()->at(0)->frames()->at(0)->function_name);
ASSERT_EQ("Crash",
state.threads()->at(0)->frames()->at(1)->function_name);
ASSERT_EQ("main",
state.threads()->at(0)->frames()->at(2)->function_name);
ASSERT_EQ("crash_example",
state.threads()->at(0)->frames()->at(0)->module->debug_file());
}
TEST_F(MicrodumpProcessorTest, TestProcessMips64) {
ProcessState state;
AnalyzeDump("microdump-mips64.dmp", false /* omit_symbols */,
1 /* expected_cpu_count */, &state);
ASSERT_EQ(7U, state.modules()->module_count());
ASSERT_EQ("mips64", state.system_info()->cpu);
ASSERT_EQ("3.10.0-gf185e20 #112 PREEMPT Mon Oct 5 11:12:49 PDT 2015",
state.system_info()->os_version);
ASSERT_EQ(4U, state.threads()->at(0)->frames()->size());
ASSERT_EQ("blaTest",
state.threads()->at(0)->frames()->at(0)->function_name);
ASSERT_EQ("Crash",
state.threads()->at(0)->frames()->at(1)->function_name);
ASSERT_EQ("main",
state.threads()->at(0)->frames()->at(2)->function_name);
ASSERT_EQ("crash_example",
state.threads()->at(0)->frames()->at(0)->module->debug_file());
}
} // namespace
int main(int argc, char* argv[]) {

View File

@ -57,7 +57,7 @@
#include "processor/range_map-inl.h"
#include "common/scoped_ptr.h"
#include "common/stdio_wrapper.h"
#include "common/stdio.h"
#include "google_breakpad/processor/dump_context.h"
#include "processor/basic_code_module.h"
#include "processor/basic_code_modules.h"
@ -1180,7 +1180,7 @@ bool MinidumpContext::CheckAgainstSystemInfo(uint32_t context_cpu_type) {
//
uint32_t MinidumpMemoryRegion::max_bytes_ = 2 * 1024 * 1024; // 2MB
uint32_t MinidumpMemoryRegion::max_bytes_ = 1024 * 1024; // 1MB
MinidumpMemoryRegion::MinidumpMemoryRegion(Minidump* minidump)
@ -1930,8 +1930,9 @@ string MinidumpModule::debug_file() const {
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.
assert(reinterpret_cast<const MDCVInfoELF*>(&(*cv_record_)[0])->
cv_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 MDCVInfoELF, the debug file is the code file.
file = *name_;
@ -2672,8 +2673,7 @@ const MinidumpModule* MinidumpModuleList::GetModuleForAddress(
}
unsigned int module_index;
if (!range_map_->RetrieveRange(address, &module_index, NULL /* base */,
NULL /* delta */, NULL /* size */)) {
if (!range_map_->RetrieveRange(address, &module_index, NULL, NULL)) {
BPLOG(INFO) << "MinidumpModuleList has no module at " <<
HexString(address);
return NULL;
@ -2709,9 +2709,7 @@ const MinidumpModule* MinidumpModuleList::GetModuleAtSequence(
}
unsigned int module_index;
if (!range_map_->RetrieveRangeAtIndex(sequence, &module_index,
NULL /* base */, NULL /* delta */,
NULL /* size */)) {
if (!range_map_->RetrieveRangeAtIndex(sequence, &module_index, NULL, NULL)) {
BPLOG(ERROR) << "MinidumpModuleList has no module at sequence " << sequence;
return NULL;
}
@ -2926,8 +2924,7 @@ MinidumpMemoryRegion* MinidumpMemoryList::GetMemoryRegionForAddress(
}
unsigned int region_index;
if (!range_map_->RetrieveRange(address, &region_index, NULL /* base */,
NULL /* delta */, NULL /* size */)) {
if (!range_map_->RetrieveRange(address, &region_index, NULL, NULL)) {
BPLOG(INFO) << "MinidumpMemoryList has no memory region at " <<
HexString(address);
return NULL;
@ -4031,8 +4028,7 @@ const MinidumpMemoryInfo* MinidumpMemoryInfoList::GetMemoryInfoForAddress(
}
unsigned int info_index;
if (!range_map_->RetrieveRange(address, &info_index, NULL /* base */,
NULL /* delta */, NULL /* size */)) {
if (!range_map_->RetrieveRange(address, &info_index, NULL, NULL)) {
BPLOG(INFO) << "MinidumpMemoryInfoList has no memory info at " <<
HexString(address);
return NULL;
@ -4572,14 +4568,6 @@ static const char* get_stream_name(uint32_t stream_type) {
return "MD_THREAD_INFO_LIST_STREAM";
case MD_HANDLE_OPERATION_LIST_STREAM:
return "MD_HANDLE_OPERATION_LIST_STREAM";
case MD_TOKEN_STREAM:
return "MD_TOKEN_STREAM";
case MD_JAVASCRIPT_DATA_STREAM:
return "MD_JAVASCRIPT_DATA_STREAM";
case MD_SYSTEM_MEMORY_INFO_STREAM:
return "MD_SYSTEM_MEMORY_INFO_STREAM";
case MD_PROCESS_VM_COUNTERS_STREAM:
return "MD_PROCESS_VM_COUNTERS_STREAM";
case MD_LAST_RESERVED_STREAM:
return "MD_LAST_RESERVED_STREAM";
case MD_BREAKPAD_INFO_STREAM:

View File

@ -34,7 +34,7 @@
#include <string>
#include "common/scoped_ptr.h"
#include "common/stdio_wrapper.h"
#include "common/stdio.h"
#include "common/using_std_string.h"
#include "google_breakpad/processor/call_stack.h"
#include "google_breakpad/processor/minidump.h"
@ -267,7 +267,6 @@ ProcessResult MinidumpProcessor::Process(
// one bad thread.
BPLOG(ERROR) << "No stackwalker for " << thread_string;
}
stack->set_tid(thread_id);
process_state->threads_.push_back(stack.release());
process_state->thread_memory_regions_.push_back(thread_memory);
}
@ -746,19 +745,6 @@ string MinidumpProcessor::GetCrashReason(Minidump *dump, uint64_t *address) {
BPLOG(INFO) << "Unknown exception reason " << reason;
break;
}
} else if (raw_system_info->processor_architecture ==
MD_CPU_ARCHITECTURE_X86 ||
raw_system_info->processor_architecture ==
MD_CPU_ARCHITECTURE_AMD64) {
switch (exception_flags) {
case MD_EXCEPTION_CODE_MAC_X86_GENERAL_PROTECTION_FAULT:
reason.append("EXC_I386_GPFLT");
break;
default:
reason.append(flags_string);
BPLOG(INFO) << "Unknown exception reason " << reason;
break;
}
} else {
reason.append(flags_string);
BPLOG(INFO) << "Unknown exception reason " << reason;
@ -809,26 +795,25 @@ string MinidumpProcessor::GetCrashReason(Minidump *dump, uint64_t *address) {
}
break;
}
case MD_CPU_ARCHITECTURE_AMD64:
case MD_CPU_ARCHITECTURE_X86: {
switch (exception_flags) {
case MD_EXCEPTION_CODE_MAC_X86_INVALID_OPERATION:
reason.append("EXC_I386_INVOP");
break;
case MD_EXCEPTION_CODE_MAC_X86_INVALID_TASK_STATE_SEGMENT:
reason.append("EXC_I386_INVTSSFLT");
reason.append("EXC_INVTSSFLT");
break;
case MD_EXCEPTION_CODE_MAC_X86_SEGMENT_NOT_PRESENT:
reason.append("EXC_I386_SEGNPFLT");
reason.append("EXC_SEGNPFLT");
break;
case MD_EXCEPTION_CODE_MAC_X86_STACK_FAULT:
reason.append("EXC_I386_STKFLT");
reason.append("EXC_STKFLT");
break;
case MD_EXCEPTION_CODE_MAC_X86_GENERAL_PROTECTION_FAULT:
reason.append("EXC_I386_GPFLT");
reason.append("EXC_GPFLT");
break;
case MD_EXCEPTION_CODE_MAC_X86_ALIGNMENT_FAULT:
reason.append("EXC_I386_ALIGNFLT");
reason.append("EXC_ALIGNFLT");
break;
default:
reason.append(flags_string);
@ -881,7 +866,6 @@ string MinidumpProcessor::GetCrashReason(Minidump *dump, uint64_t *address) {
}
break;
}
case MD_CPU_ARCHITECTURE_AMD64:
case MD_CPU_ARCHITECTURE_X86: {
switch (exception_flags) {
case MD_EXCEPTION_CODE_MAC_X86_DIV:
@ -982,7 +966,6 @@ string MinidumpProcessor::GetCrashReason(Minidump *dump, uint64_t *address) {
}
break;
}
case MD_CPU_ARCHITECTURE_AMD64:
case MD_CPU_ARCHITECTURE_X86: {
switch (exception_flags) {
case MD_EXCEPTION_CODE_MAC_X86_SGL:

View File

@ -414,7 +414,6 @@ TEST_F(MinidumpProcessorTest, TestBasicProcessing) {
ASSERT_EQ(state.crash_reason(), "EXCEPTION_ACCESS_VIOLATION_WRITE");
ASSERT_EQ(state.crash_address(), 0x45U);
ASSERT_EQ(state.threads()->size(), size_t(1));
EXPECT_EQ((*state.threads())[0]->tid(), 3060U);
ASSERT_EQ(state.requesting_thread(), 0);
EXPECT_EQ(1171480435U, state.time_date_stamp());
EXPECT_EQ(1171480435U, state.process_create_time());

View File

@ -625,80 +625,6 @@ TEST(Dump, CVELFShort) {
ASSERT_EQ("B4CDA95F0000000000000000000000000", md_module->debug_identifier());
}
// Test that a build_id that's very long is handled properly.
TEST(Dump, CVELFLong) {
Dump dump(0, kLittleEndian);
String module_name(dump, "elf module");
Section cv_info(dump);
cv_info
.D32(MD_CVINFOELF_SIGNATURE) // signature
// build_id, lots of bytes
.Append("\x5f\xa9\xcd\xb4\x10\x53\xdf\x1b\x86\xfa\xb7\x33\xb4\xdf"
"\x37\x38\xce\xa3\x4a\x87\x01\x02\x03\x04\x05\x06\x07\x08"
"\x09\x0a\x0b\x0c\x0d\x0e\x0f");
const MDRawSystemInfo linux_x86 = {
MD_CPU_ARCHITECTURE_X86, // processor_architecture
6, // processor_level
0xd08, // processor_revision
1, // number_of_processors
0, // product_type
0, // major_version
0, // minor_version
0, // build_number
MD_OS_LINUX, // platform_id
0xdeadbeef, // csd_version_rva
0x100, // suite_mask
0, // reserved2
{ // cpu
{ // x86_cpu_info
{ 0x756e6547, 0x49656e69, 0x6c65746e }, // vendor_id
0x6d8, // version_information
0xafe9fbff, // feature_information
0xffffffff // amd_extended_cpu_features
}
}
};
String csd_version(dump, "Literally Linux");
SystemInfo system_info(dump, linux_x86, csd_version);
Module module(dump, 0xa90206ca83eb2852ULL, 0xada542bd,
module_name,
0xb1054d2a,
0x34571371,
fixed_file_info, // from synth_minidump_unittest_data.h
&cv_info, nullptr);
dump.Add(&module);
dump.Add(&module_name);
dump.Add(&cv_info);
dump.Add(&system_info);
dump.Add(&csd_version);
dump.Finish();
string contents;
ASSERT_TRUE(dump.GetContents(&contents));
istringstream minidump_stream(contents);
Minidump minidump(minidump_stream);
ASSERT_TRUE(minidump.Read());
ASSERT_EQ(2U, minidump.GetDirectoryEntryCount());
MinidumpModuleList *md_module_list = minidump.GetModuleList();
ASSERT_TRUE(md_module_list != NULL);
ASSERT_EQ(1U, md_module_list->module_count());
const MinidumpModule *md_module = md_module_list->GetModuleAtIndex(0);
ASSERT_TRUE(md_module != NULL);
// just the build_id, directly
ASSERT_EQ(
"5fa9cdb41053df1b86fab733b4df3738cea34a870102030405060708090a0b0c0d0e0f",
md_module->code_identifier());
// build_id truncated to GUID length and treated as such, with zero
// age appended.
ASSERT_EQ("B4CDA95F53101BDF86FAB733B4DF37380", md_module->debug_identifier());
}
TEST(Dump, OneSystemInfo) {
Dump dump(0, kLittleEndian);
String csd_version(dump, "Petulant Pierogi");

View File

@ -77,7 +77,7 @@
'pathname_stripper.h',
'postfix_evaluator-inl.h',
'postfix_evaluator.h',
'proc_maps_linux.cc',
'proc_maps_linux.cc',
'process_state.cc',
'range_map-inl.h',
'range_map.h',
@ -154,7 +154,6 @@
'minidump_unittest.cc',
'pathname_stripper_unittest.cc',
'postfix_evaluator_unittest.cc',
'range_map_shrink_down_unittest.cc',
'range_map_unittest.cc',
'stackwalker_address_list_unittest.cc',
'stackwalker_amd64_unittest.cc',

View File

@ -40,29 +40,16 @@
#include <assert.h>
#include "processor/range_map.h"
#include "processor/linked_ptr.h"
#include "processor/logging.h"
namespace google_breakpad {
template<typename AddressType, typename EntryType>
void RangeMap<AddressType, EntryType>::SetEnableShrinkDown(
bool enable_shrink_down) {
enable_shrink_down_ = enable_shrink_down;
}
template<typename AddressType, typename EntryType>
bool RangeMap<AddressType, EntryType>::StoreRange(const AddressType &base,
const AddressType &size,
const EntryType &entry) {
return StoreRangeInternal(base, 0 /* delta */, size, entry);
}
template<typename AddressType, typename EntryType>
bool RangeMap<AddressType, EntryType>::StoreRangeInternal(
const AddressType &base, const AddressType &delta,
const AddressType &size, const EntryType &entry) {
AddressType high = base + (size - 1);
// Check for undersize or overflow.
@ -70,10 +57,9 @@ bool RangeMap<AddressType, EntryType>::StoreRangeInternal(
// The processor will hit this case too frequently with common symbol
// files in the size == 0 case, which is more suited to a DEBUG channel.
// Filter those out since there's no DEBUG channel at the moment.
BPLOG_IF(INFO, size != 0) << "StoreRangeInternal failed, "
<< HexString(base) << "+" << HexString(size)
<< ", " << HexString(high)
<< ", delta: " << HexString(delta);
BPLOG_IF(INFO, size != 0) << "StoreRange failed, " << HexString(base) <<
"+" << HexString(size) << ", " <<
HexString(high);
return false;
}
@ -85,80 +71,53 @@ bool RangeMap<AddressType, EntryType>::StoreRangeInternal(
if (iterator_base != iterator_high) {
// Some other range begins in the space used by this range. It may be
// contained within the space used by this range, or it may extend lower.
// If enable_shrink_down_ is true, shrink the current range down, otherwise
// this is an error.
if (enable_shrink_down_) {
AddressType additional_delta = iterator_base->first - base + 1;
return StoreRangeInternal(base + additional_delta,
delta + additional_delta,
size - additional_delta, entry);
} else {
// The processor hits this case too frequently with common symbol files.
// This is most appropriate for a DEBUG channel, but since none exists
// now simply comment out this logging.
// AddressType other_base = iterator_base->second.base();
// AddressType other_size = iterator_base->first - other_base + 1;
// BPLOG(INFO) << "StoreRangeInternal failed, an existing range is "
// << "overlapping with the new range: new "
// << HexString(base) << "+" << HexString(size)
// << ", existing " << HexString(other_base) << "+"
// << HexString(other_size);
return false;
}
// Regardless, it is an error.
// The processor hits this case too frequently with common symbol files.
// This is most appropriate for a DEBUG channel, but since none exists now
// simply comment out this logging.
//
// AddressType other_base = iterator_base->second.base();
// AddressType other_size = iterator_base->first - other_base + 1;
// BPLOG(INFO) << "StoreRange failed, an existing range is contained by or "
// "extends lower than the new range: new " <<
// HexString(base) << "+" << HexString(size) <<
// ", existing " << HexString(other_base) << "+" <<
// HexString(other_size);
return false;
}
if (iterator_high != map_.end()) {
if (iterator_high->second.base() <= high) {
// The range above this one overlaps with this one. It may fully
// contain this range, or it may begin within this range and extend
// higher. If enable_shrink_down_ is true, shrink the other range down,
// otherwise this is an error.
if (enable_shrink_down_ && iterator_high->first > high) {
// Shrink the other range down.
AddressType other_high = iterator_high->first;
AddressType additional_delta =
high - iterator_high->second.base() + 1;
EntryType other_entry;
AddressType other_base = AddressType();
AddressType other_size = AddressType();
AddressType other_delta = AddressType();
RetrieveRange(other_high, &other_entry, &other_base, &other_delta,
&other_size);
map_.erase(iterator_high);
map_.insert(MapValue(other_high,
Range(other_base + additional_delta,
other_delta + additional_delta,
other_entry)));
// Retry to store this range.
return StoreRangeInternal(base, delta, size, entry);
} else {
// The processor hits this case too frequently with common symbol files.
// This is most appropriate for a DEBUG channel, but since none exists
// now simply comment out this logging.
//
// AddressType other_base = iterator_high->second.base();
// AddressType other_size = iterator_high->first - other_base + 1;
// BPLOG(INFO) << "StoreRangeInternal failed, an existing range "
// << "contains or extends higher than the new range: new "
// << HexString(base) << "+" << HexString(size)
// << ", existing " << HexString(other_base) << "+"
// << HexString(other_size);
return false;
}
// higher. Regardless, it's an error.
// The processor hits this case too frequently with common symbol files.
// This is most appropriate for a DEBUG channel, but since none exists now
// simply comment out this logging.
//
// AddressType other_base = iterator_high->second.base();
// AddressType other_size = iterator_high->first - other_base + 1;
// BPLOG(INFO) << "StoreRange failed, an existing range contains or "
// "extends higher than the new range: new " <<
// HexString(base) << "+" << HexString(size) <<
// ", existing " << HexString(other_base) << "+" <<
// HexString(other_size);
return false;
}
}
// Store the range in the map by its high address, so that lower_bound can
// be used to quickly locate a range by address.
map_.insert(MapValue(high, Range(base, delta, entry)));
map_.insert(MapValue(high, Range(base, entry)));
return true;
}
template<typename AddressType, typename EntryType>
bool RangeMap<AddressType, EntryType>::RetrieveRange(
const AddressType &address, EntryType *entry, AddressType *entry_base,
AddressType *entry_delta, AddressType *entry_size) const {
const AddressType &address, EntryType *entry,
AddressType *entry_base, AddressType *entry_size) const {
BPLOG_IF(ERROR, !entry) << "RangeMap::RetrieveRange requires |entry|";
assert(entry);
@ -177,8 +136,6 @@ bool RangeMap<AddressType, EntryType>::RetrieveRange(
*entry = iterator->second.entry();
if (entry_base)
*entry_base = iterator->second.base();
if (entry_delta)
*entry_delta = iterator->second.delta();
if (entry_size)
*entry_size = iterator->first - iterator->second.base() + 1;
@ -188,13 +145,13 @@ bool RangeMap<AddressType, EntryType>::RetrieveRange(
template<typename AddressType, typename EntryType>
bool RangeMap<AddressType, EntryType>::RetrieveNearestRange(
const AddressType &address, EntryType *entry, AddressType *entry_base,
AddressType *entry_delta, AddressType *entry_size) const {
const AddressType &address, EntryType *entry,
AddressType *entry_base, AddressType *entry_size) const {
BPLOG_IF(ERROR, !entry) << "RangeMap::RetrieveNearestRange requires |entry|";
assert(entry);
// If address is within a range, RetrieveRange can handle it.
if (RetrieveRange(address, entry, entry_base, entry_delta, entry_size))
if (RetrieveRange(address, entry, entry_base, entry_size))
return true;
// upper_bound gives the first element whose key is greater than address,
@ -210,8 +167,6 @@ bool RangeMap<AddressType, EntryType>::RetrieveNearestRange(
*entry = iterator->second.entry();
if (entry_base)
*entry_base = iterator->second.base();
if (entry_delta)
*entry_delta = iterator->second.delta();
if (entry_size)
*entry_size = iterator->first - iterator->second.base() + 1;
@ -221,8 +176,8 @@ bool RangeMap<AddressType, EntryType>::RetrieveNearestRange(
template<typename AddressType, typename EntryType>
bool RangeMap<AddressType, EntryType>::RetrieveRangeAtIndex(
int index, EntryType *entry, AddressType *entry_base,
AddressType *entry_delta, AddressType *entry_size) const {
int index, EntryType *entry,
AddressType *entry_base, AddressType *entry_size) const {
BPLOG_IF(ERROR, !entry) << "RangeMap::RetrieveRangeAtIndex requires |entry|";
assert(entry);
@ -240,8 +195,6 @@ bool RangeMap<AddressType, EntryType>::RetrieveRangeAtIndex(
*entry = iterator->second.entry();
if (entry_base)
*entry_base = iterator->second.base();
if (entry_delta)
*entry_delta = iterator->second.delta();
if (entry_size)
*entry_size = iterator->first - iterator->second.base() + 1;

View File

@ -52,55 +52,40 @@ template<class, class> class RangeMapSerializer;
template<typename AddressType, typename EntryType>
class RangeMap {
public:
RangeMap() : enable_shrink_down_(false), map_() {}
// |enable_shrink_down| tells whether overlapping ranges can be shrunk down.
// If true, then adding a new range that overlaps with an existing one can
// be a successful operation. The range which ends at the higher address
// will be shrunk down by moving its start position to a higher address so
// that it does not overlap anymore.
void SetEnableShrinkDown(bool enable_shrink_down);
RangeMap() : map_() {}
// Inserts a range into the map. Returns false for a parameter error,
// or if the location of the range would conflict with a range already
// stored in the map. If enable_shrink_down is true and there is an overlap
// between the current range and some other range (already in the map),
// shrink down the range which ends at a higher address.
bool StoreRange(const AddressType &base, const AddressType &size,
// stored in the map.
bool StoreRange(const AddressType &base,
const AddressType &size,
const EntryType &entry);
// Locates the range encompassing the supplied address. If there is no such
// range, returns false. entry_base, entry_delta, and entry_size, if
// non-NULL, are set to the base, delta, and size of the entry's range.
// A positive entry delta (> 0) indicates that there was an overlap and the
// entry was shrunk down (original start address was increased by delta).
// Locates the range encompassing the supplied address. If there is
// no such range, returns false. entry_base and entry_size, if non-NULL,
// are set to the base and size of the entry's range.
bool RetrieveRange(const AddressType &address, EntryType *entry,
AddressType *entry_base, AddressType *entry_delta,
AddressType *entry_size) const;
AddressType *entry_base, AddressType *entry_size) const;
// Locates the range encompassing the supplied address, if one exists.
// If no range encompasses the supplied address, locates the nearest range
// to the supplied address that is lower than the address. Returns false
// if no range meets these criteria. entry_base, entry_delta, and entry_size,
// if non-NULL, are set to the base, delta, and size of the entry's range.
// A positive entry delta (> 0) indicates that there was an overlap and the
// entry was shrunk down (original start address was increased by delta).
// if no range meets these criteria. entry_base and entry_size, if
// non-NULL, are set to the base and size of the entry's range.
bool RetrieveNearestRange(const AddressType &address, EntryType *entry,
AddressType *entry_base, AddressType *entry_delta,
AddressType *entry_size) const;
AddressType *entry_base, AddressType *entry_size)
const;
// Treating all ranges as a list ordered by the address spaces that they
// occupy, locates the range at the index specified by index. Returns
// false if index is larger than the number of ranges stored. entry_base,
// entry_delta, and entry_size, if non-NULL, are set to the base, delta, and
// size of the entry's range.
// A positive entry delta (> 0) indicates that there was an overlap and the
// entry was shrunk down (original start address was increased by delta).
// false if index is larger than the number of ranges stored. entry_base
// and entry_size, if non-NULL, are set to the base and size of the entry's
// range.
//
// RetrieveRangeAtIndex is not optimized for speedy operation.
bool RetrieveRangeAtIndex(int index, EntryType *entry,
AddressType *entry_base, AddressType *entry_delta,
AddressType *entry_size) const;
AddressType *entry_base, AddressType *entry_size)
const;
// Returns the number of ranges stored in the RangeMap.
int GetCount() const;
@ -114,19 +99,12 @@ class RangeMap {
friend class ModuleComparer;
friend class RangeMapSerializer<AddressType, EntryType>;
// Same a StoreRange() with the only exception that the |delta| can be
// passed in.
bool StoreRangeInternal(const AddressType &base, const AddressType &delta,
const AddressType &size, const EntryType &entry);
class Range {
public:
Range(const AddressType &base, const AddressType &delta,
const EntryType &entry)
: base_(base), delta_(delta), entry_(entry) {}
Range(const AddressType &base, const EntryType &entry)
: base_(base), entry_(entry) {}
AddressType base() const { return base_; }
AddressType delta() const { return delta_; }
EntryType entry() const { return entry_; }
private:
@ -134,9 +112,6 @@ class RangeMap {
// be stored, because RangeMap uses it as the key to the map.
const AddressType base_;
// The delta when the range is shrunk down.
const AddressType delta_;
// The entry corresponding to a range.
const EntryType entry_;
};
@ -146,9 +121,6 @@ class RangeMap {
typedef typename AddressToRangeMap::const_iterator MapConstIterator;
typedef typename AddressToRangeMap::value_type MapValue;
// Whether overlapping ranges can be shrunk down.
bool enable_shrink_down_;
// Maps the high address of each range to a EntryType.
AddressToRangeMap map_;
};

View File

@ -1,355 +0,0 @@
// Copyright (c) 2016, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
// range_map_shrink_down_unittest.cc: Unit tests for RangeMap that specifically
// test shrink down when ranges overlap.
//
// Author: Ivan Penkov
#include <limits.h>
#include <stdio.h>
#include "processor/range_map-inl.h"
#include "breakpad_googletest_includes.h"
#include "common/scoped_ptr.h"
#include "processor/linked_ptr.h"
#include "processor/logging.h"
namespace {
using google_breakpad::linked_ptr;
using google_breakpad::scoped_ptr;
using google_breakpad::RangeMap;
// A CountedObject holds an int. A global (not thread safe!) count of
// allocated CountedObjects is maintained to help test memory management.
class CountedObject {
public:
explicit CountedObject(int id) : id_(id) { ++count_; }
~CountedObject() { --count_; }
static int count() { return count_; }
int id() const { return id_; }
private:
static int count_;
int id_;
};
int CountedObject::count_;
typedef int AddressType;
typedef RangeMap<AddressType, linked_ptr<CountedObject>> TestMap;
// Same range cannot be stored wice.
TEST(RangeMap, TestShinkDown_SameRange) {
TestMap range_map;
range_map.SetEnableShrinkDown(true);
linked_ptr<CountedObject> object_1(new CountedObject(1));
EXPECT_TRUE(range_map.StoreRange(0 /* base address */, 100 /* size */,
object_1));
// Same range cannot be stored wice.
linked_ptr<CountedObject> object_2(new CountedObject(2));
EXPECT_FALSE(range_map.StoreRange(0 /* base address */, 100 /* size */,
object_2));
}
// If a range is completely contained by another range, then the larger range
// should be shrinked down.
TEST(RangeMap, TestShinkDown_CompletelyContained) {
TestMap range_map;
range_map.SetEnableShrinkDown(true);
// Larger range is added first.
linked_ptr<CountedObject> object_1(new CountedObject(1));
EXPECT_TRUE(range_map.StoreRange(0 /* base address */, 100 /* size */,
object_1));
// Smaller (contained) range is added second.
linked_ptr<CountedObject> object_2(new CountedObject(2));
EXPECT_TRUE(range_map.StoreRange(10 /* base address */, 80 /* size */,
object_2));
linked_ptr<CountedObject> object;
AddressType retrieved_base = AddressType();
AddressType retrieved_delta = AddressType();
AddressType retrieved_size = AddressType();
// The first range contains the second, so the first range should have been
// shrunk to [90, 99]. Range [0, 9] should be free.
EXPECT_FALSE(range_map.RetrieveRange(0, &object, &retrieved_base,
&retrieved_delta, &retrieved_size));
EXPECT_FALSE(range_map.RetrieveRange(9, &object, &retrieved_base,
&retrieved_delta, &retrieved_size));
EXPECT_TRUE(range_map.RetrieveRange(90, &object, &retrieved_base,
&retrieved_delta, &retrieved_size));
EXPECT_EQ(1, object->id());
EXPECT_EQ(90, retrieved_base);
EXPECT_EQ(90, retrieved_delta);
EXPECT_EQ(10, retrieved_size);
// Validate the properties of the smaller range (should be untouched).
EXPECT_TRUE(range_map.RetrieveRange(10, &object, &retrieved_base,
&retrieved_delta, &retrieved_size));
EXPECT_EQ(2, object->id());
EXPECT_EQ(10, retrieved_base);
EXPECT_EQ(0, retrieved_delta);
EXPECT_EQ(80, retrieved_size);
}
// Same as the previous test, however the larger range is added second.
TEST(RangeMap, TestShinkDown_CompletelyContained_LargerAddedSecond) {
TestMap range_map;
range_map.SetEnableShrinkDown(true);
// Smaller (contained) range is added first.
linked_ptr<CountedObject> object_1(new CountedObject(1));
EXPECT_TRUE(range_map.StoreRange(10 /* base address */, 80 /* size */,
object_1));
// Larger range is added second.
linked_ptr<CountedObject> object_2(new CountedObject(2));
EXPECT_TRUE(range_map.StoreRange(0 /* base address */, 100 /* size */,
object_2));
linked_ptr<CountedObject> object;
AddressType retrieved_base = AddressType();
AddressType retrieved_delta = AddressType();
AddressType retrieved_size = AddressType();
// The second range contains the first, so the second range should have been
// shrunk to [90, 99]. Range [0, 9] should be free.
EXPECT_FALSE(range_map.RetrieveRange(0, &object, &retrieved_base,
&retrieved_delta, &retrieved_size));
EXPECT_FALSE(range_map.RetrieveRange(9, &object, &retrieved_base,
&retrieved_delta, &retrieved_size));
EXPECT_TRUE(range_map.RetrieveRange(90, &object, &retrieved_base,
&retrieved_delta, &retrieved_size));
EXPECT_EQ(2, object->id());
EXPECT_EQ(90, retrieved_base);
EXPECT_EQ(90, retrieved_delta);
EXPECT_EQ(10, retrieved_size);
// Validate the properties of the smaller range (should be untouched).
EXPECT_TRUE(range_map.RetrieveRange(10, &object, &retrieved_base,
&retrieved_delta, &retrieved_size));
EXPECT_EQ(1, object->id());
EXPECT_EQ(10, retrieved_base);
EXPECT_EQ(0, retrieved_delta);
EXPECT_EQ(80, retrieved_size);
}
TEST(RangeMap, TestShinkDown_PartialOverlap_AtBeginning) {
TestMap range_map;
range_map.SetEnableShrinkDown(true);
linked_ptr<CountedObject> object_1(new CountedObject(1));
EXPECT_TRUE(range_map.StoreRange(0 /* base address */, 100 /* size */,
object_1));
// Partial overlap at the beginning of the new range.
linked_ptr<CountedObject> object_2(new CountedObject(2));
EXPECT_TRUE(range_map.StoreRange(90 /* base address */, 110 /* size */,
object_2));
linked_ptr<CountedObject> object;
AddressType retrieved_base = AddressType();
AddressType retrieved_delta = AddressType();
AddressType retrieved_size = AddressType();
// The second range is supposed to be shrunk down so the following address
// should resize in the first range.
EXPECT_TRUE(range_map.RetrieveRange(99, &object, &retrieved_base,
&retrieved_delta, &retrieved_size));
EXPECT_EQ(1, object->id());
EXPECT_EQ(0, retrieved_base);
EXPECT_EQ(0, retrieved_delta);
EXPECT_EQ(100, retrieved_size);
// Validate the properties of the shrunk down range.
EXPECT_TRUE(range_map.RetrieveRange(100, &object, &retrieved_base,
&retrieved_delta, &retrieved_size));
EXPECT_EQ(2, object->id());
EXPECT_EQ(100, retrieved_base);
EXPECT_EQ(10, retrieved_delta);
EXPECT_EQ(100, retrieved_size);
}
TEST(RangeMap, TestShinkDown_PartialOverlap_AtEnd) {
TestMap range_map;
range_map.SetEnableShrinkDown(true);
linked_ptr<CountedObject> object_1(new CountedObject(1));
EXPECT_TRUE(range_map.StoreRange(50 /* base address */, 50 /* size */,
object_1));
// Partial overlap at the end of the new range.
linked_ptr<CountedObject> object_2(new CountedObject(2));
EXPECT_TRUE(range_map.StoreRange(0 /* base address */, 70 /* size */,
object_2));
linked_ptr<CountedObject> object;
AddressType retrieved_base = AddressType();
AddressType retrieved_delta = AddressType();
AddressType retrieved_size = AddressType();
// The first range is supposed to be shrunk down so the following address
// should resize in the first range.
EXPECT_TRUE(range_map.RetrieveRange(69, &object, &retrieved_base,
&retrieved_delta, &retrieved_size));
EXPECT_EQ(2, object->id());
EXPECT_EQ(0, retrieved_base);
EXPECT_EQ(0, retrieved_delta);
EXPECT_EQ(70, retrieved_size);
// Validate the properties of the shrunk down range.
EXPECT_TRUE(range_map.RetrieveRange(70, &object, &retrieved_base,
&retrieved_delta, &retrieved_size));
EXPECT_EQ(1, object->id());
EXPECT_EQ(70, retrieved_base);
EXPECT_EQ(20, retrieved_delta);
EXPECT_EQ(30, retrieved_size);
}
// A new range is overlapped at both ends. The new range and the range
// that overlaps at the end should be shrink. The range that overlaps at the
// beginning should be left untouched.
TEST(RangeMap, TestShinkDown_OverlapAtBothEnds) {
TestMap range_map;
range_map.SetEnableShrinkDown(true);
// This should overlap object_3 at the beginning.
linked_ptr<CountedObject> object_1(new CountedObject(1));
EXPECT_TRUE(range_map.StoreRange(0 /* base address */, 100 /* size */,
object_1));
// This should overlap object_3 at the end.
linked_ptr<CountedObject> object_2(new CountedObject(2));
EXPECT_TRUE(range_map.StoreRange(100 /* base address */, 100 /* size */,
object_2));
// This should be overlapped on both ends by object_1 and object_2.
linked_ptr<CountedObject> object_3(new CountedObject(3));
EXPECT_TRUE(range_map.StoreRange(50 /* base address */, 100 /* size */,
object_3));
linked_ptr<CountedObject> object;
AddressType retrieved_base = AddressType();
AddressType retrieved_delta = AddressType();
AddressType retrieved_size = AddressType();
// The first range should be intact.
EXPECT_TRUE(range_map.RetrieveRange(0, &object, &retrieved_base,
&retrieved_delta, &retrieved_size));
EXPECT_EQ(1, object->id());
EXPECT_EQ(0, retrieved_base);
EXPECT_EQ(0, retrieved_delta);
EXPECT_EQ(100, retrieved_size);
// The second range should be shrunk down by 50.
EXPECT_TRUE(range_map.RetrieveRange(150, &object, &retrieved_base,
&retrieved_delta, &retrieved_size));
EXPECT_EQ(2, object->id());
EXPECT_EQ(150, retrieved_base);
EXPECT_EQ(50, retrieved_delta);
EXPECT_EQ(50, retrieved_size);
// The third range (in the middle) should be shrunk down by 50.
EXPECT_TRUE(range_map.RetrieveRange(100, &object, &retrieved_base,
&retrieved_delta, &retrieved_size));
EXPECT_EQ(3, object->id());
EXPECT_EQ(100, retrieved_base);
EXPECT_EQ(50, retrieved_delta);
EXPECT_EQ(50, retrieved_size);
}
TEST(RangeMap, TestShinkDown_MultipleConflicts) {
TestMap range_map;
range_map.SetEnableShrinkDown(true);
// This should overlap with object_3.
linked_ptr<CountedObject> object_1(new CountedObject(1));
EXPECT_TRUE(range_map.StoreRange(10 /* base address */, 90 /* size */,
object_1));
// This should also overlap with object_3 but after object_1.
linked_ptr<CountedObject> object_2(new CountedObject(2));
EXPECT_TRUE(range_map.StoreRange(100 /* base address */, 100 /* size */,
object_2));
// This should be overlapped on both object_1 and object_2. Since
// object_3 ends with the higher address it must be shrunk.
linked_ptr<CountedObject> object_3(new CountedObject(3));
EXPECT_TRUE(range_map.StoreRange(0 /* base address */, 300 /* size */,
object_3));
linked_ptr<CountedObject> object;
AddressType retrieved_base = AddressType();
AddressType retrieved_delta = AddressType();
AddressType retrieved_size = AddressType();
// The first range should be intact.
EXPECT_TRUE(range_map.RetrieveRange(99, &object, &retrieved_base,
&retrieved_delta, &retrieved_size));
EXPECT_EQ(1, object->id());
EXPECT_EQ(10, retrieved_base);
EXPECT_EQ(0, retrieved_delta);
EXPECT_EQ(90, retrieved_size);
// The second range should be intact.
EXPECT_TRUE(range_map.RetrieveRange(199, &object, &retrieved_base,
&retrieved_delta, &retrieved_size));
EXPECT_EQ(2, object->id());
EXPECT_EQ(100, retrieved_base);
EXPECT_EQ(0, retrieved_delta);
EXPECT_EQ(100, retrieved_size);
// The third range should be shrunk down by 200.
EXPECT_TRUE(range_map.RetrieveRange(299, &object, &retrieved_base,
&retrieved_delta, &retrieved_size));
EXPECT_EQ(3, object->id());
EXPECT_EQ(200, retrieved_base);
EXPECT_EQ(200, retrieved_delta);
EXPECT_EQ(100, retrieved_size);
}
// Adding two ranges without overlap should succeed and the ranges should
// be left intact.
TEST(RangeMap, TestShinkDown_NoConflicts) {
TestMap range_map;
range_map.SetEnableShrinkDown(true);
// Adding range 1.
linked_ptr<CountedObject> object_1(new CountedObject(1));
EXPECT_TRUE(range_map.StoreRange(10 /* base address */, 90 /* size */,
object_1));
// Adding range 2 - no overlap with range 1.
linked_ptr<CountedObject> object_2(new CountedObject(2));
EXPECT_TRUE(range_map.StoreRange(110 /* base address */, 90 /* size */,
object_2));
linked_ptr<CountedObject> object;
AddressType retrieved_base = AddressType();
AddressType retrieved_delta = AddressType();
AddressType retrieved_size = AddressType();
// The first range should be intact.
EXPECT_TRUE(range_map.RetrieveRange(99, &object, &retrieved_base,
&retrieved_delta, &retrieved_size));
EXPECT_EQ(1, object->id());
EXPECT_EQ(10, retrieved_base);
EXPECT_EQ(0, retrieved_delta);
EXPECT_EQ(90, retrieved_size);
// The second range should be intact.
EXPECT_TRUE(range_map.RetrieveRange(199, &object, &retrieved_base,
&retrieved_delta, &retrieved_size));
EXPECT_EQ(2, object->id());
EXPECT_EQ(110, retrieved_base);
EXPECT_EQ(0, retrieved_delta);
EXPECT_EQ(90, retrieved_size);
}
} // namespace

View File

@ -166,10 +166,8 @@ static bool RetrieveTest(TestMap *range_map, const RangeTest *range_test) {
linked_ptr<CountedObject> object;
AddressType retrieved_base = AddressType();
AddressType retrieved_size = AddressType();
AddressType retrieved_delta = AddressType();
bool retrieved = range_map->RetrieveRange(address, &object,
&retrieved_base,
&retrieved_delta,
&retrieved_size);
bool observed_result = retrieved && object->id() == range_test->id;
@ -211,12 +209,10 @@ static bool RetrieveTest(TestMap *range_map, const RangeTest *range_test) {
linked_ptr<CountedObject> nearest_object;
AddressType nearest_base = AddressType();
AddressType nearest_delta = AddressType();
AddressType nearest_size = AddressType();
bool retrieved_nearest = range_map->RetrieveNearestRange(address,
&nearest_object,
&nearest_base,
&nearest_delta,
&nearest_size);
// When checking one greater than the high side, RetrieveNearestRange
@ -278,8 +274,7 @@ static bool RetrieveIndexTest(TestMap *range_map, int set) {
int object_count = range_map->GetCount();
for (int object_index = 0; object_index < object_count; ++object_index) {
AddressType base;
if (!range_map->RetrieveRangeAtIndex(object_index, &object, &base,
NULL /* delta */, NULL /* size */)) {
if (!range_map->RetrieveRangeAtIndex(object_index, &object, &base, NULL)) {
fprintf(stderr, "FAILED: RetrieveRangeAtIndex set %d index %d, "
"expected success, observed failure\n",
set, object_index);
@ -319,8 +314,7 @@ static bool RetrieveIndexTest(TestMap *range_map, int set) {
// Make sure that RetrieveRangeAtIndex doesn't allow lookups at indices that
// are too high.
if (range_map->RetrieveRangeAtIndex(object_count, &object, NULL /* base */,
NULL /* delta */, NULL /* size */)) {
if (range_map->RetrieveRangeAtIndex(object_count, &object, NULL, NULL)) {
fprintf(stderr, "FAILED: RetrieveRangeAtIndex set %d index %d (too large), "
"expected failure, observed success\n",
set, object_count);
@ -349,8 +343,7 @@ static bool RetriveAtIndexTest2() {
int object_count = range_map->GetCount();
for (int object_index = 0; object_index < object_count; ++object_index) {
AddressType base;
if (!range_map->RetrieveRangeAtIndex(object_index, &object, &base,
NULL /* delta */, NULL /* size */)) {
if (!range_map->RetrieveRangeAtIndex(object_index, &object, &base, NULL)) {
fprintf(stderr, "FAILED: RetrieveAtIndexTest2 index %d, "
"expected success, observed failure\n", object_index);
return false;

View File

@ -41,7 +41,7 @@
#include <string>
#include <vector>
#include "common/stdio_wrapper.h"
#include "common/stdio.h"
#include "common/using_std_string.h"
#include "google_breakpad/processor/call_stack.h"
#include "google_breakpad/processor/code_module.h"

View File

@ -164,12 +164,6 @@ bool StackwalkerAMD64::IsEndOfStack(uint64_t caller_rip, uint64_t caller_rsp,
return false;
}
// Returns true if `ptr` is not in x86-64 canonical form.
// https://en.wikipedia.org/wiki/X86-64#Virtual_address_space_details
static bool is_non_canonical(uint64_t ptr) {
return ptr > 0x7FFFFFFFFFFF && ptr < 0xFFFF800000000000;
}
StackFrameAMD64* StackwalkerAMD64::GetCallerByFramePointerRecovery(
const vector<StackFrame*>& frames) {
StackFrameAMD64* last_frame = static_cast<StackFrameAMD64*>(frames.back());
@ -192,22 +186,11 @@ StackFrameAMD64* StackwalkerAMD64::GetCallerByFramePointerRecovery(
// %caller_rip = *(%callee_rbp + 8)
// %caller_rbp = *(%callee_rbp)
// If rbp is not 8-byte aligned it can't be a frame pointer.
if (last_rbp % 8 != 0) {
return NULL;
}
uint64_t caller_rip, caller_rbp;
if (memory_->GetMemoryAtAddress(last_rbp + 8, &caller_rip) &&
memory_->GetMemoryAtAddress(last_rbp, &caller_rbp)) {
uint64_t caller_rsp = last_rbp + 16;
// If the recovered rip is not a canonical address it can't be
// the return address, so rbp must not have been a frame pointer.
if (is_non_canonical(caller_rip)) {
return NULL;
}
// Simple sanity check that the stack is growing downwards as expected.
if (IsEndOfStack(caller_rip, caller_rsp, last_rsp) ||
caller_rbp < last_rbp) {

View File

@ -72,8 +72,8 @@ class StackwalkerAMD64Fixture {
: stack_section(kLittleEndian),
// Give the two modules reasonable standard locations and names
// for tests to play with.
module1(0x00007400c0000000ULL, 0x10000, "module1", "version1"),
module2(0x00007500b0000000ULL, 0x10000, "module2", "version2") {
module1(0x40000000c0000000ULL, 0x10000, "module1", "version1"),
module2(0x50000000b0000000ULL, 0x10000, "module2", "version2") {
// Identify the system as a Linux system.
system_info.os = "Linux";
system_info.os_short = "linux";
@ -149,7 +149,7 @@ TEST_F(SanityCheck, NoResolver) {
// provide any call frame information, so trying to reconstruct the
// context frame's caller should fail. So there's no need for us to
// provide stack contents.
raw_context.rip = 0x00007400c0000200ULL;
raw_context.rip = 0x40000000c0000200ULL;
raw_context.rbp = 0x8000000080000000ULL;
StackFrameSymbolizer frame_symbolizer(NULL, NULL);
@ -176,7 +176,7 @@ TEST_F(GetContextFrame, Simple) {
// provide any call frame information, so trying to reconstruct the
// context frame's caller should fail. So there's no need for us to
// provide stack contents.
raw_context.rip = 0x00007400c0000200ULL;
raw_context.rip = 0x40000000c0000200ULL;
raw_context.rbp = 0x8000000080000000ULL;
StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
@ -200,7 +200,7 @@ TEST_F(GetContextFrame, Simple) {
// The stackwalker should be able to produce the context frame even
// without stack memory present.
TEST_F(GetContextFrame, NoStackMemory) {
raw_context.rip = 0x00007400c0000200ULL;
raw_context.rip = 0x40000000c0000200ULL;
raw_context.rbp = 0x8000000080000000ULL;
StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
@ -230,23 +230,23 @@ TEST_F(GetCallerFrame, ScanWithoutSymbols) {
// Force scanning through three frames to ensure that the
// stack pointer is set properly in scan-recovered frames.
stack_section.start() = 0x8000000080000000ULL;
uint64_t return_address1 = 0x00007500b0000100ULL;
uint64_t return_address2 = 0x00007500b0000900ULL;
uint64_t return_address1 = 0x50000000b0000100ULL;
uint64_t return_address2 = 0x50000000b0000900ULL;
Label frame1_sp, frame2_sp, frame1_rbp;
stack_section
// frame 0
.Append(16, 0) // space
.D64(0x00007400b0000000ULL) // junk that's not
.D64(0x00007500d0000000ULL) // a return address
.D64(0x40000000b0000000ULL) // junk that's not
.D64(0x50000000d0000000ULL) // a return address
.D64(return_address1) // actual return address
// frame 1
.Mark(&frame1_sp)
.Append(16, 0) // space
.D64(0x00007400b0000000ULL) // more junk
.D64(0x00007500d0000000ULL)
.D64(0x40000000b0000000ULL) // more junk
.D64(0x50000000d0000000ULL)
.Mark(&frame1_rbp)
.D64(stack_section.start()) // This is in the right place to be
@ -260,7 +260,7 @@ TEST_F(GetCallerFrame, ScanWithoutSymbols) {
RegionFromSection();
raw_context.rip = 0x00007400c0000200ULL;
raw_context.rip = 0x40000000c0000200ULL;
raw_context.rbp = frame1_rbp.Value();
raw_context.rsp = stack_section.start().Value();
@ -308,18 +308,18 @@ TEST_F(GetCallerFrame, ScanWithFunctionSymbols) {
// it is only considered a valid return address if it
// lies within a function's bounds.
stack_section.start() = 0x8000000080000000ULL;
uint64_t return_address = 0x00007500b0000110ULL;
uint64_t return_address = 0x50000000b0000110ULL;
Label frame1_sp, frame1_rbp;
stack_section
// frame 0
.Append(16, 0) // space
.D64(0x00007400b0000000ULL) // junk that's not
.D64(0x00007500b0000000ULL) // a return address
.D64(0x40000000b0000000ULL) // junk that's not
.D64(0x50000000b0000000ULL) // a return address
.D64(0x00007400c0001000ULL) // a couple of plausible addresses
.D64(0x00007500b000aaaaULL) // that are not within functions
.D64(0x40000000c0001000ULL) // a couple of plausible addresses
.D64(0x50000000b000aaaaULL) // that are not within functions
.D64(return_address) // actual return address
// frame 1
@ -328,7 +328,7 @@ TEST_F(GetCallerFrame, ScanWithFunctionSymbols) {
.Mark(&frame1_rbp);
RegionFromSection();
raw_context.rip = 0x00007400c0000200ULL;
raw_context.rip = 0x40000000c0000200ULL;
raw_context.rbp = frame1_rbp.Value();
raw_context.rsp = stack_section.start().Value();
@ -355,7 +355,7 @@ TEST_F(GetCallerFrame, ScanWithFunctionSymbols) {
EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity);
EXPECT_EQ("platypus", frame0->function_name);
EXPECT_EQ(0x00007400c0000100ULL, frame0->function_base);
EXPECT_EQ(0x40000000c0000100ULL, frame0->function_base);
StackFrameAMD64 *frame1 = static_cast<StackFrameAMD64 *>(frames->at(1));
EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
@ -367,7 +367,7 @@ TEST_F(GetCallerFrame, ScanWithFunctionSymbols) {
EXPECT_EQ(frame1_sp.Value(), frame1->context.rsp);
EXPECT_EQ(frame1_rbp.Value(), frame1->context.rbp);
EXPECT_EQ("echidna", frame1->function_name);
EXPECT_EQ(0x00007500b0000100ULL, frame1->function_base);
EXPECT_EQ(0x50000000b0000100ULL, frame1->function_base);
}
// StackwalkerAMD64::GetCallerByFramePointerRecovery should never return an
@ -502,107 +502,6 @@ TEST_F(GetCallerFrame, GetCallerByFramePointerRecovery) {
}
}
// Don't use frame pointer recovery if %rbp is not 8-byte aligned, which
// indicates that it's not being used as a frame pointer.
TEST_F(GetCallerFrame, FramePointerNotAligned) {
stack_section.start() = 0x8000000080000000ULL;
uint64_t return_address1 = 0x00007500b0000100ULL;
Label frame0_rbp, not_frame1_rbp, frame1_sp;
stack_section
// frame 0
.Align(8, 0)
.Append(2, 0) // mis-align the frame pointer
.Mark(&frame0_rbp)
.D64(not_frame1_rbp) // not the previous frame pointer
.D64(0x00007500b0000a00ULL) // plausible but wrong return address
.Align(8, 0)
.D64(return_address1) // return address
// frame 1
.Mark(&frame1_sp)
.Mark(&not_frame1_rbp)
.Append(32, 0); // end of stack
RegionFromSection();
raw_context.rip = 0x00007400c0000200ULL;
raw_context.rbp = frame0_rbp.Value();
raw_context.rsp = stack_section.start().Value();
StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
&frame_symbolizer);
vector<const CodeModule*> modules_without_symbols;
vector<const CodeModule*> modules_with_corrupt_symbols;
ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
&modules_with_corrupt_symbols));
frames = call_stack.frames();
ASSERT_EQ(2U, frames->size());
StackFrameAMD64 *frame0 = static_cast<StackFrameAMD64 *>(frames->at(0));
EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity);
EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
StackFrameAMD64 *frame1 = static_cast<StackFrameAMD64 *>(frames->at(1));
EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP |
StackFrameAMD64::CONTEXT_VALID_RSP),
frame1->context_validity);
EXPECT_EQ(return_address1, frame1->context.rip);
EXPECT_EQ(frame1_sp.Value(), frame1->context.rsp);
}
// Don't use frame pointer recovery if the recovered %rip is not
// a canonical x86-64 address.
TEST_F(GetCallerFrame, NonCanonicalInstructionPointerFromFramePointer) {
stack_section.start() = 0x8000000080000000ULL;
uint64_t return_address1 = 0x00007500b0000100ULL;
Label frame0_rbp, frame1_sp, not_frame1_bp;
stack_section
// frame 0
.Align(8, 0)
.Mark(&frame0_rbp)
.D64(not_frame1_bp) // some junk on the stack
.D64(0xDADADADADADADADA) // not the return address
.D64(return_address1) // return address
// frame 1
.Mark(&frame1_sp)
.Append(16, 0)
.Mark(&not_frame1_bp)
.Append(32, 0); // end of stack
RegionFromSection();
raw_context.rip = 0x00007400c0000200ULL;
raw_context.rbp = frame0_rbp.Value();
raw_context.rsp = stack_section.start().Value();
StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
StackwalkerAMD64 walker(&system_info, &raw_context, &stack_region, &modules,
&frame_symbolizer);
vector<const CodeModule*> modules_without_symbols;
vector<const CodeModule*> modules_with_corrupt_symbols;
ASSERT_TRUE(walker.Walk(&call_stack, &modules_without_symbols,
&modules_with_corrupt_symbols));
frames = call_stack.frames();
ASSERT_EQ(2U, frames->size());
StackFrameAMD64 *frame0 = static_cast<StackFrameAMD64 *>(frames->at(0));
EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity);
EXPECT_EQ(0, memcmp(&raw_context, &frame0->context, sizeof(raw_context)));
StackFrameAMD64 *frame1 = static_cast<StackFrameAMD64 *>(frames->at(1));
EXPECT_EQ(StackFrame::FRAME_TRUST_SCAN, frame1->trust);
ASSERT_EQ((StackFrameAMD64::CONTEXT_VALID_RIP |
StackFrameAMD64::CONTEXT_VALID_RSP),
frame1->context_validity);
EXPECT_EQ(return_address1, frame1->context.rip);
EXPECT_EQ(frame1_sp.Value(), frame1->context.rsp);
}
// Test that set_max_frames_scanned prevents using stack scanning
// to find caller frames.
TEST_F(GetCallerFrame, ScanningNotAllowed) {
@ -610,23 +509,23 @@ TEST_F(GetCallerFrame, ScanningNotAllowed) {
// only addresses located within loaded modules are
// considered valid return addresses.
stack_section.start() = 0x8000000080000000ULL;
uint64_t return_address1 = 0x00007500b0000100ULL;
uint64_t return_address2 = 0x00007500b0000900ULL;
uint64_t return_address1 = 0x50000000b0000100ULL;
uint64_t return_address2 = 0x50000000b0000900ULL;
Label frame1_sp, frame2_sp, frame1_rbp;
stack_section
// frame 0
.Append(16, 0) // space
.D64(0x00007400b0000000ULL) // junk that's not
.D64(0x00007500d0000000ULL) // a return address
.D64(0x40000000b0000000ULL) // junk that's not
.D64(0x50000000d0000000ULL) // a return address
.D64(return_address1) // actual return address
// frame 1
.Mark(&frame1_sp)
.Append(16, 0) // space
.D64(0x00007400b0000000ULL) // more junk
.D64(0x00007500d0000000ULL)
.D64(0x40000000b0000000ULL) // more junk
.D64(0x50000000d0000000ULL)
.Mark(&frame1_rbp)
.D64(stack_section.start()) // This is in the right place to be
@ -640,7 +539,7 @@ TEST_F(GetCallerFrame, ScanningNotAllowed) {
RegionFromSection();
raw_context.rip = 0x00007400c0000200ULL;
raw_context.rip = 0x40000000c0000200ULL;
raw_context.rbp = frame1_rbp.Value();
raw_context.rsp = stack_section.start().Value();
@ -671,18 +570,18 @@ TEST_F(GetCallerFrame, CallerPushedRBP) {
// %rbp directly below the return address, assume that it is indeed the
// next frame's %rbp.
stack_section.start() = 0x8000000080000000ULL;
uint64_t return_address = 0x00007500b0000110ULL;
uint64_t return_address = 0x50000000b0000110ULL;
Label frame0_rbp, frame1_sp, frame1_rbp;
stack_section
// frame 0
.Append(16, 0) // space
.D64(0x00007400b0000000ULL) // junk that's not
.D64(0x00007500b0000000ULL) // a return address
.D64(0x40000000b0000000ULL) // junk that's not
.D64(0x50000000b0000000ULL) // a return address
.D64(0x00007400c0001000ULL) // a couple of plausible addresses
.D64(0x00007500b000aaaaULL) // that are not within functions
.D64(0x40000000c0001000ULL) // a couple of plausible addresses
.D64(0x50000000b000aaaaULL) // that are not within functions
.Mark(&frame0_rbp)
.D64(frame1_rbp) // caller-pushed %rbp
@ -693,7 +592,7 @@ TEST_F(GetCallerFrame, CallerPushedRBP) {
.Mark(&frame1_rbp); // end of stack
RegionFromSection();
raw_context.rip = 0x00007400c0000200ULL;
raw_context.rip = 0x40000000c0000200ULL;
raw_context.rbp = frame0_rbp.Value();
raw_context.rsp = stack_section.start().Value();
@ -721,7 +620,7 @@ TEST_F(GetCallerFrame, CallerPushedRBP) {
ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity);
EXPECT_EQ(frame0_rbp.Value(), frame0->context.rbp);
EXPECT_EQ("sasquatch", frame0->function_name);
EXPECT_EQ(0x00007400c0000100ULL, frame0->function_base);
EXPECT_EQ(0x40000000c0000100ULL, frame0->function_base);
StackFrameAMD64 *frame1 = static_cast<StackFrameAMD64 *>(frames->at(1));
EXPECT_EQ(StackFrame::FRAME_TRUST_FP, frame1->trust);
@ -733,7 +632,7 @@ TEST_F(GetCallerFrame, CallerPushedRBP) {
EXPECT_EQ(frame1_sp.Value(), frame1->context.rsp);
EXPECT_EQ(frame1_rbp.Value(), frame1->context.rbp);
EXPECT_EQ("yeti", frame1->function_name);
EXPECT_EQ(0x00007500b0000100ULL, frame1->function_base);
EXPECT_EQ(0x50000000b0000100ULL, frame1->function_base);
}
struct CFIFixture: public StackwalkerAMD64Fixture {
@ -764,7 +663,7 @@ struct CFIFixture: public StackwalkerAMD64Fixture {
// Provide some distinctive values for the caller's registers.
expected.rsp = 0x8000000080000000ULL;
expected.rip = 0x00007400c0005510ULL;
expected.rip = 0x40000000c0005510ULL;
expected.rbp = 0x68995b1de4700266ULL;
expected.rbx = 0x5a5beeb38de23be8ULL;
expected.r12 = 0xed1b02e8cc0fc79cULL;
@ -801,7 +700,7 @@ struct CFIFixture: public StackwalkerAMD64Fixture {
EXPECT_EQ(StackFrame::FRAME_TRUST_CONTEXT, frame0->trust);
ASSERT_EQ(StackFrameAMD64::CONTEXT_VALID_ALL, frame0->context_validity);
EXPECT_EQ("enchiridion", frame0->function_name);
EXPECT_EQ(0x00007400c0004000ULL, frame0->function_base);
EXPECT_EQ(0x40000000c0004000ULL, frame0->function_base);
StackFrameAMD64 *frame1 = static_cast<StackFrameAMD64 *>(frames->at(1));
EXPECT_EQ(StackFrame::FRAME_TRUST_CFI, frame1->trust);
@ -834,9 +733,9 @@ class CFI: public CFIFixture, public Test { };
TEST_F(CFI, At4000) {
Label frame1_rsp = expected.rsp;
stack_section
.D64(0x00007400c0005510ULL) // return address
.D64(0x40000000c0005510ULL) // return address
.Mark(&frame1_rsp); // This effectively sets stack_section.start().
raw_context.rip = 0x00007400c0004000ULL;
raw_context.rip = 0x40000000c0004000ULL;
CheckWalk();
}
@ -844,9 +743,9 @@ TEST_F(CFI, At4001) {
Label frame1_rsp = expected.rsp;
stack_section
.D64(0x5a5beeb38de23be8ULL) // saved %rbx
.D64(0x00007400c0005510ULL) // return address
.D64(0x40000000c0005510ULL) // return address
.Mark(&frame1_rsp); // This effectively sets stack_section.start().
raw_context.rip = 0x00007400c0004001ULL;
raw_context.rip = 0x40000000c0004001ULL;
raw_context.rbx = 0xbe0487d2f9eafe29ULL; // callee's (distinct) %rbx value
CheckWalk();
}
@ -855,9 +754,9 @@ TEST_F(CFI, At4002) {
Label frame1_rsp = expected.rsp;
stack_section
.D64(0x5a5beeb38de23be8ULL) // saved %rbx
.D64(0x00007400c0005510ULL) // return address
.D64(0x40000000c0005510ULL) // return address
.Mark(&frame1_rsp); // This effectively sets stack_section.start().
raw_context.rip = 0x00007400c0004002ULL;
raw_context.rip = 0x40000000c0004002ULL;
raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12
raw_context.r12 = 0xb0118de918a4bceaULL; // callee's (distinct) %r12 value
CheckWalk();
@ -870,9 +769,9 @@ TEST_F(CFI, At4003) {
.D64(0x1d20ad8acacbe930ULL) // saved %r13
.D64(0x319e68b49e3ace0fULL) // garbage
.D64(0x5a5beeb38de23be8ULL) // saved %rbx
.D64(0x00007400c0005510ULL) // return address
.D64(0x40000000c0005510ULL) // return address
.Mark(&frame1_rsp); // This effectively sets stack_section.start().
raw_context.rip = 0x00007400c0004003ULL;
raw_context.rip = 0x40000000c0004003ULL;
raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12
raw_context.r12 = 0x89d04fa804c87a43ULL; // callee's (distinct) %r12
raw_context.r13 = 0x5118e02cbdb24b03ULL; // callee's (distinct) %r13
@ -887,9 +786,9 @@ TEST_F(CFI, At4004) {
.D64(0x1d20ad8acacbe930ULL) // saved %r13
.D64(0x319e68b49e3ace0fULL) // garbage
.D64(0x5a5beeb38de23be8ULL) // saved %rbx
.D64(0x00007400c0005510ULL) // return address
.D64(0x40000000c0005510ULL) // return address
.Mark(&frame1_rsp); // This effectively sets stack_section.start().
raw_context.rip = 0x00007400c0004004ULL;
raw_context.rip = 0x40000000c0004004ULL;
raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12
raw_context.r12 = 0x89d04fa804c87a43ULL; // callee's (distinct) %r12
raw_context.r13 = 0x5118e02cbdb24b03ULL; // callee's (distinct) %r13
@ -905,10 +804,10 @@ TEST_F(CFI, At4005) {
.D64(0x5a5beeb38de23be8ULL) // saved %rbx
.D64(0xaa95fa054aedfbaeULL) // garbage
.Mark(&frame1_rsp); // This effectively sets stack_section.start().
raw_context.rip = 0x00007400c0004005ULL;
raw_context.rip = 0x40000000c0004005ULL;
raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12
raw_context.r12 = 0x46b1b8868891b34aULL; // callee's %r12
raw_context.r13 = 0x00007400c0005510ULL; // return address
raw_context.r13 = 0x40000000c0005510ULL; // return address
CheckWalk();
}
@ -923,10 +822,10 @@ TEST_F(CFI, At4006) {
.D64(0x5a5beeb38de23be8ULL) // saved %rbx
.D64(0xf015ee516ad89eabULL) // garbage
.Mark(&frame1_rsp); // This effectively sets stack_section.start().
raw_context.rip = 0x00007400c0004006ULL;
raw_context.rip = 0x40000000c0004006ULL;
raw_context.rbp = frame0_rbp.Value();
raw_context.rbx = 0xed1b02e8cc0fc79cULL; // saved %r12
raw_context.r12 = 0x26e007b341acfebdULL; // callee's %r12
raw_context.r13 = 0x00007400c0005510ULL; // return address
raw_context.r13 = 0x40000000c0005510ULL; // return address
CheckWalk();
}

View File

@ -180,7 +180,7 @@ class TestValidMap : public ::testing::Test {
void TearDown() {
for (int i = 0;i < kNumberTestCases; ++i)
::operator delete(map_data[i]);
delete map_data[i];
}

View File

@ -35,7 +35,7 @@
#include <string>
#include "common/stdio_wrapper.h"
#include "common/stdio.h"
#include "google_breakpad/common/breakpad_types.h"
#include "google_breakpad/common/minidump_exception_win32.h"
#include "processor/symbolic_constants_win.h"

View File

@ -1,37 +0,0 @@
F/google-breakpad(11976): -----BEGIN BREAKPAD MICRODUMP-----
F/google-breakpad(11976): V UNKNOWN:0.0.0.0
F/google-breakpad(11976): O A mips 02 mips 3.0.8-g893bf16 #7 SMP PREEMPT Fri Jul 10 15:20:59 PDT 2015
F/google-breakpad(11976): G UNKNOWN
F/google-breakpad(11976): S 0 7F92FC38 7F92F000 00002000
F/google-breakpad(11976): S 7F92F000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
F/google-breakpad(11976): S 7F92F180 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
F/google-breakpad(11976): S 7F92F300 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C801007701000000880140770000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000094020077010000008801407700000000880200770100000088014077000000005043BD770000000099999999000000000500000000000000030000000945BA7791F4927F0000000090F8927F90F4927F5043BD7700F8927F000000005432B67790F4927F00000000
F/google-breakpad(11976): S 7F92F480 18000077000000005043BD77000000003100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFF000000005043BD77000000009402B877FFFFFFFF0000400000004000000040000456B2774041C177000000005043BD7700000000FFFFFFFF9402B87700000000000000005043BD77C000407700000077700FB877000040006805B877E02FBA7700000000C8C6BA77000000005043BD77000000009402B877EC0EB877D02F007723000000C0004077FC0300000030B7770487B7775043BD77044BBF779402B8770000000000000000010000005043BD7700000000020000000000000000000077040000005043BD7754D2BC771E000000E00C4077
F/google-breakpad(11976): S 7F92F600 D02F007701000000C0004077FC0300000030B7770487B777C0004077FC0300000030B7770487B77700000000010000005043BD770030B777000000000000000000000077370000000100000054D2BC770200000060024077C8004077888BB77717000000400A4077C8004077888BB7770100000054D2BC775043BD77A00140771000000000700377007003000030B777C00040772865BD775043BD77FC8CB777C0004077020000000070037780000000C00040772865BD77286AB77760024077C80040774CA4B777286AB777400A4077C80040774CA4B7775043BD7794D2BC770010000060300077C0004077020000005043BD77000000008001407702000000180000000000000028700377DCB0B77700000000000000000000000024AAB7775043BD7780D2BC7750300077180000000004000080D2BC77B8F7927F8C37BD7778D2BC77A0F8927F5043BD773C7EB9775043BD77B8F7927F9837BD779C37BD77B8F7927F8C37BD7778D2BC77A0F8927FE87BBC77307DB9770300000000000000
F/google-breakpad(11976): S 7F92F780 5043BD77FF00000028700377000400005043BD77B8F7927F8C37BD77E03ABD7798A4BA770000000070A7BA7784A6BA7700000000A8A8BA77E87BBC776090B67702000000A0F8927FE03ABD770445BA77A4F9927FA0F9927F7CD2BC77E87BBC7728A6BF7778F5B5778004000000040000A4F9927FF4E0B5775043BD77F844BA77A0F8927F070000005043BD770400BC77A0F8927F070000005043BD77E03ABD775043BD77D0F4B577E03ABD7788EEB5775043BD77E03ABD7700000000E03ABD775043BD7700000000A002007701000000880140770445BA77A4F9927F64DCB3775043BD770000000002000000A0F8927F5043BD770445BA77A4F9927F02000000A0F8927F5426B2779402B877FFFFFFFFA0F9927FA4F9927F5043BD770456B277736F667469727100313736373431313720302032363138303938203020313436D002007701000000880140773431383020313136383631335043BD772031333136373332504E00775043BD77C000000000000000040000000000000000000000
F/google-breakpad(11976): S 7F92F900 0000000024AAB777302030203020302030203020302032335043BD7720302030203020382865BD774000000000010000800000000030BD77504E00771800000050000000004E007702000000100000007CD2BC77E87BBC7728A6BF772C60B9772030203020302030020000000030BD7700000000000000005043BD776CD2BC7740000000DCDEB877203020302030203020302030203020305043BD7720302000010000008CD2BC775043BD77010000005043BD77000000005043BD770030BD77008D4077400000000030BD770030BD770030BD77E4F9B777A8C8B877F0C2B1775043BD770030BD775043BD77010000005043BD770000000000000000C000407768D2BC7770D2BC7702000000C4CFB877FCD185095043BD775043BD77FCD185095043BD7758F1B177C0004077144FB177D02F007701000000C0004077FC0300000030B7770487B77707000000AC50B17700000000B452C07700000000010000005043BD77B866B177040000000000000000000077380000000100000054D2BC77
F/google-breakpad(11976): S 7F92FA80 0100000000024077C8004077888BB7770300000060CDC0775043BD7788C2BE770100000003000000D02F007704000000C0004077FC0300000030B7770487B777C00040772865BD775043BD77FC8CB77700000000010000005043BD77400000005043BD770400000000400000204E00775043BD7700000000000000000400000000000000000000000000000024AAB7770010000030D9BE7704000000040000005043BD7700024077009003772865BD7700000000000000000000000000000000204E00770800000020000000004E00770000000000000000EC17C87700E0C77700E0C7772C60B9774489B7770100000000000000588AB77700000000000000005043BD770800000000000000DCDEB8775043BD7701000000400D4077004000005043BD77009003770000000048B7B7775043BD770450C0775043BD77DCDEB877080000080020C177A80600002090C877040000000100000054FC927F0400000000E0C77784CBC177B00DC177C011BF772090C877000000000800000830800377
F/google-breakpad(11976): S 7F92FC00 000000003828C17700000000000000002472C376E4FC927F5043BD775014C177E4FC927F004000005014C17700E0C77700E0C7778C2BC177C4FC927FC4FC927FC4FC927FC4FC927F2090C877C4FC927FC4FC927FEC10C17700000000E4FD927F010000006C11C1772090C8772472C3760100000000000000E86A98771012C177B0FC927FA821C77700000000000000000000000001000000FFFFFFFF080000002090C8770090BE7700500200E4FD927F03000000FFFFFFFF00000000000000000000000000000000000000000000000014000000FFFFFFFF000000000000000000000000000000006C0FC177000000000000000003000000FFFFFFFF00000000000000000000000000000000000000000000000000000000FFFFFFFF00000000000000000000000000000000030000000400000034FD927F34FD927F0000000040FD927F40FD927F0000000013AD8CAFECFD927F6465B177010000000000000000000000000000005043BD778B0000000100000060C7C077FFFFFFFFE86A9877
F/google-breakpad(11976): S 7F92FD80 00E09677500EC1771C40C07700000000F0FB927F0090C0772090C877CCEDBE77480DC877500DC877580DC877600DC877680DC87700E0967701000000DC0DC1770100000000000000E86A987764B1BE7700000000000000000000000000000000010000007E0B937F000000008E0B937FA00B937FB30B937FD60B937FE10B937FFC0B937F070C937F1E0C937F370C937F4B0C937F640C937FE30C937FFD0C937FB90E937FCE0E937FE10E937F0D0F937F370F937F470F937F510F937F8E0F937FAD0F937FC20F937F000000001000000000000000060000000010000011000000640000000300000034E0C0770400000020000000050000000B000000070000000090BE77080000000000000009000000B00DC1770B000000000000000C000000000000000D000000000000000E00000000000000170000000000000019000000D8FE927F1F000000EC0F937F00000000000000000000000013AD8CAF8ABDF68B3A80A7E02317024E000000000000000000000000000000000000000000000000
F/google-breakpad(11976): S 7F92FF00 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
F/google-breakpad(11976): S 7F930080 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
F/google-breakpad(11976): S 7F930200 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
F/google-breakpad(11976): S 7F930380 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
F/google-breakpad(11976): S 7F930500 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
F/google-breakpad(11976): S 7F930680 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
F/google-breakpad(11976): S 7F930800 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
F/google-breakpad(11976): S 7F930980 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
F/google-breakpad(11976): S 7F930B00 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002E2F63726173685F6578616D706C65005F3D2E2F63726173685F6578616D706C6500414E44524F49445F444154413D2F64617461005345434F4E444152595F53544F524147453D2F73746F726167652F7364636172643100484F4D453D2F6461746100414E44524F49445F4153534554533D2F73797374656D2F617070005445524D3D767431303000414E44524F49445F534F434B45545F616462643D313000414E44524F49445F53544F524147453D2F73746F72616765004D4B53483D2F73797374656D2F62696E2F7368004C4F4F505F4D4F554E54504F494E543D2F6D6E742F6F62620053595354454D534552564552434C415353504154483D2F7379737465
F/google-breakpad(11976): S 7F930C80 6D2F6672616D65776F726B2F73657276696365732E6A61723A2F73797374656D2F6672616D65776F726B2F65746865726E65742D736572766963652E6A61723A2F73797374656D2F6672616D65776F726B2F776966692D736572766963652E6A617200415345435F4D4F554E54504F494E543D2F6D6E742F6173656300424F4F54434C415353504154483D2F73797374656D2F6672616D65776F726B2F636F72652D6C69626172742E6A61723A2F73797374656D2F6672616D65776F726B2F636F6E7363727970742E6A61723A2F73797374656D2F6672616D65776F726B2F6F6B687474702E6A61723A2F73797374656D2F6672616D65776F726B2F636F72652D6A756E69742E6A61723A2F73797374656D2F6672616D65776F726B2F626F756E6379636173746C652E6A61723A2F73797374656D2F6672616D65776F726B2F6578742E6A61723A2F73797374656D2F6672616D65776F726B2F6672616D65776F726B2E6A61723A2F73797374656D2F6672616D65776F726B2F74656C657068
F/google-breakpad(11976): S 7F930E00 6F6E792D636F6D6D6F6E2E6A61723A2F73797374656D2F6672616D65776F726B2F766F69702D636F6D6D6F6E2E6A61723A2F73797374656D2F6672616D65776F726B2F696D732D636F6D6D6F6E2E6A61723A2F73797374656D2F6672616D65776F726B2F6D6D732D636F6D6D6F6E2E6A61723A2F73797374656D2F6672616D65776F726B2F616E64726F69642E706F6C6963792E6A61723A2F73797374656D2F6672616D65776F726B2F6170616368652D786D6C2E6A6172005348454C4C3D2F73797374656D2F62696E2F736800414E44524F49445F424F4F544C4F474F3D3100454D554C415445445F53544F524147455F534F555243453D2F6D6E742F7368656C6C2F656D756C6174656400454D554C415445445F53544F524147455F5441524745543D2F73746F726167652F656D756C6174656400484F53544E414D453D6E706D38303100555345523D726F6F7400504154483D2F7362696E3A2F76656E646F722F62696E3A2F73797374656D2F7362696E3A2F73797374656D2F62696E
F/google-breakpad(11976): S 7F930F80 3A2F73797374656D2F7862696E00414E44524F49445F50524F50455254595F574F524B53504143453D382C3000414E44524F49445F524F4F543D2F73797374656D0045585445524E414C5F53544F524147453D2F73746F726167652F656D756C617465642F6C6567616379002E2F63726173685F6578616D706C650000000000
F/google-breakpad(11976): C 0E0004000000000000000000000000000100000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000006830007700000000683000770000000068300077000000002865BD770000000000000000000000002870037700000000284400000000000000000000000000003044000000000000ECFD927F00000000E4FD927F0000000001000000000000006C11C1770000000001000000000000002472C376000000000100000000000000000000000000000001000000000000005810C17700000000000000000000000000000000000000002090C8770000000038FC927F00000000E86A987700000000EC10C177000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000007C10C1770000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
F/google-breakpad(11976): M 77C0E000 00000000 0006D000 8F36148CC4647A8116CAF2A25F591F570 crash_example
F/google-breakpad(11976): M 77A9B000 00000000 00012000 3A1A14AAD5B1EB3BC54F2E1C36CE3ACB0 libnetd_client.so
F/google-breakpad(11976): M 77ACD000 00000000 00012000 E8FC3CD6F45E059AD5849A4BEE176D0F0 libstdc++.so
F/google-breakpad(11976): M 77ADF000 00000000 00024000 07C6570597295683DE36D8FE97E6AEC30 libm.so
F/google-breakpad(11976): M 77B03000 00000000 000CB000 D1E0DFA8390BAADD25564F8B0E139FF90 libc.so
F/google-breakpad(11976): M 77BD7000 00000000 00012000 EC0B4DDBEFC52282C34AF60EEEB8EAAA0 liblog.so
F/google-breakpad(11976): M 77BE9000 00000000 00014000 8C70B1BF8FBAC1170EB21E350AB2E7580 linker
F/google-breakpad(11976): -----END BREAKPAD MICRODUMP-----

View File

@ -1,26 +0,0 @@
02-23 15:49:14.700 1740 1739 F google-breakpad: -----BEGIN BREAKPAD MICRODUMP-----
02-23 15:49:14.700 1740 1739 F google-breakpad: V UNKNOWN:0.0.0.0
02-23 15:49:14.702 1740 1739 F google-breakpad: O A mips64 01 mips64 3.10.0-gf185e20 #112 PREEMPT Mon Oct 5 11:12:49 PDT 2015
02-23 15:49:14.702 1740 1739 F google-breakpad: G UNKNOWN
02-23 15:49:14.702 1740 1739 F google-breakpad: S 0 000000FFFFCCF650 000000FFFFCCF000 0000000000001000
02-23 15:49:14.707 1740 1739 F google-breakpad: S 000000FFFFCCF000 FF0000000000000000301DF1FF00000040701DF1FF0000008C7216F1FF000000704F1DF1FF00000000301DF1FF000000604F1DF1FF000000E0511DF1FF00000040701DF1FF0000001C2E16F1FF00000080501DF1FF000000A04F1DF1FF00000090501DF1FF000000E0511DF1FF000000C08416F1FF0000000000000000000000B0501DF1FF000000C08416F1FF0000000000000000000000C0501DF1FF000000C08416F1FF000000000000000000000008521DF1FF000000C08416F1FF0000000000000000000000F8511DF1FF000000C08416F1FF000000000000000000000000000000000000001000F5F0FF0000001000F5F0FF0000001000F5F0FF0000000800F5F0FF0000000010F5F0FF00000001000000000000000010F5F0FF0000000010F5F0FF0000000800F5F0FF0000000010F5F0FF0000000800F5F0FF0000000010F5F0FF0000000010F5F0FF0000000010F5F0FF0000001010F5F0FF0000001010F5F0FF0000000010F5F0FF0000000800F5F0FF0000000010F5F0FF000000
02-23 15:49:14.708 1740 1739 F google-breakpad: S 000000FFFFCCF180 0010F5F0FF0000000010F5F0FF0000001010F5F0FF0000001010F5F0FF0000000010F5F0FF0000000800F5F0FF000000306042F1FF00000018F4CCFFFF00000018F4CCFFFF0000001010F5F0FF000000306042F1FF000000000000000000000018F4CCFFFF00000018F4CCFFFF000000000000000000000018F4CCFFFF0000000000000000000000000000000000000020F4CCFFFF00000000000000000000000010F5F0FF00000020F4CCFFFF0000000010F5F0FF00000020F4CCFFFF0000000810F5F0FF00000028F4CCFFFF0000000810F5F0FF00000028F4CCFFFF0000000010F5F0FF0000001010F5F0FF0000001010F5F0FF00000018F4CCFFFF00000030F4CCFFFF00000030F4CCFFFF0000001010F5F0FF00000030F4CCFFFF0000001010F5F0FF00000030F4CCFFFF0000000010F5F0FF0000000010F5F0FF000000306042F1FF00000060DF38F1FF000000A8F4CCFFFF0000000010F5F0FF0000000040000000000000880000000000000078462EF1FF000000D06B28F1FF000000
02-23 15:49:14.710 1740 1739 F google-breakpad: S 000000FFFFCCF300 01000000000000001010F5F0FF0000000010F5F0FF0000001010F5F0FF0000001010F5F0FF0000000010F5F0FF0000000010F5F0FF000000FFFFFFFFFFFFFF1F0010F5F0FF0000000010F5F0FF0000000010F5F0FF0000001010F5F0FF0000001010F5F0FF000000000000000000000018F4CCFFFF00000000F3CCFFFF00000018F4CCFFFF00000000F3CCFFFF0000000010F5F0FF0000000800F5F0FF000000A8F4CCFFFF0000001010F5F0FF0000000800F5F0FF000000A8F4CCFFFF000000A8F4CCFFFF0000001010F5F0FF0000000800F5F0FF000000A8F4CCFFFF000000A8F4CCFFFF0000001010F5F0FF0000000800F5F0FF000000A8F4CCFFFF000000A8F4CCFFFF00000008000000000000000800F5F0FF00000000000000000000000000000000000000000000000000000000000000000000001010F5F0FF00000078F8CCFFFF00000088F8CCFFFF000000306042F1FF00000024BB38F1FF000000FFFFFFFF0100000000000000000000005CA138F1FF0000000000000000000000
02-23 15:49:14.711 1740 1739 F google-breakpad: S 000000FFFFCCF480 A8F6CCFFFF00000008F7CCFFFF000000404538F1FF000000344E33F1FF0000004B3838F1FF00000008F7CCFFFF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000098F7CCFFFF00000098F7CCFFFF00000098F7CCFFFF00000098F7CCFFFF00000098F7CCFFFF00000098F7CCFFFF00000098F7CCFFFF000000A8F7CCFFFF000000A8F7CCFFFF000000A8F7CCFFFF000000B0F7CCFFFF000000B0F7CCFFFF000000B0F7CCFFFF000000B0F7CCFFFF000000B0F7CCFFFF000000B0F7CCFFFF000000B0F7CCFFFF000000C0F7CCFFFF000000C0F7CCFFFF000000C0F7CCFFFF0000000010F5F0FF0000000010F5F0FF0000000010F5F0FF0000001010F5F0FF0000001010F5F0FF0000001010F5F0FF0000000010F5F0FF0000000010F5F0FF0000001010F5F0FF0000001010F5F0FF000000389732F1FF000000E09432F1FF00000011000000000000001900000000000000389432F1FF0000007C9432F1FF000000
02-23 15:49:14.713 1740 1739 F google-breakpad: S 000000FFFFCCF600 50C537F1FF000000C8F6CCFFFF0000000000000000000000C8F6CCFFFF000000D100000003000000C8F6CCFFFF000000C8F6CCFFFF000000C8F6CCFFFF000000C8F6CCFFFF000000C8F6CCFFFF000000C8F6CCFFFF0000000000000000000000306042F1FF000000B0A238F1FF00000078F8CCFFFF0000000000000000000000306042F1FF000000B0A338F1FF00000078F8CCFFFF0000000000000001000000000000000000000003000000FFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000000000000000000005CA138F1FF0000000000000000000000000000000000000003000000FFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFF00000000000000000000000000000000
02-23 15:49:14.715 1740 1739 F google-breakpad: S 000000FFFFCCF780 00000000000000000000000000000000030000000400000098F7CCFFFF00000098F7CCFFFF0000000000000000000000B0F7CCFFFF000000B0F7CCFFFF0000000000000000000000EF89807E722BAE6F0820BAECFF00000078F8CCFFFF00000080462EF1FF000000ACBB1FF1FF00000008D537F1FF000000FFFFFFFFFFFFFFFF06261800000000000020B8ECFF000000306042F1FF0000003CA038F1FF000000D8DC41F1FF000000E8DC41F1FF000000F8DC41F1FF00000048C472ECFF000000306042F1FF000000D09F38F1FF0000000626180000000000443333F1FF000000404538F1FF000000000000000000000001000000000000000AFCCCFFFF00000000000000000000001AFCCCFFFF0000002CFCCCFFFF0000003FFCCCFFFF00000053FCCCFFFF0000005EFCCCFFFF00000068FCCCFFFF0000007DFCCCFFFF00000088FCCCFFFF0000009DFCCCFFFF000000B0FCCCFFFF000000C7FCCCFFFF000000E2FCCCFFFF0000008AFECCFFFF000000A4FECCFFFF000000BBFECCFFFF000000
02-23 15:49:14.716 1740 1739 F google-breakpad: S 000000FFFFCCF900 D3FECCFFFF000000F4FECCFFFF0000000DFFCCFFFF0000004AFFCCFFFF000000C9FFCCFFFF00000000000000000000001000000000000000030000000000000006000000000000000010000000000000110000000000000064000000000000000300000000000000402038F1FF0000000400000000000000380000000000000005000000000000000B000000000000000700000000000000009032F1FF000000080000000000000000000000000000000900000000000000A09F38F1FF0000000B0000000000000000000000000000000C0000000000000000000000000000000D0000000000000000000000000000000E00000000000000000000000000000017000000000000000000000000000000190000000000000040FACCFFFF0000001F00000000000000E8FFCCFFFF00000000000000000000000000000000000000EF89807E722BAE6F9B236B56712BD221000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
02-23 15:49:14.717 1740 1739 F google-breakpad: S 000000FFFFCCFA80 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
02-23 15:49:14.719 1740 1739 F google-breakpad: S 000000FFFFCCFC00 000000000000000000002E2F63726173685F6578616D706C65005F3D2E2F63726173685F6578616D706C6500414E44524F49445F444154413D2F64617461004D4B53483D2F73797374656D2F62696E2F736800484F4D453D2F6461746100555345523D726F6F7400414E44524F49445F524F4F543D2F73797374656D005445524D3D787465726D005348454C4C3D2F73797374656D2F62696E2F736800414E44524F49445F424F4F544C4F474F3D3100544D504449523D2F646174612F6C6F63616C2F746D7000414E44524F49445F4153534554533D2F73797374656D2F61707000424F4F54434C415353504154483D2F73797374656D2F6672616D65776F726B2F636F72652D6C69626172742E6A61723A2F73797374656D2F6672616D65776F726B2F636F6E7363727970742E6A61723A2F73797374656D2F6672616D65776F726B2F6F6B687474702E6A61723A2F73797374656D2F6672616D65776F726B2F636F72652D6A756E69742E6A61723A2F73797374656D2F6672616D65776F72
02-23 15:49:14.720 1740 1739 F google-breakpad: S 000000FFFFCCFD80 6B2F626F756E6379636173746C652E6A61723A2F73797374656D2F6672616D65776F726B2F6578742E6A61723A2F73797374656D2F6672616D65776F726B2F6672616D65776F726B2E6A61723A2F73797374656D2F6672616D65776F726B2F74656C6570686F6E792D636F6D6D6F6E2E6A61723A2F73797374656D2F6672616D65776F726B2F766F69702D636F6D6D6F6E2E6A61723A2F73797374656D2F6672616D65776F726B2F696D732D636F6D6D6F6E2E6A61723A2F73797374656D2F6672616D65776F726B2F6170616368652D786D6C2E6A61723A2F73797374656D2F6672616D65776F726B2F6F72672E6170616368652E687474702E6C65676163792E626F6F742E6A617200415345435F4D4F554E54504F494E543D2F6D6E742F6173656300414E44524F49445F534F434B45545F616462643D313000484F53544E414D453D67656E657269635F6D69707336340045585445524E414C5F53544F524147453D2F73746F726167652F73646361726400414E44524F49445F53544F52
02-23 15:49:14.720 1740 1739 F google-breakpad: S 000000FFFFCCFF00 4147453D2F73746F7261676500504154483D2F7362696E3A2F76656E646F722F62696E3A2F73797374656D2F7362696E3A2F73797374656D2F62696E3A2F73797374656D2F7862696E0053595354454D534552564552434C415353504154483D2F73797374656D2F6672616D65776F726B2F73657276696365732E6A61723A2F73797374656D2F6672616D65776F726B2F65746865726E65742D736572766963652E6A61723A2F73797374656D2F6672616D65776F726B2F776966692D736572766963652E6A617200414E44524F49445F50524F50455254595F574F524B53504143453D392C30002E2F63726173685F6578616D706C65000000000000000000
02-23 15:49:14.723 1740 1739 F google-breakpad: C 0E000800000000000000000000000000010000000000000000000000000000000100000000000000000000000000000038F241F1FF0000000000FFFFFFFFFFFF0000000000000000FFFF000000000000FCFFFFFFFFFFFFFF00000000000000000100000000000000010000000000000000000000000000000100000000000000010000000000000078F8CCFFFF00000088F8CCFFFF00000001000000000000001CA338F1FF00000000001000000000000820BAECFF00000048C472ECFF0000000000000000000000000000000000000028A238F1FF00000010000000000000000000000000000000306042F1FF00000050F6CCFFFF0000000626180000000000B0A238F1FF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004CA238F1FF00000000000000000000000000000000000000FFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFF7F0000000000000000
02-23 15:49:14.725 1740 1739 F google-breakpad: M 000000FFF1382000 0000000000000000 0000000000081000 6E72E2F1A5F59AB3D51356FDFE394D490 crash_example
02-23 15:49:14.725 1740 1739 F google-breakpad: M 000000FFF0FE2000 0000000000000000 0000000000014000 3C1F908C8C62D8A2EBFC12D8AF285F670 libnetd_client.so
02-23 15:49:14.726 1740 1739 F google-breakpad: M 000000FFF1016000 0000000000000000 000000000005D000 F53A8A43C039FF5DB65F78E97ADAAE000 libm.so
02-23 15:49:14.726 1740 1739 F google-breakpad: M 000000FFF1073000 0000000000000000 0000000000014000 906759235C65BD24385BA1376F1C4A0D0 libstdc++.so
02-23 15:49:14.726 1740 1739 F google-breakpad: M 000000FFF1083000 0000000000000000 0000000000150000 FF1D9D1DA2F0B636817320E78C3E2AF20 libc++.so
02-23 15:49:14.726 1740 1739 F google-breakpad: M 000000FFF11D6000 0000000000000000 0000000000109000 3A55BF92DE1E4C51F6F6140479CFA5080 libc.so
02-23 15:49:14.726 1740 1739 F google-breakpad: M 000000FFF12ED000 0000000000000000 000000000001C000 44F1FB3127301036FA2EFE040F09CF6C0 liblog.so
02-23 15:49:14.726 1740 1739 F google-breakpad: M 000000FFF1329000 0000000000000000 000000000003A000 519DF595D6558C61E962693B460A31C80 linker64
02-23 15:49:14.726 1740 1739 F google-breakpad: -----END BREAKPAD MICRODUMP-----

View File

@ -1,56 +0,0 @@
MODULE Linux mips 6E72E2F1A5F59AB3D51356FDFE394D490 crash_example
FILE 0 /s/breakpad/src/tools/linux/crash_example.cc
FUNC 80a8 9c 0 google_breakpad::MinidumpDescriptor::MinidumpDescriptor
80a8 20 75 8
80c8 38 78 8
8100 10 78 8
8110 14 78 8
8124 10 78 8
8134 10 78 8
FUNC 815c a0 0 DumpCallback
815c 2c 13 37
8188 1c 14 37
81a4 14 15 37
81b8 1c 15 37
81d4 14 17 37
81e8 4 18 37
81ec 10 19 37
FUNC 81fc 2c 0 Leaf
81fc 10 21 37
820c 8 22 37
8214 8 23 37
821c 4 25 37
8220 8 26 37
FUNC 8228 58 0 blaTest
8228 1c 28 37
8244 c 29 37
8250 20 30 37
8270 10 31 37
FUNC 8280 40 0 Crash
8280 18 33 37
8298 4 34 37
829c 14 35 37
82b0 10 36 37
FUNC 831c f4 0 main
831c 2c 40 37
8348 c 40 37
8354 18 41 37
836c 34 43 37
83a0 10 44 37
83b0 4 45 37
83b4 14 43 37
83c8 18 45 37
83e0 30 46 37
PUBLIC 831c 0 main
STACK CFI INIT 8228 58 .cfa: $sp 0 + .ra: $ra
STACK CFI 822c .cfa: $sp 32 +
STACK CFI 8234 $gp: .cfa -16 + ^ .ra: .cfa -8 + ^
STACK CFI 827c $gp: $gp .cfa: $sp 0 + .ra: .ra
STACK CFI INIT 8280 40 .cfa: $sp 0 + .ra: $ra
STACK CFI 8284 .cfa: $sp 32 +
STACK CFI 828c $gp: .cfa -16 + ^ .ra: .cfa -8 + ^
STACK CFI 82bc $gp: $gp .cfa: $sp 0 + .ra: .ra
STACK CFI INIT 831c f4 .cfa: $sp 0 + .ra: $ra
STACK CFI 8320 .cfa: $sp 352 +
STACK CFI 832c $gp: .cfa -16 + ^ $s0: .cfa -24 + ^ .ra: .cfa -8 + ^
STACK CFI 840c $gp: $gp $s0: $s0 .cfa: $sp 0 + .ra: .ra

View File

@ -1,48 +0,0 @@
MODULE Linux mips 8F36148CC4647A8116CAF2A25F591F570 crash_example
FILE 0 /home/rtrk/chromium_mips/chromium/src/out-android-mips/Debug/../../breakpad/src/tools/linux/crash_example.cc
FUNC 2ea4 b4 0 google_breakpad::MinidumpDescriptor::MinidumpDescriptor
2ea4 20 75 6
2ec4 40 78 6
2f04 18 78 6
2f1c 14 78 6
2f30 18 78 6
2f48 10 78 6
FUNC 2f6c c4 0 DumpCallback
2f6c 28 13 33
2f94 28 14 33
2fbc 1c 15 33
2fd8 28 15 33
3000 1c 17 33
301c 4 18 33
3020 10 19 33
FUNC 3030 28 0 Leaf
3030 4 21 33
3034 c 22 33
3040 c 23 33
304c 4 25 33
3050 8 26 33
FUNC 3058 60 0 blaTest
3058 1c 28 33
3074 c 29 33
3080 28 30 33
30a8 10 31 33
FUNC 30b8 48 0 Crash
30b8 18 33 33
30d0 4 34 33
30d4 1c 35 33
30f0 10 36 33
FUNC 316c 120 0 main
316c 24 40 33
3190 c 40 33
319c 20 41 33
31bc 40 43 33
31fc 18 44 33
3214 4 45 33
3218 1c 43 33
3234 20 45 33
3254 38 46 33
PUBLIC 316c 0 main
STACK CFI INIT 30b8 48 .cfa: $sp 39792944 + .ra: $ra
STACK CFI 30c8 .cfa: $sp 40 +
STACK CFI 30d0 .ra: .cfa -4 + ^
STACK CFI 30f8 .cfa: $sp 0 + .ra: .ra

View File

@ -118,7 +118,7 @@ struct WindowsFrameInfo {
uint64_t &code_size) {
// The format of a STACK WIN record is documented at:
//
// https://chromium.googlesource.com/breakpad/breakpad/+/master/docs/symbol_files.md
// http://code.google.com/p/google-breakpad/wiki/SymbolFiles
std::vector<char> buffer;
StringToVector(string, buffer);

View File

@ -1,163 +0,0 @@
musl as a whole is licensed under the following standard MIT license:
----------------------------------------------------------------------
Copyright © 2005-2014 Rich Felker, et al.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------
Authors/contributors include:
Alex Dowad
Alexander Monakov
Anthony G. Basile
Arvid Picciani
Bobby Bingham
Boris Brezillon
Brent Cook
Chris Spiegel
Clément Vasseur
Daniel Micay
Denys Vlasenko
Emil Renner Berthing
Felix Fietkau
Felix Janda
Gianluca Anzolin
Hauke Mehrtens
Hiltjo Posthuma
Isaac Dunham
Jaydeep Patil
Jens Gustedt
Jeremy Huntwork
Jo-Philipp Wich
Joakim Sindholt
John Spencer
Josiah Worcester
Justin Cormack
Khem Raj
Kylie McClain
Luca Barbato
Luka Perkov
M Farkas-Dyck (Strake)
Mahesh Bodapati
Michael Forney
Natanael Copa
Nicholas J. Kain
orc
Pascal Cuoq
Petr Hosek
Pierre Carrier
Rich Felker
Richard Pennington
Shiz
sin
Solar Designer
Stefan Kristiansson
Szabolcs Nagy
Timo Teräs
Trutz Behn
Valentin Ochs
William Haddon
Portions of this software are derived from third-party works licensed
under terms compatible with the above MIT license:
The TRE regular expression implementation (src/regex/reg* and
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
under a 2-clause BSD license (license text in the source files). The
included version has been heavily modified by Rich Felker in 2012, in
the interests of size, simplicity, and namespace cleanliness.
Much of the math library code (src/math/* and src/complex/*) is
Copyright © 1993,2004 Sun Microsystems or
Copyright © 2003-2011 David Schultz or
Copyright © 2003-2009 Steven G. Kargl or
Copyright © 2003-2009 Bruce D. Evans or
Copyright © 2008 Stephen L. Moshier
and labelled as such in comments in the individual source files. All
have been licensed under extremely permissive terms.
The ARM memcpy code (src/string/arm/memcpy_el.S) is Copyright © 2008
The Android Open Source Project and is licensed under a two-clause BSD
license. It was taken from Bionic libc, used on Android.
The implementation of DES for crypt (src/crypt/crypt_des.c) is
Copyright © 1994 David Burren. It is licensed under a BSD license.
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
originally written by Solar Designer and placed into the public
domain. The code also comes with a fallback permissive license for use
in jurisdictions that may not recognize the public domain.
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
Valentin Ochs and is licensed under an MIT-style license.
The BSD PRNG implementation (src/prng/random.c) and XSI search API
(src/search/*.c) functions are Copyright © 2011 Szabolcs Nagy and
licensed under following terms: "Permission to use, copy, modify,
and/or distribute this code for any purpose with or without fee is
hereby granted. There is no warranty."
The x86_64 port was written by Nicholas J. Kain and is licensed under
the standard MIT terms.
The mips and microblaze ports were originally written by Richard
Pennington for use in the ellcc project. The original code was adapted
by Rich Felker for build system and code conventions during upstream
integration. It is licensed under the standard MIT terms.
The mips64 port was contributed by Imagination Technologies and is
licensed under the standard MIT terms.
The powerpc port was also originally written by Richard Pennington,
and later supplemented and integrated by John Spencer. It is licensed
under the standard MIT terms.
All other files which have no copyright comments are original works
produced specifically for use as part of this library, written either
by Rich Felker, the main author of the library, or by one or more
contibutors listed above. Details on authorship of individual files
can be found in the git version control history of the project. The
omission of copyright and license comments in each file is in the
interest of source tree size.
In addition, permission is hereby granted for all public header files
(include/* and arch/*/bits/*) and crt files intended to be linked into
applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
the copyright notice and permission notice otherwise required by the
license, and to use these files without any requirement of
attribution. These files include substantial contributions from:
Bobby Bingham
John Spencer
Nicholas J. Kain
Rich Felker
Richard Pennington
Stefan Kristiansson
Szabolcs Nagy
all of whom have explicitly granted such permission.
This file previously contained text expressing a belief that most of
the files covered by the above exception were sufficiently trivial not
to be subject to copyright, resulting in confusion over whether it
negated the permissions granted in the license. In the spirit of
permissive licensing, and of not having licensing issues being an
obstacle to adoption, that text has been removed.

View File

@ -1,23 +0,0 @@
musl libc
musl, pronounced like the word "mussel", is an MIT-licensed
implementation of the standard C library targetting the Linux syscall
API, suitable for use in a wide range of deployment environments. musl
offers efficient static and dynamic linking support, lightweight code
and low runtime overhead, strong fail-safe guarantees under correct
usage, and correctness in the sense of standards conformance and
safety. musl is built on the principle that these goals are best
achieved through simple code that is easy to understand and maintain.
The 1.1 release series for musl features coverage for all interfaces
defined in ISO C99 and POSIX 2008 base, along with a number of
non-standardized interfaces for compatibility with Linux, BSD, and
glibc functionality.
For basic installation instructions, see the included INSTALL file.
Information on full musl-targeted compiler toolchains, system
bootstrapping, and Linux distributions built on musl can be found on
the project website:
http://www.musl-libc.org/

View File

@ -1,3 +0,0 @@
This directory contains the elf header from
https://git.musl-libc.org/cgit/musl/tree/
that is required to get ELF working in dump_syms on Mac OS X.

View File

@ -1 +0,0 @@
1.1.14

File diff suppressed because it is too large Load Diff

View File

@ -39,13 +39,11 @@
#include "common/linux/dump_symbols.h"
using google_breakpad::WriteSymbolFile;
using google_breakpad::WriteSymbolFileHeader;
int usage(const char* self) {
fprintf(stderr, "Usage: %s [OPTION] <binary-with-debugging-info> "
"[directories-for-debug-file]\n\n", self);
fprintf(stderr, "Options:\n");
fprintf(stderr, " -i: Output module header information only.\n");
fprintf(stderr, " -c Do not generate CFI section\n");
fprintf(stderr, " -r Do not handle inter-compilation unit references\n");
fprintf(stderr, " -v Print all warnings to stderr\n");
@ -55,29 +53,27 @@ int usage(const char* self) {
int main(int argc, char **argv) {
if (argc < 2)
return usage(argv[0]);
bool header_only = false;
bool cfi = true;
bool handle_inter_cu_refs = true;
bool log_to_stderr = false;
int arg_index = 1;
while (arg_index < argc && strlen(argv[arg_index]) > 0 &&
argv[arg_index][0] == '-') {
if (strcmp("-i", argv[arg_index]) == 0) {
header_only = true;
} else if (strcmp("-c", argv[arg_index]) == 0) {
if (strcmp("-c", argv[arg_index]) == 0) {
cfi = false;
} else if (strcmp("-r", argv[arg_index]) == 0) {
handle_inter_cu_refs = false;
} else if (strcmp("-v", argv[arg_index]) == 0) {
log_to_stderr = true;
} else {
printf("2.4 %s\n", argv[arg_index]);
return usage(argv[0]);
}
++arg_index;
}
if (arg_index == argc)
return usage(argv[0]);
// Save stderr so it can be used below.
FILE* saved_stderr = fdopen(dup(fileno(stderr)), "w");
if (!log_to_stderr) {
@ -86,6 +82,7 @@ int main(int argc, char **argv) {
// Add this brace section to silence gcc warnings.
}
}
const char* binary;
std::vector<string> debug_dirs;
binary = argv[arg_index];
@ -95,18 +92,11 @@ int main(int argc, char **argv) {
debug_dirs.push_back(argv[debug_dir_index]);
}
if (header_only) {
if (!WriteSymbolFileHeader(binary, std::cout)) {
fprintf(saved_stderr, "Failed to process file.\n");
return 1;
}
} else {
SymbolData symbol_data = cfi ? ALL_SYMBOL_DATA : NO_CFI;
google_breakpad::DumpOptions options(symbol_data, handle_inter_cu_refs);
if (!WriteSymbolFile(binary, debug_dirs, options, std::cout)) {
fprintf(saved_stderr, "Failed to write symbol file.\n");
return 1;
}
SymbolData symbol_data = cfi ? ALL_SYMBOL_DATA : NO_CFI;
google_breakpad::DumpOptions options(symbol_data, handle_inter_cu_refs);
if (!WriteSymbolFile(binary, debug_dirs, options, std::cout)) {
fprintf(saved_stderr, "Failed to write symbol file.\n");
return 1;
}
return 0;

View File

@ -39,13 +39,138 @@
// cpu: the CPU that the module was built for
// symbol_file: the contents of the breakpad-format symbol file
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "common/linux/symbol_upload.h"
#include <functional>
#include <iostream>
#include <string>
#include <vector>
using google_breakpad::sym_upload::Options;
#include "common/linux/http_upload.h"
#include "common/using_std_string.h"
using google_breakpad::HTTPUpload;
typedef struct {
string symbolsPath;
string uploadURLStr;
string proxy;
string proxy_user_pwd;
string version;
bool success;
} Options;
static void TokenizeByChar(const string &source_string,
int c, std::vector<string> *results) {
assert(results);
string::size_type cur_pos = 0, next_pos = 0;
while ((next_pos = source_string.find(c, cur_pos)) != string::npos) {
if (next_pos != cur_pos)
results->push_back(source_string.substr(cur_pos, next_pos - cur_pos));
cur_pos = next_pos + 1;
}
if (cur_pos < source_string.size() && next_pos != cur_pos)
results->push_back(source_string.substr(cur_pos));
}
//=============================================================================
// Parse out the module line which have 5 parts.
// MODULE <os> <cpu> <uuid> <module-name>
static bool ModuleDataForSymbolFile(const string &file,
std::vector<string> *module_parts) {
assert(module_parts);
const size_t kModulePartNumber = 5;
FILE* fp = fopen(file.c_str(), "r");
if (fp) {
char buffer[1024];
if (fgets(buffer, sizeof(buffer), fp)) {
string line(buffer);
string::size_type line_break_pos = line.find_first_of('\n');
if (line_break_pos == string::npos) {
assert(0 && "The file is invalid!");
fclose(fp);
return false;
}
line.resize(line_break_pos);
const char kDelimiter = ' ';
TokenizeByChar(line, kDelimiter, module_parts);
if (module_parts->size() != kModulePartNumber)
module_parts->clear();
}
fclose(fp);
}
return module_parts->size() == kModulePartNumber;
}
//=============================================================================
static string CompactIdentifier(const string &uuid) {
std::vector<string> components;
TokenizeByChar(uuid, '-', &components);
string result;
for (size_t i = 0; i < components.size(); ++i)
result += components[i];
return result;
}
//=============================================================================
static void Start(Options *options) {
std::map<string, string> parameters;
options->success = false;
std::vector<string> module_parts;
if (!ModuleDataForSymbolFile(options->symbolsPath, &module_parts)) {
fprintf(stderr, "Failed to parse symbol file!\n");
return;
}
string compacted_id = CompactIdentifier(module_parts[3]);
// Add parameters
if (!options->version.empty())
parameters["version"] = options->version;
// MODULE <os> <cpu> <uuid> <module-name>
// 0 1 2 3 4
parameters["os"] = module_parts[1];
parameters["cpu"] = module_parts[2];
parameters["debug_file"] = module_parts[4];
parameters["code_file"] = module_parts[4];
parameters["debug_identifier"] = compacted_id;
std::map<string, string> files;
files["symbol_file"] = options->symbolsPath;
string response, error;
long response_code;
bool success = HTTPUpload::SendRequest(options->uploadURLStr,
parameters,
files,
options->proxy,
options->proxy_user_pwd,
"",
&response,
&response_code,
&error);
if (!success) {
printf("Failed to send symbol file: %s\n", error.c_str());
printf("Response code: %ld\n", response_code);
printf("Response:\n");
printf("%s\n", response.c_str());
} else if (response_code == 0) {
printf("Failed to send symbol file: No response code\n");
} else if (response_code != 200) {
printf("Failed to send symbol file: Response code %ld\n", response_code);
printf("Response:\n");
printf("%s\n", response.c_str());
} else {
printf("Successfully sent the symbol file.\n");
}
options->success = success;
}
//=============================================================================
static void
@ -107,6 +232,6 @@ SetupOptions(int argc, const char *argv[], Options *options) {
int main(int argc, const char* argv[]) {
Options options;
SetupOptions(argc, argv, &options);
google_breakpad::sym_upload::Start(&options);
Start(&options);
return options.success ? 0 : 1;
}

View File

@ -36,8 +36,6 @@
162F64FA161C591500CD68D5 /* arch_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 162F64F8161C591500CD68D5 /* arch_utilities.cc */; };
162F6500161C5F2200CD68D5 /* arch_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = 162F64F8161C591500CD68D5 /* arch_utilities.cc */; };
4D72CAF513DFBAC2006CABE3 /* md5.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D72CAF413DFBAC2006CABE3 /* md5.cc */; };
8BCAAA4C1CE3A7980046090B /* elf_reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8BCAAA4A1CE3A7980046090B /* elf_reader.cc */; };
8BCAAA4D1CE3B1260046090B /* elf_reader.cc in Sources */ = {isa = PBXBuildFile; fileRef = 8BCAAA4A1CE3A7980046090B /* elf_reader.cc */; };
B84A91F8116CF78F006C210E /* libgtestmockall.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B88FB024116BDFFF00407530 /* libgtestmockall.a */; };
B84A91FB116CF7AF006C210E /* module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE241166603300407530 /* module.cc */; };
B84A91FC116CF7AF006C210E /* stabs_to_module.cc in Sources */ = {isa = PBXBuildFile; fileRef = B88FAE3C11666C8900407530 /* stabs_to_module.cc */; };
@ -282,8 +280,6 @@
8B31023E11F0CF1C00FCF3E4 /* Breakpad.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Breakpad.xcconfig; path = ../../../common/mac/Breakpad.xcconfig; sourceTree = SOURCE_ROOT; };
8B3102D411F0D60300FCF3E4 /* BreakpadDebug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = BreakpadDebug.xcconfig; path = ../../../common/mac/BreakpadDebug.xcconfig; sourceTree = SOURCE_ROOT; };
8B3102D511F0D60300FCF3E4 /* BreakpadRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = BreakpadRelease.xcconfig; path = ../../../common/mac/BreakpadRelease.xcconfig; sourceTree = SOURCE_ROOT; };
8BCAAA4A1CE3A7980046090B /* elf_reader.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = elf_reader.cc; path = ../../../common/dwarf/elf_reader.cc; sourceTree = "<group>"; };
8BCAAA4B1CE3A7980046090B /* elf_reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = elf_reader.h; path = ../../../common/dwarf/elf_reader.h; sourceTree = "<group>"; };
9BDF186D0B1BB43700F8391B /* dump_syms.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dump_syms.h; path = ../../../common/mac/dump_syms.h; sourceTree = "<group>"; };
9BDF186E0B1BB43700F8391B /* dump_syms_tool.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = dump_syms_tool.cc; sourceTree = "<group>"; };
9BE650410B52F6D800611104 /* file_id.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = file_id.cc; path = ../../../common/mac/file_id.cc; sourceTree = SOURCE_ROOT; };
@ -617,8 +613,6 @@
B88FAE1711665FE400407530 /* dwarf2diehandler.cc */,
B88FAE1811665FE400407530 /* dwarf2diehandler.h */,
B88FB0DB116CEC5800407530 /* dwarf2diehandler_unittest.cc */,
8BCAAA4A1CE3A7980046090B /* elf_reader.cc */,
8BCAAA4B1CE3A7980046090B /* elf_reader.h */,
);
name = DWARF;
sourceTree = "<group>";
@ -893,8 +887,6 @@
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
attributes = {
};
buildConfigurationList = 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "dump_syms" */;
compatibilityVersion = "Xcode 3.1";
developmentRegion = English;
@ -962,7 +954,6 @@
files = (
B88FAF38116A595400407530 /* dwarf2reader_cfi_unittest.cc in Sources */,
B88FAF3F116A5A2E00407530 /* dwarf2reader.cc in Sources */,
8BCAAA4D1CE3B1260046090B /* elf_reader.cc in Sources */,
B88FAF40116A5A2E00407530 /* bytereader.cc in Sources */,
B88FAF37116A595400407530 /* cfi_assembler.cc in Sources */,
);
@ -1080,7 +1071,6 @@
files = (
162F64FA161C591500CD68D5 /* arch_utilities.cc in Sources */,
B88FAE2C1166606200407530 /* macho_reader.cc in Sources */,
8BCAAA4C1CE3A7980046090B /* elf_reader.cc in Sources */,
B8C5B5171166534700D34F4E /* dwarf2reader.cc in Sources */,
B8C5B5181166534700D34F4E /* bytereader.cc in Sources */,
B8C5B5191166534700D34F4E /* macho_utilities.cc in Sources */,
@ -1235,11 +1225,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 8B3102D411F0D60300FCF3E4 /* BreakpadDebug.xcconfig */;
buildSettings = {
HEADER_SEARCH_PATHS = (
../../..,
../../../common/mac/include/,
../../../third_party/musl/include/,
);
HEADER_SEARCH_PATHS = ../../..;
};
name = Debug;
};
@ -1247,11 +1233,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 8B3102D511F0D60300FCF3E4 /* BreakpadRelease.xcconfig */;
buildSettings = {
HEADER_SEARCH_PATHS = (
../../..,
../../../common/mac/include/,
../../../third_party/musl/include/,
);
HEADER_SEARCH_PATHS = ../../..;
};
name = Release;
};
@ -1637,6 +1619,7 @@
GCC_PREPROCESSOR_DEFINITIONS = HAVE_MACH_O_NLIST_H;
GCC_VERSION = "";
PRODUCT_NAME = dump_syms;
SDKROOT = macosx;
};
name = Debug;
};
@ -1646,6 +1629,7 @@
GCC_PREPROCESSOR_DEFINITIONS = HAVE_MACH_O_NLIST_H;
GCC_VERSION = "";
PRODUCT_NAME = dump_syms;
SDKROOT = macosx;
};
name = Release;
};

View File

@ -51,13 +51,11 @@ using std::vector;
struct Options {
Options()
: srcPath(), dsymPath(), arch(), header_only(false),
cfi(true), handle_inter_cu_refs(true) {}
: srcPath(), dsymPath(), arch(), cfi(true), handle_inter_cu_refs(true) {}
string srcPath;
string dsymPath;
const NXArchInfo *arch;
bool header_only;
bool cfi;
bool handle_inter_cu_refs;
};
@ -153,9 +151,6 @@ static bool Start(const Options &options) {
}
}
if (options.header_only)
return dump_symbols.WriteSymbolFileHeader(std::cout);
// Read the primary file into a Breakpad Module.
Module* module = NULL;
if (!dump_symbols.ReadSymbolData(&module))
@ -194,7 +189,6 @@ static void Usage(int argc, const char *argv[]) {
fprintf(stderr, "Output a Breakpad symbol file from a Mach-o file.\n");
fprintf(stderr, "Usage: %s [-a ARCHITECTURE] [-c] [-g dSYM path] "
"<Mach-o file>\n", argv[0]);
fprintf(stderr, "\t-i: Output module header information only.\n");
fprintf(stderr, "\t-a: Architecture type [default: native, or whatever is\n");
fprintf(stderr, "\t in the file, if it contains only one architecture]\n");
fprintf(stderr, "\t-g: Debug symbol file (dSYM) to dump in addition to the "
@ -210,11 +204,8 @@ static void SetupOptions(int argc, const char *argv[], Options *options) {
extern int optind;
signed char ch;
while ((ch = getopt(argc, (char * const *)argv, "ia:g:chr?")) != -1) {
while ((ch = getopt(argc, (char * const *)argv, "a:g:chr?")) != -1) {
switch (ch) {
case 'i':
options->header_only = true;
break;
case 'a': {
const NXArchInfo *arch_info =
google_breakpad::BreakpadGetArchInfoFromName(optarg);

View File

@ -54,7 +54,7 @@ class SymbolFileParser(object):
"""Parser for Breakpad symbol files.
The format of these files is documented at
https://chromium.googlesource.com/breakpad/breakpad/+/master/docs/symbol_files.md
https://code.google.com/p/google-breakpad/wiki/SymbolFiles
"""
def __init__(self, input_stream, output_stream, ignored_prefixes=None,