Merge pull request #95 from haberman/fixseparatedebug
Fixed a few bugs with total file size, and added tests to verify.
diff --git a/src/bloaty.cc b/src/bloaty.cc
index 3d4fd37..fa3ba4f 100644
--- a/src/bloaty.cc
+++ b/src/bloaty.cc
@@ -372,6 +372,8 @@
}
}
+ int64_t file_total() const { return file_total_; }
+
private:
BLOATY_DISALLOW_COPY_AND_ASSIGN(Rollup);
@@ -1134,6 +1136,8 @@
pair.first->file_map.AddRangeWithTranslation(fileoff, filesize, label,
translator_->file_map,
&pair.first->vm_map);
+ } else {
+ pair.first->file_map.AddRange(fileoff, filesize, label);
}
}
}
@@ -1513,10 +1517,6 @@
sink_ptrs.push_back(sinks.back().get());
}
- // Ensure all parts of the VM/file-space are covered. If all data sources had
- // 100% coverage, this wouldn't be necessary.
- maps.base_map()->file_map.AddRange(0, file->file_data().data().size(),
- "[None]");
std::string build_id = file->GetBuildId();
if (!build_id.empty()) {
auto iter = debug_files_.find(build_id);
@@ -1525,9 +1525,16 @@
*out_build_id = build_id;
}
}
- file->ProcessFile(sink_ptrs);
+ int64_t filesize_before = rollup->file_total();
+ file->ProcessFile(sink_ptrs);
maps.ComputeRollup(filename, filename_position_, rollup);
+
+ // The ObjectFile implementation must guarantee this.
+ int64_t filesize = rollup->file_total() - filesize_before;
+ (void)filesize;
+ assert(filesize == file->file_data().data().size());
+
if (verbose_level > 0) {
fprintf(stderr, "FILE MAP:\n");
maps.PrintFileMaps(filename, filename_position_);
diff --git a/src/elf.cc b/src/elf.cc
index 4a575a5..08598d3 100644
--- a/src/elf.cc
+++ b/src/elf.cc
@@ -708,24 +708,6 @@
}
template <class Func>
-void OnElfFile(const ElfFile& elf, string_view filename,
- unsigned long index_base, RangeSink* sink, Func func) {
- func(elf, filename, index_base);
-
- // Add these *after* running the user callback. That way if there is
- // overlap, the user's annotations will take precedence.
- MaybeAddFileRange(sink, "[ELF Headers]", elf.header_region());
- MaybeAddFileRange(sink, "[ELF Headers]", elf.section_headers());
- MaybeAddFileRange(sink, "[ELF Headers]", elf.segment_headers());
-
- // Any sections of the file not covered by any segments/sections/symbols/etc.
- if (sink && (sink->data_source() == DataSource::kSegments ||
- sink->data_source() == DataSource::kSections)) {
- sink->AddFileRange("[Unmapped]", elf.entire_file());
- }
-}
-
-template <class Func>
bool ForEachElf(const InputFile& file, RangeSink* sink, Func func) {
ArFile ar_file(file.data());
unsigned long index_base = 0;
@@ -742,7 +724,7 @@
case ArFile::MemberFile::kNormal: {
ElfFile elf(member.contents);
if (elf.IsOpen()) {
- OnElfFile(elf, member.filename, index_base, sink, func);
+ func(elf, member.filename, index_base);
index_base += elf.section_count();
} else {
MaybeAddFileRange(sink, "[AR Non-ELF Member File]",
@@ -766,20 +748,24 @@
return false;
}
- OnElfFile(elf, file.filename(), index_base, sink, func);
+ func(elf, file.filename(), index_base);
}
return true;
}
+void AddELFFallback(RangeSink* sink) {
+ ForEachElf(sink->input_file(), sink,
+ [sink](const ElfFile& elf, string_view /*filename*/,
+ uint32_t /*index_base*/) {
+ sink->AddFileRange("[ELF Headers]", elf.header_region());
+ sink->AddFileRange("[ELF Headers]", elf.section_headers());
+ sink->AddFileRange("[ELF Headers]", elf.segment_headers());
-// There are several programs that offer useful information about
-// binaries:
-//
-// - objdump: display object file headers and contents (including disassembly)
-// - readelf: more ELF-specific objdump (no disassembly though)
-// - nm: display symbols
-// - size: display binary size
+ });
+ // The last-line fallback to make sure we cover the entire file.
+ sink->AddFileRange("[Unmapped]", sink->input_file().data());
+}
// For object files, addresses are relative to the section they live in, which
// is indicated by ndx. We split this into:
@@ -1127,6 +1113,7 @@
default:
THROW("unknown data source");
}
+ AddELFFallback(sink);
}
}
diff --git a/src/macho.cc b/src/macho.cc
index ac5dd1e..8c380c4 100644
--- a/src/macho.cc
+++ b/src/macho.cc
@@ -377,6 +377,10 @@
}
}
+static void AddMachOFallback(RangeSink* sink) {
+ sink->AddFileRange("[Unmapped]", sink->input_file().data());
+}
+
class MachOObjectFile : public ObjectFile {
public:
MachOObjectFile(std::unique_ptr<InputFile> file_data)
@@ -404,6 +408,7 @@
default:
THROW("Mach-O doesn't support this data source");
}
+ AddMachOFallback(sink);
}
}
diff --git a/tests/bloaty_test.cc b/tests/bloaty_test.cc
index e7f370a..006c03c 100644
--- a/tests/bloaty_test.cc
+++ b/tests/bloaty_test.cc
@@ -254,3 +254,8 @@
std::make_tuple("foo_y", 4, 0)
});
}
+
+TEST_F(BloatyTest, SeparateDebug) {
+ RunBloaty({"bloaty", "--debug-file=05-binary.bin", "07-binary-stripped.bin",
+ "-d", "symbols"});
+}
diff --git a/tests/test.h b/tests/test.h
index dfc5231..0e68579 100644
--- a/tests/test.h
+++ b/tests/test.h
@@ -128,6 +128,17 @@
void CheckConsistency(const bloaty::Options& options) {
ASSERT_EQ(options.base_filename_size() > 0, output_->diff_mode());
+
+ if (!output_->diff_mode()) {
+ size_t total_input_size = 0;
+ for (const auto& filename : options.filename()) {
+ uint64_t size;
+ ASSERT_TRUE(GetFileSize(filename, &size));
+ total_input_size += size;
+ }
+ ASSERT_EQ(top_row_->filesize, total_input_size);
+ }
+
int rows = 0;
CheckConsistencyForRow(*top_row_, true, output_->diff_mode(), &rows);
CheckCSVConsistency(rows);
diff --git a/tests/testdata/linux-x86/07-binary-stripped.bin b/tests/testdata/linux-x86/07-binary-stripped.bin
new file mode 100644
index 0000000..9bcbe46
--- /dev/null
+++ b/tests/testdata/linux-x86/07-binary-stripped.bin
Binary files differ
diff --git a/tests/testdata/linux-x86_64/07-binary-stripped.bin b/tests/testdata/linux-x86_64/07-binary-stripped.bin
new file mode 100644
index 0000000..0035670
--- /dev/null
+++ b/tests/testdata/linux-x86_64/07-binary-stripped.bin
Binary files differ
diff --git a/tests/testdata/make_test_files.sh b/tests/testdata/make_test_files.sh
index 85ea950..bb75402 100755
--- a/tests/testdata/make_test_files.sh
+++ b/tests/testdata/make_test_files.sh
@@ -114,3 +114,7 @@
"
make_ar "06-diff.a" "foo2.o" "bar.o" "a_filename_longer_than_sixteen_chars.o"
+
+cp "05-binary.bin" "07-binary-stripped.bin"
+strip "07-binary-stripped.bin"
+publish "07-binary-stripped.bin"