aboutsummaryrefslogtreecommitdiff
path: root/src/common/linux
diff options
context:
space:
mode:
authorjimblandy <jimblandy@4c0a9323-5329-0410-9bdc-e9ce6186880e>2010-03-02 19:39:18 +0000
committerjimblandy <jimblandy@4c0a9323-5329-0410-9bdc-e9ce6186880e>2010-03-02 19:39:18 +0000
commit81aadb99a6acf7f1175e8c6f538a609c96b3a961 (patch)
tree8c3074646f1aec6c144ffbfaad2ba8a8550d0bb9 /src/common/linux
parentARM support, with some build system changes to support x86-64, arm, and i386 ... (diff)
downloadbreakpad-81aadb99a6acf7f1175e8c6f538a609c96b3a961.tar.xz
Breakpad Linux dumper: Tolerate STABS data from code linked with --gc-sections.
Programs compiled with -ffunction-sections -Wl,--gc-sections may have SO entries for the start of the compilation unit whose addresses are zero, even when the compilation unit contains non-omitted functions at non-zero addresses. The breakpad dumper should not assume that the compilation unit starting address is always non-zero. a=jimblandy, r=nealsid git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@542 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/common/linux')
-rw-r--r--src/common/linux/dump_stabs.cc6
-rw-r--r--src/common/linux/dump_stabs.h6
-rw-r--r--src/common/linux/dump_stabs_unittest.cc16
3 files changed, 26 insertions, 2 deletions
diff --git a/src/common/linux/dump_stabs.cc b/src/common/linux/dump_stabs.cc
index adc79fd0..6842eae6 100644
--- a/src/common/linux/dump_stabs.cc
+++ b/src/common/linux/dump_stabs.cc
@@ -58,7 +58,8 @@ static string Demangle(const string &mangled) {
bool DumpStabsHandler::StartCompilationUnit(const char *name, uint64_t address,
const char *build_directory) {
- assert(!comp_unit_base_address_);
+ assert(!in_compilation_unit_);
+ in_compilation_unit_ = true;
current_source_file_name_ = name;
current_source_file_ = module_->FindFile(name);
comp_unit_base_address_ = address;
@@ -67,7 +68,8 @@ bool DumpStabsHandler::StartCompilationUnit(const char *name, uint64_t address,
}
bool DumpStabsHandler::EndCompilationUnit(uint64_t address) {
- assert(comp_unit_base_address_);
+ assert(in_compilation_unit_);
+ in_compilation_unit_ = false;
comp_unit_base_address_ = 0;
current_source_file_ = NULL;
current_source_file_name_ = NULL;
diff --git a/src/common/linux/dump_stabs.h b/src/common/linux/dump_stabs.h
index fb69e596..e6ea1d54 100644
--- a/src/common/linux/dump_stabs.h
+++ b/src/common/linux/dump_stabs.h
@@ -63,6 +63,7 @@ class DumpStabsHandler: public google_breakpad::StabsHandler {
// store it all in MODULE.
DumpStabsHandler(Module *module) :
module_(module),
+ in_compilation_unit_(false),
comp_unit_base_address_(0),
current_function_(NULL),
current_source_file_(NULL),
@@ -109,6 +110,11 @@ class DumpStabsHandler: public google_breakpad::StabsHandler {
// finding the next object.
vector<Module::Address> boundaries_;
+ // True if we are currently within a compilation unit: we have gotten a
+ // StartCompilationUnit call, but no matching EndCompilationUnit call
+ // yet. We use this for sanity checks.
+ bool in_compilation_unit_;
+
// The base address of the current compilation unit. We use this to
// recognize functions we should omit from the symbol file. (If you
// know the details of why we omit these, please patch this
diff --git a/src/common/linux/dump_stabs_unittest.cc b/src/common/linux/dump_stabs_unittest.cc
index f135d9bd..382c4f5f 100644
--- a/src/common/linux/dump_stabs_unittest.cc
+++ b/src/common/linux/dump_stabs_unittest.cc
@@ -157,6 +157,22 @@ TEST(FunctionNames, Mangled) {
ASSERT_EQ(0U, function->lines.size());
}
+// The GNU toolchain can omit functions that are not used; however,
+// when it does so, it doesn't clean up the debugging information that
+// refers to them. In STABS, this results in compilation units whose
+// SO addresses are zero.
+TEST(Omitted, Function) {
+ Module m("name", "os", "arch", "id");
+ DumpStabsHandler h(&m);
+
+ // The StartCompilationUnit and EndCompilationUnit calls may both have an
+ // address of zero if the compilation unit has had sections removed.
+ EXPECT_TRUE(h.StartCompilationUnit("compilation-unit", 0, "build-directory"));
+ EXPECT_TRUE(h.StartFunction("function", 0x2a133596));
+ EXPECT_TRUE(h.EndFunction(0));
+ EXPECT_TRUE(h.EndCompilationUnit(0));
+}
+
// TODO --- if we actually cared about STABS. Even without these we've
// got full coverage of non-failure source lines in dump_stabs.cc.