aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGennadiy Civil <gennadiycivil@users.noreply.github.com>2018-08-16 13:34:03 -0400
committerGitHub <noreply@github.com>2018-08-16 13:34:03 -0400
commit8b34930c62c21c281bfd756b05a471cca2312aca (patch)
tree7b3b8b24fd173a16b88036ef1171c135dc298908
parent490554aa0f3618e1e5dd217f11fe0c3f188ed615 (diff)
parentc38f4b9f2c542d16611b59e37b5e4d2ec0c8f924 (diff)
downloadgoogletest-8b34930c62c21c281bfd756b05a471cca2312aca.tar.gz
googletest-8b34930c62c21c281bfd756b05a471cca2312aca.tar.bz2
googletest-8b34930c62c21c281bfd756b05a471cca2312aca.zip
Merge pull request #1142 from scottslacksmith/master
Fix/silence false positive memory leaks reported by Microsoft's debug CRT
-rw-r--r--googletest/src/gtest-port.cc46
1 files changed, 44 insertions, 2 deletions
diff --git a/googletest/src/gtest-port.cc b/googletest/src/gtest-port.cc
index 13901e3f..fecb5d11 100644
--- a/googletest/src/gtest-port.cc
+++ b/googletest/src/gtest-port.cc
@@ -294,6 +294,43 @@ void Mutex::AssertHeld() {
<< "The current thread is not holding the mutex @" << this;
}
+namespace {
+
+// Use the RAII idiom to flag mem allocs that are intentionally never
+// deallocated. The motivation is to silence the false positive mem leaks
+// that are reported by the debug version of MS's CRT which can only detect
+// if an alloc is missing a matching deallocation.
+// Example:
+// MemoryIsNotDeallocated memory_is_not_deallocated;
+// critical_section_ = new CRITICAL_SECTION;
+//
+class MemoryIsNotDeallocated
+{
+ public:
+ MemoryIsNotDeallocated() : old_crtdbg_flag_(0) {
+#ifdef _MSC_VER
+ old_crtdbg_flag_ = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
+ // Set heap allocation block type to _IGNORE_BLOCK so that MS debug CRT
+ // doesn't report mem leak if there's no matching deallocation.
+ _CrtSetDbgFlag(old_crtdbg_flag_ & ~_CRTDBG_ALLOC_MEM_DF);
+#endif // _MSC_VER
+ }
+
+ ~MemoryIsNotDeallocated() {
+#ifdef _MSC_VER
+ // Restore the original _CRTDBG_ALLOC_MEM_DF flag
+ _CrtSetDbgFlag(old_crtdbg_flag_);
+#endif // _MSC_VER
+ }
+
+ private:
+ int old_crtdbg_flag_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(MemoryIsNotDeallocated);
+};
+
+} // namespace
+
// Initializes owner_thread_id_ and critical_section_ in static mutexes.
void Mutex::ThreadSafeLazyInit() {
// Dynamic mutexes are initialized in the constructor.
@@ -304,7 +341,11 @@ void Mutex::ThreadSafeLazyInit() {
// If critical_section_init_phase_ was 0 before the exchange, we
// are the first to test it and need to perform the initialization.
owner_thread_id_ = 0;
- critical_section_ = new CRITICAL_SECTION;
+ {
+ // Use RAII to flag that following mem alloc is never deallocated.
+ MemoryIsNotDeallocated memory_is_not_deallocated;
+ critical_section_ = new CRITICAL_SECTION;
+ }
::InitializeCriticalSection(critical_section_);
// Updates the critical_section_init_phase_ to 2 to signal
// initialization complete.
@@ -546,7 +587,8 @@ class ThreadLocalRegistryImpl {
// Returns map of thread local instances.
static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() {
mutex_.AssertHeld();
- static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals;
+ MemoryIsNotDeallocated memory_is_not_deallocated;
+ static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals();
return map;
}