diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/linux/dump_stabs.cc | 6 | ||||
-rw-r--r-- | src/common/linux/dump_stabs.h | 6 | ||||
-rw-r--r-- | src/common/linux/dump_stabs_unittest.cc | 16 |
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. |