Fix lsan errors
These leaks are all intentional, so this fixes them by deallocating them
only when asan is enabled.
To show them:
build/gen.py -d --use-asan
ninja -C out
out/gn_unittests
Change-Id: I937a4c33bfc6178cb42a61fc43e4da10d6668cc2
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/19000
Reviewed-by: David Turner <digit@google.com>
Commit-Queue: Andrew Grieve <agrieve@google.com>
diff --git a/build/gen.py b/build/gen.py
index 5d07459..533df58 100755
--- a/build/gen.py
+++ b/build/gen.py
@@ -478,6 +478,7 @@
if options.use_asan:
cflags.append('-fsanitize=address')
+ cflags.append('-DASAN_ENABLED')
ldflags.append('-fsanitize=address')
if options.use_ubsan:
diff --git a/src/gn/command_gen.cc b/src/gn/command_gen.cc
index 3edee43..652c3e3 100644
--- a/src/gn/command_gen.cc
+++ b/src/gn/command_gen.cc
@@ -918,7 +918,9 @@
// Just like the build graph, leak the resolved data to avoid expensive
// process teardown here too.
+#ifndef ASAN_ENABLED
write_info.LeakOnPurpose();
+#endif
return 0;
}
diff --git a/src/gn/string_atom.cc b/src/gn/string_atom.cc
index 5c3f73f..36f912f 100644
--- a/src/gn/string_atom.cc
+++ b/src/gn/string_atom.cc
@@ -114,12 +114,23 @@
//
// This allows the StringAtom() default initializer to use the same
// address directly, avoiding a table lookup.
- //
size_t hash = set_.Hash("");
auto* node = set_.Lookup(hash, "");
set_.Insert(node, hash, &kEmptyString);
}
+#ifdef ASAN_ENABLED
+ ~StringAtomSet() {
+ if (!slabs_.empty()) {
+ Slab* last_slab = slabs_.back();
+ for (Slab* slab : slabs_) {
+ slab->destroy(slab == last_slab ? slab_index_ : kStringsPerSlab);
+ delete slab;
+ }
+ }
+ }
+#endif
+
// Find the unique constant string pointer for |key|.
const std::string* find(std::string_view key) {
std::lock_guard<std::mutex> lock(mutex_);
@@ -168,6 +179,12 @@
return result;
}
+ void destroy(size_t max_index) {
+ for (size_t i = 0; i < max_index; ++i) {
+ items_[i].str.~basic_string();
+ }
+ }
+
private:
StringStorage items_[kStringsPerSlab];
};