Skip to content

Commit

Permalink
Add an option to exclude based on source names
Browse files Browse the repository at this point in the history
  • Loading branch information
learn-more committed May 3, 2021
1 parent be6f782 commit 3f2ed6d
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 14 deletions.
56 changes: 43 additions & 13 deletions src/bloaty.cc
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,9 @@ class Rollup {
CreateRows(row, base, options, true);
}

void SetFilterRegex(const ReImpl* regex) {
filter_regex_ = regex;
void SetFilterRegex(const ReImpl* regex_include, const ReImpl* regex_exclude) {
filter_regex_include_ = regex_include;
filter_regex_exclude_ = regex_exclude;
}

// Subtract the values in "other" from this.
Expand Down Expand Up @@ -379,7 +380,8 @@ class Rollup {
int64_t filtered_vm_total_ = 0;
int64_t filtered_file_total_ = 0;

const ReImpl* filter_regex_ = nullptr;
const ReImpl* filter_regex_include_ = nullptr;
const ReImpl* filter_regex_exclude_ = nullptr;

// Putting Rollup by value seems to work on some compilers/libs but not
// others.
Expand All @@ -398,20 +400,33 @@ class Rollup {
// If there are more entries names[i+1, i+2, etc] add them to sub-rollups.
void AddInternal(const std::vector<std::string>& names, size_t i,
uint64_t size, bool is_vmsize) {
if (filter_regex_ != nullptr) {
if (filter_regex_include_ != nullptr || filter_regex_exclude_ != nullptr) {
// filter_regex_ is only set in the root rollup, which checks the full
// label hierarchy for a match to determine whether a region should be
// considered.
bool any_matched = false;
bool exclude = false;
if (filter_regex_include_ != nullptr) {
bool any_matched = false;

for (const auto& name : names) {
if (ReImpl::PartialMatch(name, *filter_regex_include_)) {
any_matched = true;
break;
}
}
exclude = !any_matched;
}

for (const auto& name : names) {
if (ReImpl::PartialMatch(name, *filter_regex_)) {
any_matched = true;
break;
if (!exclude && filter_regex_exclude_ != nullptr) {
for (const auto& name : names) {
if (ReImpl::PartialMatch(name, *filter_regex_exclude_)) {
exclude = true;
break;
}
}
}

if (!any_matched) {
if (exclude) {
// Ignore this region in the rollup and don't visit sub-rollups.
if (is_vmsize) {
CheckedAdd(&filtered_vm_total_, size);
Expand Down Expand Up @@ -1789,13 +1804,17 @@ void Bloaty::ScanAndRollupFiles(
std::vector<std::thread> threads(num_threads);
ThreadSafeIterIndex index(filenames.size());

std::unique_ptr<ReImpl> regex = nullptr;
std::unique_ptr<ReImpl> regex_include = nullptr;
std::unique_ptr<ReImpl> regex_exclude = nullptr;
if (options_.has_source_filter()) {
regex = absl::make_unique<ReImpl>(options_.source_filter());
regex_include = absl::make_unique<ReImpl>(options_.source_filter());
}
if (options_.has_not_source_filter()) {
regex_exclude = absl::make_unique<ReImpl>(options_.not_source_filter());
}

for (int i = 0; i < num_threads; i++) {
thread_data[i].rollup.SetFilterRegex(regex.get());
thread_data[i].rollup.SetFilterRegex(regex_include.get(), regex_exclude.get());

threads[i] = std::thread([this, &index, &filenames](PerThreadData* data) {
try {
Expand Down Expand Up @@ -1940,6 +1959,8 @@ USAGE: bloaty [OPTION]... FILE... [-- BASE_FILE...]
--list-sources Show a list of available sources and exit.
--source-filter=PATTERN
Only show keys with names matching this pattern.
--not-source-filter=PATTERN
Exclude keys with names matching this pattern.
Options for debugging Bloaty:
Expand Down Expand Up @@ -2139,6 +2160,8 @@ bool DoParseOptions(bool skip_unknown, int* argc, char** argv[],
}
} else if (args.TryParseOption("--source-filter", &option)) {
options->set_source_filter(std::string(option));
} else if (args.TryParseOption("--not-source-filter", &option)) {
options->set_not_source_filter(std::string(option));
} else if (args.TryParseFlag("-v")) {
options->set_verbose_level(1);
} else if (args.TryParseFlag("-vv")) {
Expand Down Expand Up @@ -2247,6 +2270,13 @@ void BloatyDoMain(const Options& options, const InputFileFactory& file_factory,
}
}

if (options.has_not_source_filter()) {
ReImpl re(options.not_source_filter());
if (!re.ok()) {
THROW("invalid regex for not_source_filter");
}
}

verbose_level = options.verbose_level();

if (options.data_source_size() > 0) {
Expand Down
3 changes: 3 additions & 0 deletions src/bloaty.proto
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ message Options {

// Regex with which to filter names in the data sources.
optional string source_filter = 13;

// Regex with which to exclude names in the data sources.
optional string not_source_filter = 14;
}

// A custom data source allows users to create their own label space by
Expand Down
6 changes: 6 additions & 0 deletions tests/bloaty_test_pe.cc
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,21 @@ TEST_P(BloatyOutputTest, CheckOutput) {
}

static BloatyTestEntry tests[] = {
// Normal tests on MSVC 15 (2017)
{ "MSVCR15DLL", {}, "msvc-15.0-foo-bar.dll", "msvc-15.0-foo-bar.dll.txt" },
{ "MSVCR15DLLSEG", {"-d", "segments"}, "msvc-15.0-foo-bar.dll", "msvc-15.0-foo-bar.dll.seg.txt" },
{ "MSVC15EXE", {}, "msvc-15.0-foo-bar-main-cv.bin", "msvc-15.0-foo-bar-main-cv.bin.txt" },
{ "MSVC15EXESEG", {"-d", "segments"}, "msvc-15.0-foo-bar-main-cv.bin", "msvc-15.0-foo-bar-main-cv.bin.seg.txt" },

// Normal tests on MSVC 16 (2019)
{ "MSVCR16DLL", {}, "msvc-16.0-foo-bar.dll", "msvc-16.0-foo-bar.dll.txt" },
{ "MSVCR16DLLSEG", {"-d", "segments"}, "msvc-16.0-foo-bar.dll", "msvc-16.0-foo-bar.dll.seg.txt" },
{ "MSVC16EXE", {}, "msvc-16.0-foo-bar-main-cv.bin", "msvc-16.0-foo-bar-main-cv.bin.txt" },
{ "MSVC16EXESEG", {"-d", "segments"}, "msvc-16.0-foo-bar-main-cv.bin", "msvc-16.0-foo-bar-main-cv.bin.seg.txt" },

// Filter tests
{ "FILTERINCLUDE", {"--source-filter", "text"}, "msvc-15.0-foo-bar.dll", "filter_include.txt" },
{ "FILTEREXCLUDE", {"--not-source-filter", "text"}, "msvc-15.0-foo-bar.dll", "filter_exclude.txt" },
};

INSTANTIATE_TEST_SUITE_P(BloatyTest,
Expand Down
2 changes: 1 addition & 1 deletion tests/test.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ class BloatyTest : public ::testing::Test {
void CheckConsistency(const bloaty::Options& options) {
ASSERT_EQ(options.base_filename_size() > 0, output_->diff_mode());

if (!output_->diff_mode()) {
if (!output_->diff_mode() && !options.has_source_filter() && !options.has_not_source_filter()) {
size_t total_input_size = 0;
for (const auto& filename : options.filename()) {
uint64_t size;
Expand Down
7 changes: 7 additions & 0 deletions tests/testdata/PE/x64/filter_exclude.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
sections vmsize filesize
.rdata 2520 2560
.data 1592 512
[PE Headers] 696 696
.pdata 408 512
.reloc 24 512
[Unmapped] 0 328
2 changes: 2 additions & 0 deletions tests/testdata/PE/x64/filter_include.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
sections vmsize filesize
.text 3587 4096
6 changes: 6 additions & 0 deletions tests/testdata/PE/x86/filter_exclude.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
sections vmsize filesize
.rdata 1772 2048
.data 908 512
[PE Headers] 656 656
.reloc 296 512
[Unmapped] 0 368
2 changes: 2 additions & 0 deletions tests/testdata/PE/x86/filter_include.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
sections vmsize filesize
.text 3172 3584

0 comments on commit 3f2ed6d

Please sign in to comment.