aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorted.mielczarek@gmail.com <ted.mielczarek@gmail.com@4c0a9323-5329-0410-9bdc-e9ce6186880e>2013-01-23 18:01:28 +0000
committerted.mielczarek@gmail.com <ted.mielczarek@gmail.com@4c0a9323-5329-0410-9bdc-e9ce6186880e>2013-01-23 18:01:28 +0000
commit1f87c4a732fa5175218549b4d7053112dbd57894 (patch)
tree9e2ff52635b97120c72dbc82f8f2e7e53f5c4d67 /src/common
parentPrint the correct return address, even on architectures where StackFrame::ins... (diff)
downloadbreakpad-1f87c4a732fa5175218549b4d7053112dbd57894.tar.xz
Include the compilation directory for FILE entries, making them absolute instead of relative
A=Ryan Sleevi <rsleevi@chromium.org> R=mark,ted at https://breakpad.appspot.com/385001/ git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1106 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/common')
-rw-r--r--src/common/dwarf_cu_to_module.cc18
-rw-r--r--src/common/dwarf_cu_to_module.h24
-rw-r--r--src/common/dwarf_cu_to_module_unittest.cc51
-rw-r--r--src/common/dwarf_line_to_module.cc27
-rw-r--r--src/common/dwarf_line_to_module.h8
-rw-r--r--src/common/dwarf_line_to_module_unittest.cc98
-rw-r--r--src/common/linux/dump_symbols.cc12
-rw-r--r--src/common/mac/dump_syms.mm14
8 files changed, 176 insertions, 76 deletions
diff --git a/src/common/dwarf_cu_to_module.cc b/src/common/dwarf_cu_to_module.cc
index 127beacb..55f69130 100644
--- a/src/common/dwarf_cu_to_module.cc
+++ b/src/common/dwarf_cu_to_module.cc
@@ -623,7 +623,7 @@ void DwarfCUToModule::WarningReporter::UnnamedFunction(uint64 offset) {
}
DwarfCUToModule::DwarfCUToModule(FileContext *file_context,
- LineToModuleFunctor *line_reader,
+ LineToModuleHandler *line_reader,
WarningReporter *reporter)
: line_reader_(line_reader), has_source_line_info_(false) {
cu_context_ = new CUContext(file_context, reporter);
@@ -666,8 +666,16 @@ void DwarfCUToModule::ProcessAttributeUnsigned(enum DwarfAttribute attr,
void DwarfCUToModule::ProcessAttributeString(enum DwarfAttribute attr,
enum DwarfForm form,
const string &data) {
- if (attr == dwarf2reader::DW_AT_name)
- cu_context_->reporter->SetCUName(data);
+ switch (attr) {
+ case dwarf2reader::DW_AT_name:
+ cu_context_->reporter->SetCUName(data);
+ break;
+ case dwarf2reader::DW_AT_comp_dir:
+ line_reader_->StartCompilationUnit(data);
+ break;
+ default:
+ break;
+ }
}
bool DwarfCUToModule::EndAttributes() {
@@ -744,8 +752,8 @@ void DwarfCUToModule::ReadSourceLines(uint64 offset) {
cu_context_->reporter->BadLineInfoOffset(offset);
return;
}
- (*line_reader_)(section_start + offset, section_length - offset,
- cu_context_->file_context->module, &lines_);
+ line_reader_->ReadProgram(section_start + offset, section_length - offset,
+ cu_context_->file_context->module, &lines_);
}
namespace {
diff --git a/src/common/dwarf_cu_to_module.h b/src/common/dwarf_cu_to_module.h
index c7072b0f..85453316 100644
--- a/src/common/dwarf_cu_to_module.h
+++ b/src/common/dwarf_cu_to_module.h
@@ -92,21 +92,27 @@ class DwarfCUToModule: public dwarf2reader::RootDIEHandler {
FilePrivate *file_private;
};
- // An abstract base class for functors that handle DWARF line data
+ // An abstract base class for handlers that handle DWARF line data
// for DwarfCUToModule. DwarfCUToModule could certainly just use
// dwarf2reader::LineInfo itself directly, but decoupling things
// this way makes unit testing a little easier.
- class LineToModuleFunctor {
+ class LineToModuleHandler {
public:
- LineToModuleFunctor() { }
- virtual ~LineToModuleFunctor() { }
+ LineToModuleHandler() { }
+ virtual ~LineToModuleHandler() { }
+
+ // Called at the beginning of a new compilation unit, prior to calling
+ // ReadProgram(). compilation_dir will indicate the path that the
+ // current compilation unit was compiled in, consistent with the
+ // DW_AT_comp_dir DIE.
+ virtual void StartCompilationUnit(const string& compilation_dir) = 0;
// Populate MODULE and LINES with source file names and code/line
// mappings, given a pointer to some DWARF line number data
// PROGRAM, and an overestimate of its size. Add no zero-length
// lines to LINES.
- virtual void operator()(const char *program, uint64 length,
- Module *module, vector<Module::Line> *lines) = 0;
+ virtual void ReadProgram(const char *program, uint64 length,
+ Module *module, vector<Module::Line> *lines) = 0;
};
// The interface DwarfCUToModule uses to report warnings. The member
@@ -186,7 +192,7 @@ class DwarfCUToModule: public dwarf2reader::RootDIEHandler {
// unit's line number data. Use REPORTER to report problems with the
// data we find.
DwarfCUToModule(FileContext *file_context,
- LineToModuleFunctor *line_reader,
+ LineToModuleHandler *line_reader,
WarningReporter *reporter);
~DwarfCUToModule();
@@ -247,8 +253,8 @@ class DwarfCUToModule: public dwarf2reader::RootDIEHandler {
// owned by this DwarfCUToModule: the constructor sets them, and the
// destructor deletes them.
- // The functor to use to handle line number data.
- LineToModuleFunctor *line_reader_;
+ // The handler to use to handle line number data.
+ LineToModuleHandler *line_reader_;
// This compilation unit's context.
CUContext *cu_context_;
diff --git a/src/common/dwarf_cu_to_module_unittest.cc b/src/common/dwarf_cu_to_module_unittest.cc
index 37061d2a..81e629b0 100644
--- a/src/common/dwarf_cu_to_module_unittest.cc
+++ b/src/common/dwarf_cu_to_module_unittest.cc
@@ -62,14 +62,11 @@ using ::testing::ValuesIn;
// Mock classes.
-class MockLineToModuleFunctor: public DwarfCUToModule::LineToModuleFunctor {
+class MockLineToModuleHandler: public DwarfCUToModule::LineToModuleHandler {
public:
- MOCK_METHOD4(mock_apply, void(const char *program, uint64 length,
- Module *module, vector<Module::Line> *lines));
- void operator()(const char *program, uint64 length,
- Module *module, vector<Module::Line> *lines) {
- mock_apply(program, length, module, lines);
- }
+ MOCK_METHOD1(StartCompilationUnit, void(const string& compilation_dir));
+ MOCK_METHOD4(ReadProgram, void(const char* program, uint64 length,
+ Module *module, vector<Module::Line> *lines));
};
class MockWarningReporter: public DwarfCUToModule::WarningReporter {
@@ -102,10 +99,10 @@ class CUFixtureBase {
// appender(line_program, length, module, line_vector);
//
// will append lines to the end of line_vector. We can use this with
- // MockLineToModuleFunctor like this:
+ // MockLineToModuleHandler like this:
//
- // MockLineToModuleFunctor l2m;
- // EXPECT_CALL(l2m, mock_apply(_,_,_,_))
+ // MockLineToModuleHandler l2m;
+ // EXPECT_CALL(l2m, ReadProgram(_,_,_,_))
// .WillOnce(DoAll(Invoke(appender), Return()));
//
// in which case calling l2m with some line vector will append lines.
@@ -143,7 +140,8 @@ class CUFixtureBase {
// By default, expect the line program reader not to be invoked. We
// may override this in StartCU.
- EXPECT_CALL(line_reader_, mock_apply(_,_,_,_)).Times(0);
+ EXPECT_CALL(line_reader_, StartCompilationUnit(_)).Times(0);
+ EXPECT_CALL(line_reader_, ReadProgram(_,_,_,_)).Times(0);
// The handler will consult this section map to decide what to
// pass to our line reader.
@@ -153,7 +151,7 @@ class CUFixtureBase {
// Add a line with the given address, size, filename, and line
// number to the end of the statement list the handler will receive
- // when it invokes its LineToModuleFunctor. Call this before calling
+ // when it invokes its LineToModuleHandler. Call this before calling
// StartCU.
void PushLine(Module::Address address, Module::Address size,
const string &filename, int line_number);
@@ -271,13 +269,17 @@ class CUFixtureBase {
// report it as an unsigned value.
bool language_signed_;
+ // If this is not empty, we'll give the CU a DW_AT_comp_dir attribute that
+ // indicates the path that this compilation unit was compiled in.
+ string compilation_dir_;
+
// If this is not empty, we'll give the CU a DW_AT_stmt_list
// attribute that, when passed to line_reader_, adds these lines to the
// provided lines array.
vector<Module::Line> lines_;
// Mock line program reader.
- MockLineToModuleFunctor line_reader_;
+ MockLineToModuleHandler line_reader_;
AppendLinesFunctor appender_;
static const char dummy_line_program_[];
static const size_t dummy_line_size_;
@@ -311,6 +313,10 @@ void CUFixtureBase::PushLine(Module::Address address, Module::Address size,
}
void CUFixtureBase::StartCU() {
+ if (!compilation_dir_.empty())
+ EXPECT_CALL(line_reader_,
+ StartCompilationUnit(compilation_dir_)).Times(1);
+
// If we have lines, make the line reader expect to be invoked at
// most once. (Hey, if the handler can pass its tests without
// bothering to read the line number data, that's great.)
@@ -318,8 +324,8 @@ void CUFixtureBase::StartCU() {
// initial expectation (no calls) in force.
if (!lines_.empty())
EXPECT_CALL(line_reader_,
- mock_apply(&dummy_line_program_[0], dummy_line_size_,
- &module_, _))
+ ReadProgram(&dummy_line_program_[0], dummy_line_size_,
+ &module_, _))
.Times(AtMost(1))
.WillOnce(DoAll(Invoke(appender_), Return()));
@@ -333,6 +339,10 @@ void CUFixtureBase::StartCU() {
root_handler_.ProcessAttributeString(dwarf2reader::DW_AT_name,
dwarf2reader::DW_FORM_strp,
"compilation-unit-name");
+ if (!compilation_dir_.empty())
+ root_handler_.ProcessAttributeString(dwarf2reader::DW_AT_comp_dir,
+ dwarf2reader::DW_FORM_strp,
+ compilation_dir_);
if (!lines_.empty())
root_handler_.ProcessAttributeUnsigned(dwarf2reader::DW_AT_stmt_list,
dwarf2reader::DW_FORM_ref4,
@@ -626,6 +636,13 @@ void CUFixtureBase::TestLine(int i, int j,
class SimpleCU: public CUFixtureBase, public Test {
};
+TEST_F(SimpleCU, CompilationDir) {
+ compilation_dir_ = "/src/build/";
+
+ StartCU();
+ root_handler_.Finish();
+}
+
TEST_F(SimpleCU, OneFunc) {
PushLine(0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, "line-file", 246571772);
@@ -1414,8 +1431,8 @@ TEST_F(Specifications, InterCU) {
Module m("module-name", "module-os", "module-arch", "module-id");
DwarfCUToModule::FileContext fc("dwarf-filename", &m);
EXPECT_CALL(reporter_, UncoveredFunction(_)).WillOnce(Return());
- MockLineToModuleFunctor lr;
- EXPECT_CALL(lr, mock_apply(_,_,_,_)).Times(0);
+ MockLineToModuleHandler lr;
+ EXPECT_CALL(lr, ReadProgram(_,_,_,_)).Times(0);
// Kludge: satisfy reporter_'s expectation.
reporter_.SetCUName("compilation-unit-name");
diff --git a/src/common/dwarf_line_to_module.cc b/src/common/dwarf_line_to_module.cc
index 962848d1..258b0b60 100644
--- a/src/common/dwarf_line_to_module.cc
+++ b/src/common/dwarf_line_to_module.cc
@@ -48,13 +48,17 @@ static bool PathIsAbsolute(const string &path) {
return (path.size() >= 1 && path[0] == '/');
}
+static bool HasTrailingSlash(const string &path) {
+ return (path.size() >= 1 && path[path.size() - 1] == '/');
+}
+
// If PATH is an absolute path, return PATH. If PATH is a relative path,
// treat it as relative to BASE and return the combined path.
static string ExpandPath(const string &path,
const string &base) {
- if (PathIsAbsolute(path))
+ if (PathIsAbsolute(path) || base.empty())
return path;
- return base + "/" + path;
+ return base + (HasTrailingSlash(base) ? "" : "/") + path;
}
namespace google_breakpad {
@@ -63,7 +67,7 @@ void DwarfLineToModule::DefineDir(const string &name, uint32 dir_num) {
// Directory number zero is reserved to mean the compilation
// directory. Silently ignore attempts to redefine it.
if (dir_num != 0)
- directories_[dir_num] = name;
+ directories_[dir_num] = ExpandPath(name, compilation_dir_);
}
void DwarfLineToModule::DefineFile(const string &name, int32 file_num,
@@ -74,25 +78,26 @@ void DwarfLineToModule::DefineFile(const string &name, int32 file_num,
else if (file_num > highest_file_number_)
highest_file_number_ = file_num;
- string full_name;
- if (dir_num != 0) {
+ string dir_name;
+ if (dir_num == 0) {
+ // Directory number zero is the compilation directory, and is stored as
+ // an attribute on the compilation unit, rather than in the program table.
+ dir_name = compilation_dir_;
+ } else {
DirectoryTable::const_iterator directory_it = directories_.find(dir_num);
if (directory_it != directories_.end()) {
- full_name = ExpandPath(name, directory_it->second);
+ dir_name = directory_it->second;
} else {
if (!warned_bad_directory_number_) {
fprintf(stderr, "warning: DWARF line number data refers to undefined"
" directory numbers\n");
warned_bad_directory_number_ = true;
}
- full_name = name; // just treat name as relative
}
- } else {
- // Directory number zero is the compilation directory; we just report
- // relative paths in that case.
- full_name = name;
}
+ string full_name = ExpandPath(name, dir_name);
+
// Find a Module::File object of the given name, and add it to the
// file table.
files_[file_num] = module_->FindFile(full_name);
diff --git a/src/common/dwarf_line_to_module.h b/src/common/dwarf_line_to_module.h
index 9382e40d..1fdd4cb7 100644
--- a/src/common/dwarf_line_to_module.h
+++ b/src/common/dwarf_line_to_module.h
@@ -120,8 +120,10 @@ class DwarfLineToModule: public dwarf2reader::LineInfoHandler {
// end of the address space, we clip it. It's up to our client to
// sort out which lines belong to which functions; we don't add them
// to any particular function in MODULE ourselves.
- DwarfLineToModule(Module *module, vector<Module::Line> *lines)
+ DwarfLineToModule(Module *module, const string& compilation_dir,
+ vector<Module::Line> *lines)
: module_(module),
+ compilation_dir_(compilation_dir),
lines_(lines),
highest_file_number_(-1),
omitted_line_end_(0),
@@ -146,6 +148,10 @@ class DwarfLineToModule: public dwarf2reader::LineInfoHandler {
// client.
Module *module_;
+ // The compilation directory for the current compilation unit whose
+ // lines are being accumulated.
+ string compilation_dir_;
+
// The vector of lines we're accumulating. Owned by our client.
//
// In a Module, as in a breakpad symbol file, lines belong to
diff --git a/src/common/dwarf_line_to_module_unittest.cc b/src/common/dwarf_line_to_module_unittest.cc
index 1e123e97..7c0fcfd3 100644
--- a/src/common/dwarf_line_to_module_unittest.cc
+++ b/src/common/dwarf_line_to_module_unittest.cc
@@ -45,7 +45,7 @@ using google_breakpad::Module;
TEST(SimpleModule, One) {
Module m("name", "os", "architecture", "id");
vector<Module::Line> lines;
- DwarfLineToModule h(&m, &lines);
+ DwarfLineToModule h(&m, "/", &lines);
h.DefineFile("file1", 0x30bf0f27, 0, 0, 0);
h.AddLine(0x6fd126fbf74f2680LL, 0x63c9a14cf556712bLL, 0x30bf0f27,
@@ -54,7 +54,7 @@ TEST(SimpleModule, One) {
vector<Module::File *> files;
m.GetFiles(&files);
EXPECT_EQ(1U, files.size());
- EXPECT_STREQ("file1", files[0]->name.c_str());
+ EXPECT_STREQ("/file1", files[0]->name.c_str());
EXPECT_EQ(1U, lines.size());
EXPECT_EQ(0x6fd126fbf74f2680ULL, lines[0].address);
@@ -66,7 +66,7 @@ TEST(SimpleModule, One) {
TEST(SimpleModule, Many) {
Module m("name", "os", "architecture", "id");
vector<Module::Line> lines;
- DwarfLineToModule h(&m, &lines);
+ DwarfLineToModule h(&m, "/", &lines);
h.DefineDir("directory1", 0x838299ab);
h.DefineDir("directory2", 0xf85de023);
@@ -89,11 +89,11 @@ TEST(SimpleModule, Many) {
vector<Module::File *> files;
m.GetFiles(&files);
ASSERT_EQ(5U, files.size());
- EXPECT_STREQ("directory1/file1", files[0]->name.c_str());
- EXPECT_STREQ("directory1/file2", files[1]->name.c_str());
- EXPECT_STREQ("directory2/file1", files[2]->name.c_str());
- EXPECT_STREQ("directory2/file2", files[3]->name.c_str());
- EXPECT_STREQ("file3", files[4]->name.c_str());
+ EXPECT_STREQ("/directory1/file1", files[0]->name.c_str());
+ EXPECT_STREQ("/directory1/file2", files[1]->name.c_str());
+ EXPECT_STREQ("/directory2/file1", files[2]->name.c_str());
+ EXPECT_STREQ("/directory2/file2", files[3]->name.c_str());
+ EXPECT_STREQ("/file3", files[4]->name.c_str());
ASSERT_EQ(5U, lines.size());
@@ -126,7 +126,7 @@ TEST(SimpleModule, Many) {
TEST(Filenames, Absolute) {
Module m("name", "os", "architecture", "id");
vector<Module::Line> lines;
- DwarfLineToModule h(&m, &lines);
+ DwarfLineToModule h(&m, "/", &lines);
h.DefineDir("directory1", 1);
h.DefineFile("/absolute", 1, 1, 0, 0);
@@ -144,7 +144,7 @@ TEST(Filenames, Absolute) {
TEST(Filenames, Relative) {
Module m("name", "os", "architecture", "id");
vector<Module::Line> lines;
- DwarfLineToModule h(&m, &lines);
+ DwarfLineToModule h(&m, "/", &lines);
h.DefineDir("directory1", 1);
h.DefineFile("relative", 1, 1, 0, 0);
@@ -154,7 +154,7 @@ TEST(Filenames, Relative) {
vector<Module::File *> files;
m.GetFiles(&files);
ASSERT_EQ(1U, files.size());
- EXPECT_STREQ("directory1/relative", files[0]->name.c_str());
+ EXPECT_STREQ("/directory1/relative", files[0]->name.c_str());
ASSERT_EQ(1U, lines.size());
EXPECT_TRUE(lines[0].file == files[0]);
}
@@ -162,20 +162,20 @@ TEST(Filenames, Relative) {
TEST(Filenames, StrangeFile) {
Module m("name", "os", "architecture", "id");
vector<Module::Line> lines;
- DwarfLineToModule h(&m, &lines);
+ DwarfLineToModule h(&m, "/", &lines);
h.DefineDir("directory1", 1);
h.DefineFile("", 1, 1, 0, 0);
h.AddLine(1, 1, 1, 0, 0);
ASSERT_EQ(1U, lines.size());
- EXPECT_STREQ("directory1/", lines[0].file->name.c_str());
+ EXPECT_STREQ("/directory1/", lines[0].file->name.c_str());
}
TEST(Filenames, StrangeDirectory) {
Module m("name", "os", "architecture", "id");
vector<Module::Line> lines;
- DwarfLineToModule h(&m, &lines);
+ DwarfLineToModule h(&m, "/", &lines);
h.DefineDir("", 1);
h.DefineFile("file1", 1, 1, 0, 0);
@@ -188,7 +188,7 @@ TEST(Filenames, StrangeDirectory) {
TEST(Filenames, StrangeDirectoryAndFile) {
Module m("name", "os", "architecture", "id");
vector<Module::Line> lines;
- DwarfLineToModule h(&m, &lines);
+ DwarfLineToModule h(&m, "/", &lines);
h.DefineDir("", 1);
h.DefineFile("", 1, 1, 0, 0);
@@ -198,12 +198,60 @@ TEST(Filenames, StrangeDirectoryAndFile) {
EXPECT_STREQ("/", lines[0].file->name.c_str());
}
+// We should use the compilation directory when encountering a file for
+// directory number zero.
+TEST(Filenames, DirectoryZeroFileIsRelativeToCompilationDir) {
+ Module m("name", "os", "architecture", "id");
+ vector<Module::Line> lines;
+ DwarfLineToModule h(&m, "src/build", &lines);
+
+ h.DefineDir("Dir", 1);
+ h.DefineFile("File", 1, 0, 0, 0);
+
+ h.AddLine(1, 1, 1, 0, 0);
+
+ ASSERT_EQ(1U, lines.size());
+ EXPECT_STREQ("src/build/File", lines[0].file->name.c_str());
+}
+
+// We should treat non-absolute directories as relative to the compilation
+// directory.
+TEST(Filenames, IncludeDirectoryRelativeToDirectoryZero) {
+ Module m("name", "os", "architecture", "id");
+ vector<Module::Line> lines;
+ DwarfLineToModule h(&m, "src/build", &lines);
+
+ h.DefineDir("Dir", 1);
+ h.DefineFile("File", 1, 1, 0, 0);
+
+ h.AddLine(1, 1, 1, 0, 0);
+
+ ASSERT_EQ(1U, lines.size());
+ EXPECT_STREQ("src/build/Dir/File", lines[0].file->name.c_str());
+}
+
+// We should treat absolute directories as absolute, and not relative to
+// the compilation dir.
+TEST(Filenames, IncludeDirectoryAbsolute) {
+ Module m("name", "os", "architecture", "id");
+ vector<Module::Line> lines;
+ DwarfLineToModule h(&m, "src/build", &lines);
+
+ h.DefineDir("/Dir", 1);
+ h.DefineFile("File", 1, 1, 0, 0);
+
+ h.AddLine(1, 1, 1, 0, 0);
+
+ ASSERT_EQ(1U, lines.size());
+ EXPECT_STREQ("/Dir/File", lines[0].file->name.c_str());
+}
+
// We should silently ignore attempts to define directory number zero,
// since that is always the compilation directory.
TEST(ModuleErrors, DirectoryZero) {
Module m("name", "os", "architecture", "id");
vector<Module::Line> lines;
- DwarfLineToModule h(&m, &lines);
+ DwarfLineToModule h(&m, "/", &lines);
h.DefineDir("directory0", 0); // should be ignored
h.DefineFile("relative", 1, 0, 0, 0);
@@ -211,7 +259,7 @@ TEST(ModuleErrors, DirectoryZero) {
h.AddLine(1, 1, 1, 0, 0);
ASSERT_EQ(1U, lines.size());
- EXPECT_STREQ("relative", lines[0].file->name.c_str());
+ EXPECT_STREQ("/relative", lines[0].file->name.c_str());
}
// We should refuse to add lines with bogus file numbers. We should
@@ -219,7 +267,7 @@ TEST(ModuleErrors, DirectoryZero) {
TEST(ModuleErrors, BadFileNumber) {
Module m("name", "os", "architecture", "id");
vector<Module::Line> lines;
- DwarfLineToModule h(&m, &lines);
+ DwarfLineToModule h(&m, "/", &lines);
h.DefineFile("relative", 1, 0, 0, 0);
h.AddLine(1, 1, 2, 0, 0); // bad file number
@@ -233,7 +281,7 @@ TEST(ModuleErrors, BadFileNumber) {
TEST(ModuleErrors, BadDirectoryNumber) {
Module m("name", "os", "architecture", "id");
vector<Module::Line> lines;
- DwarfLineToModule h(&m, &lines);
+ DwarfLineToModule h(&m, "/", &lines);
h.DefineDir("directory1", 1);
h.DefineFile("baddirnumber1", 1, 2, 0, 0); // bad directory number
@@ -248,7 +296,7 @@ TEST(ModuleErrors, BadDirectoryNumber) {
TEST(ModuleErrors, EmptyLine) {
Module m("name", "os", "architecture", "id");
vector<Module::Line> lines;
- DwarfLineToModule h(&m, &lines);
+ DwarfLineToModule h(&m, "/", &lines);
h.DefineFile("filename1", 1, 0, 0, 0);
h.AddLine(1, 0, 1, 0, 0);
@@ -261,7 +309,7 @@ TEST(ModuleErrors, EmptyLine) {
TEST(ModuleErrors, BigLine) {
Module m("name", "os", "architecture", "id");
vector<Module::Line> lines;
- DwarfLineToModule h(&m, &lines);
+ DwarfLineToModule h(&m, "/", &lines);
h.DefineFile("filename1", 1, 0, 0, 0);
h.AddLine(0xffffffffffffffffULL, 2, 1, 0, 0);
@@ -278,7 +326,7 @@ TEST(ModuleErrors, BigLine) {
TEST(Omitted, DroppedThenGood) {
Module m("name", "os", "architecture", "id");
vector<Module::Line> lines;
- DwarfLineToModule h(&m, &lines);
+ DwarfLineToModule h(&m, "/", &lines);
h.DefineFile("filename1", 1, 0, 0, 0);
h.AddLine(0, 10, 1, 83816211, 0); // should be omitted
@@ -291,7 +339,7 @@ TEST(Omitted, DroppedThenGood) {
TEST(Omitted, GoodThenDropped) {
Module m("name", "os", "architecture", "id");
vector<Module::Line> lines;
- DwarfLineToModule h(&m, &lines);
+ DwarfLineToModule h(&m, "/", &lines);
h.DefineFile("filename1", 1, 0, 0, 0);
h.AddLine(0x9dd6a372, 10, 1, 41454594, 0); // should be recorded
@@ -304,7 +352,7 @@ TEST(Omitted, GoodThenDropped) {
TEST(Omitted, Mix1) {
Module m("name", "os", "architecture", "id");
vector<Module::Line> lines;
- DwarfLineToModule h(&m, &lines);
+ DwarfLineToModule h(&m, "/", &lines);
h.DefineFile("filename1", 1, 0, 0, 0);
h.AddLine(0x679ed72f, 10, 1, 58932642, 0); // should be recorded
@@ -325,7 +373,7 @@ TEST(Omitted, Mix1) {
TEST(Omitted, Mix2) {
Module m("name", "os", "architecture", "id");
vector<Module::Line> lines;
- DwarfLineToModule h(&m, &lines);
+ DwarfLineToModule h(&m, "/", &lines);
h.DefineFile("filename1", 1, 0, 0, 0);
h.AddLine(0, 0xf2, 1, 58802211, 0); // should be omitted
diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc
index 4a85ab8f..b739bf71 100644
--- a/src/common/linux/dump_symbols.cc
+++ b/src/common/linux/dump_symbols.cc
@@ -186,18 +186,22 @@ bool LoadStabs(const typename ElfClass::Ehdr* elf_header,
// A line-to-module loader that accepts line number info parsed by
// dwarf2reader::LineInfo and populates a Module and a line vector
// with the results.
-class DumperLineToModule: public DwarfCUToModule::LineToModuleFunctor {
+class DumperLineToModule: public DwarfCUToModule::LineToModuleHandler {
public:
// Create a line-to-module converter using BYTE_READER.
explicit DumperLineToModule(dwarf2reader::ByteReader *byte_reader)
: byte_reader_(byte_reader) { }
- void operator()(const char *program, uint64 length,
- Module *module, std::vector<Module::Line> *lines) {
- DwarfLineToModule handler(module, lines);
+ void StartCompilationUnit(const string& compilation_dir) {
+ compilation_dir_ = compilation_dir;
+ }
+ void ReadProgram(const char *program, uint64 length,
+ Module *module, std::vector<Module::Line> *lines) {
+ DwarfLineToModule handler(module, compilation_dir_, lines);
dwarf2reader::LineInfo parser(program, length, byte_reader_, &handler);
parser.Start();
}
private:
+ string compilation_dir_;
dwarf2reader::ByteReader *byte_reader_;
};
diff --git a/src/common/mac/dump_syms.mm b/src/common/mac/dump_syms.mm
index d79afe26..e26b05ea 100644
--- a/src/common/mac/dump_syms.mm
+++ b/src/common/mac/dump_syms.mm
@@ -227,18 +227,24 @@ string DumpSymbols::Identifier() {
// dwarf2reader::LineInfo and populates a Module and a line vector
// with the results.
class DumpSymbols::DumperLineToModule:
- public DwarfCUToModule::LineToModuleFunctor {
+ public DwarfCUToModule::LineToModuleHandler {
public:
// Create a line-to-module converter using BYTE_READER.
DumperLineToModule(dwarf2reader::ByteReader *byte_reader)
: byte_reader_(byte_reader) { }
- void operator()(const char *program, uint64 length,
- Module *module, vector<Module::Line> *lines) {
- DwarfLineToModule handler(module, lines);
+
+ void StartCompilationUnit(const string& compilation_dir) {
+ compilation_dir_ = compilation_dir;
+ }
+
+ void ReadProgram(const char *program, uint64 length,
+ Module *module, vector<Module::Line> *lines) {
+ DwarfLineToModule handler(module, compilation_dir_, lines);
dwarf2reader::LineInfo parser(program, length, byte_reader_, &handler);
parser.Start();
}
private:
+ string compilation_dir_;
dwarf2reader::ByteReader *byte_reader_; // WEAK
};