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]; };