Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ThreadIdToThreadLocals objects leaked. #624

Closed
FrankStain opened this issue Nov 5, 2015 · 8 comments
Closed

ThreadIdToThreadLocals objects leaked. #624

FrankStain opened this issue Nov 5, 2015 · 8 comments

Comments

@FrankStain
Copy link

Hi there.
https://github.com/google/googletest/blob/master/googletest/src/gtest-port.cc#L516
Here some object is created. But it's never deleted. Memory leaks detection pointing me on this allocation and on void Mutex::ThreadSafeLazyInit() as well.

Can you fix this leaks so leaks detection tool will stop pointing me on it?

Leaks of ThreadIdToThreadLocals can be fixed here:
https://github.com/google/googletest/blob/master/googletest/src/gtest-port.cc#L408
Currently i fix it via counting of total elements that remains inside of thread_local_values and deleting it when thread_local_values becomes empty. But i don't satisfied with this fix as it maybe break some feature and i actually don't clearly understand this code.

@FrankStain
Copy link
Author

UPD:

Hre is detailed leaks report.

d:\th\minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp (450): App!heap_alloc_dbg + 0x18 bytes
d:\th\minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp (492): App!_malloc_dbg
d:\th\minkernel\crts\ucrt\src\appcrt\heap\malloc.cpp (22): App!malloc
f:\dd\vctools\crt\vcstartup\src\heap\new_scalar.cpp (19): App!operator new + 0xA bytes

d:\dev\googletest\googletest\src\gtest-port.cc (516): App!testing::internal::ThreadLocalRegistryImpl::GetThreadLocalsMapLocked + 0x44 bytes
d:\dev\googletest\googletest\src\gtest-port.cc (416): App!testing::internal::ThreadLocalRegistryImpl::OnThreadLocalDestroyed + 0x5 bytes
d:\dev\googletest\googletest\src\gtest-port.cc (538): App!testing::internal::ThreadLocalRegistry::OnThreadLocalDestroyed
d:\dev\googletest\googletest\include\gtest\internal\gtest-port.h (1851): App!testing::internal::ThreadLocal<std::vector<testing::internal::TraceInfo,std::allocator<testing::internal::TraceInfo> > >::~ThreadLocal<std::vector<testing::internal::TraceInfo,std::allocator<testing::internal::TraceInfo> > > + 0x2B bytes
d:\dev\googletest\googletest\src\gtest.cc (4363): App!testing::internal::UnitTestImpl::~UnitTestImpl + 0x13 bytes
0x00000000D44792D7 (File and line number not available): App!testing::internal::UnitTestImpl::`scalar deleting destructor' + 0x17 bytes
d:\dev\googletest\googletest\src\gtest.cc (4303): App!testing::UnitTest::~UnitTest + 0x34 bytes
0x00000000D46FBDE0 (File and line number not available): App!`testing::UnitTest::GetInstance'::`2'::`dynamic atexit destructor for 'instance'' + 0x10 bytes

d:\th\minkernel\crts\ucrt\src\appcrt\startup\onexit.cpp (198): App!<lambda_e971338317bfa523bb8920b43d823727>::operator()
d:\th\minkernel\crts\ucrt\devdiv\vcruntime\inc\internal_shared.h (199): App!__crt_seh_guarded_call<int>::operator()<<lambda_d22e02de4d14401f49897516b29a2b7c>,<lambda_e971338317bfa523bb8920b43d823727> & __ptr64,<lambda_b0b8599c9027f5b14541fbbd6863d1f1> > + 0xA bytes
d:\th\minkernel\crts\ucrt\inc\corecrt_internal.h (882): App!__acrt_lock_and_call<<lambda_e971338317bfa523bb8920b43d823727> >
d:\th\minkernel\crts\ucrt\src\appcrt\startup\onexit.cpp (222): App!_execute_onexit_table
d:\th\minkernel\crts\ucrt\src\appcrt\startup\exit.cpp (211): App!common_exit + 0xC bytes
d:\th\minkernel\crts\ucrt\src\appcrt\startup\exit.cpp (283): App!exit
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (275): App!__scrt_common_main_seh
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (309): App!__scrt_common_main
f:\dd\vctools\crt\vcstartup\src\startup\exe_main.cpp (17): App!mainCRTStartup
0x0000000089F513D2 (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0x22 bytes
0x000000008BCA5454 (File and line number not available): ntdll.dll!RtlUserThreadStart + 0x34 bytes
d:\th\minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp (359): App!heap_alloc_dbg_internal + 0x14 bytes
d:\th\minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp (450): App!heap_alloc_dbg + 0x18 bytes
d:\th\minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp (492): App!_malloc_dbg
d:\th\minkernel\crts\ucrt\src\appcrt\heap\malloc.cpp (22): App!malloc
f:\dd\vctools\crt\vcstartup\src\heap\new_scalar.cpp (19): App!operator new + 0xA bytes

d:\dev\googletest\googletest\src\gtest-port.cc (274): App!testing::internal::Mutex::ThreadSafeLazyInit + 0xA bytes
d:\dev\googletest\googletest\src\gtest-port.cc (243): App!testing::internal::Mutex::Lock
d:\dev\googletest\googletest\include\gtest\internal\gtest-port.h (1714): App!testing::internal::GTestMutexLock::GTestMutexLock + 0x1A bytes
d:\dev\googletest\googletest\src\gtest-port.cc (414): App!testing::internal::ThreadLocalRegistryImpl::OnThreadLocalDestroyed + 0x11 bytes
d:\dev\googletest\googletest\src\gtest-port.cc (538): App!testing::internal::ThreadLocalRegistry::OnThreadLocalDestroyed
d:\dev\googletest\googletest\include\gtest\internal\gtest-port.h (1851): App!testing::internal::ThreadLocal<std::vector<testing::internal::TraceInfo,std::allocator<testing::internal::TraceInfo> > >::~ThreadLocal<std::vector<testing::internal::TraceInfo,std::allocator<testing::internal::TraceInfo> > > + 0x2B bytes
d:\dev\googletest\googletest\src\gtest.cc (4363): App!testing::internal::UnitTestImpl::~UnitTestImpl + 0x13 bytes
0x00000000D44792D7 (File and line number not available): App!testing::internal::UnitTestImpl::`scalar deleting destructor' + 0x17 bytes
d:\dev\googletest\googletest\src\gtest.cc (4303): App!testing::UnitTest::~UnitTest + 0x34 bytes
0x00000000D46FBDE0 (File and line number not available): App!`testing::UnitTest::GetInstance'::`2'::`dynamic atexit destructor for 'instance'' + 0x10 bytes

d:\th\minkernel\crts\ucrt\src\appcrt\startup\onexit.cpp (198): App!<lambda_e971338317bfa523bb8920b43d823727>::operator()
d:\th\minkernel\crts\ucrt\devdiv\vcruntime\inc\internal_shared.h (199): App!__crt_seh_guarded_call<int>::operator()<<lambda_d22e02de4d14401f49897516b29a2b7c>,<lambda_e971338317bfa523bb8920b43d823727> & __ptr64,<lambda_b0b8599c9027f5b14541fbbd6863d1f1> > + 0xA bytes
d:\th\minkernel\crts\ucrt\inc\corecrt_internal.h (882): App!__acrt_lock_and_call<<lambda_e971338317bfa523bb8920b43d823727> >
d:\th\minkernel\crts\ucrt\src\appcrt\startup\onexit.cpp (222): App!_execute_onexit_table
d:\th\minkernel\crts\ucrt\src\appcrt\startup\exit.cpp (211): App!common_exit + 0xC bytes
d:\th\minkernel\crts\ucrt\src\appcrt\startup\exit.cpp (283): App!exit
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (275): App!__scrt_common_main_seh
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (309): App!__scrt_common_main
f:\dd\vctools\crt\vcstartup\src\startup\exe_main.cpp (17): App!mainCRTStartup
0x0000000089F513D2 (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0x22 bytes
0x000000008BCA5454 (File and line number not available): ntdll.dll!RtlUserThreadStart + 0x34 bytes

@BillyDonahue
Copy link
Contributor

When you have some idea what 'new' expression is being leaked, please
follow up.
L516 is a closing brace.

What memory leak detection are you using?

I just can't tell what this complaint is about.

On Sun, Dec 13, 2015 at 4:34 AM, Franken notifications@github.com wrote:

UPD:

Hre is detailed leaks report.

d:\th\minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp (450): App!heap_alloc_dbg + 0x18 bytes
d:\th\minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp (492): App!_malloc_dbg
d:\th\minkernel\crts\ucrt\src\appcrt\heap\malloc.cpp (22): App!malloc
f:\dd\vctools\crt\vcstartup\src\heap\new_scalar.cpp (19): App!operator new + 0xA bytes

d:\dev\googletest\googletest\src\gtest-port.cc (516): App!testing::internal::ThreadLocalRegistryImpl::GetThreadLocalsMapLocked + 0x44 bytes
d:\dev\googletest\googletest\src\gtest-port.cc (416): App!testing::internal::ThreadLocalRegistryImpl::OnThreadLocalDestroyed + 0x5 bytes
d:\dev\googletest\googletest\src\gtest-port.cc (538): App!testing::internal::ThreadLocalRegistry::OnThreadLocalDestroyed
d:\dev\googletest\googletest\include\gtest\internal\gtest-port.h (1851): App!testing::internal::ThreadLocalstd::vector<testing::internal::TraceInfo,std::allocator<testing::internal::TraceInfo > >::~ThreadLocalstd::vector<testing::internal::TraceInfo,std::allocator<testing::internal::TraceInfo > > + 0x2B bytes
d:\dev\googletest\googletest\src\gtest.cc (4363): App!testing::internal::UnitTestImpl::~UnitTestImpl + 0x13 bytes
0x00000000D44792D7 (File and line number not available): App!testing::internal::UnitTestImpl::scalar deleting destructor' + 0x17 bytes d:\dev\googletest\googletest\src\gtest.cc (4303): App!testing::UnitTest::~UnitTest + 0x34 bytes 0x00000000D46FBDE0 (File and line number not available): App!testing::UnitTest::GetInstance'::2'::dynamic atexit destructor for 'instance'' + 0x10 bytes

d:\th\minkernel\crts\ucrt\src\appcrt\startup\onexit.cpp (198): App!<lambda_e971338317bfa523bb8920b43d823727>::operator()
d:\th\minkernel\crts\ucrt\devdiv\vcruntime\inc\internal_shared.h (199): App!__crt_seh_guarded_call::operator()<<lambda_d22e02de4d14401f49897516b29a2b7c>,<lambda_e971338317bfa523bb8920b43d823727> & __ptr64,<lambda_b0b8599c9027f5b14541fbbd6863d1f1> > + 0xA bytes
d:\th\minkernel\crts\ucrt\inc\corecrt_internal.h (882): App!__acrt_lock_and_call<<lambda_e971338317bfa523bb8920b43d823727> >
d:\th\minkernel\crts\ucrt\src\appcrt\startup\onexit.cpp (222): App!_execute_onexit_table
d:\th\minkernel\crts\ucrt\src\appcrt\startup\exit.cpp (211): App!common_exit + 0xC bytes
d:\th\minkernel\crts\ucrt\src\appcrt\startup\exit.cpp (283): App!exit
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (275): App!__scrt_common_main_seh
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (309): App!__scrt_common_main
f:\dd\vctools\crt\vcstartup\src\startup\exe_main.cpp (17): App!mainCRTStartup
0x0000000089F513D2 (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0x22 bytes
0x000000008BCA5454 (File and line number not available): ntdll.dll!RtlUserThreadStart + 0x34 bytes

d:\th\minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp (359): App!heap_alloc_dbg_internal + 0x14 bytes
d:\th\minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp (450): App!heap_alloc_dbg + 0x18 bytes
d:\th\minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp (492): App!_malloc_dbg
d:\th\minkernel\crts\ucrt\src\appcrt\heap\malloc.cpp (22): App!malloc
f:\dd\vctools\crt\vcstartup\src\heap\new_scalar.cpp (19): App!operator new + 0xA bytes

d:\dev\googletest\googletest\src\gtest-port.cc (274): App!testing::internal::Mutex::ThreadSafeLazyInit + 0xA bytes
d:\dev\googletest\googletest\src\gtest-port.cc (243): App!testing::internal::Mutex::Lock
d:\dev\googletest\googletest\include\gtest\internal\gtest-port.h (1714): App!testing::internal::GTestMutexLock::GTestMutexLock + 0x1A bytes
d:\dev\googletest\googletest\src\gtest-port.cc (414): App!testing::internal::ThreadLocalRegistryImpl::OnThreadLocalDestroyed + 0x11 bytes
d:\dev\googletest\googletest\src\gtest-port.cc (538): App!testing::internal::ThreadLocalRegistry::OnThreadLocalDestroyed
d:\dev\googletest\googletest\include\gtest\internal\gtest-port.h (1851): App!testing::internal::ThreadLocalstd::vector<testing::internal::TraceInfo,std::allocator<testing::internal::TraceInfo > >::~ThreadLocalstd::vector<testing::internal::TraceInfo,std::allocator<testing::internal::TraceInfo > > + 0x2B bytes
d:\dev\googletest\googletest\src\gtest.cc (4363): App!testing::internal::UnitTestImpl::~UnitTestImpl + 0x13 bytes
0x00000000D44792D7 (File and line number not available): App!testing::internal::UnitTestImpl::scalar deleting destructor' + 0x17 bytes d:\dev\googletest\googletest\src\gtest.cc (4303): App!testing::UnitTest::~UnitTest + 0x34 bytes 0x00000000D46FBDE0 (File and line number not available): App!testing::UnitTest::GetInstance'::2'::dynamic atexit destructor for 'instance'' + 0x10 bytes

d:\th\minkernel\crts\ucrt\src\appcrt\startup\onexit.cpp (198): App!<lambda_e971338317bfa523bb8920b43d823727>::operator()
d:\th\minkernel\crts\ucrt\devdiv\vcruntime\inc\internal_shared.h (199): App!__crt_seh_guarded_call::operator()<<lambda_d22e02de4d14401f49897516b29a2b7c>,<lambda_e971338317bfa523bb8920b43d823727> & __ptr64,<lambda_b0b8599c9027f5b14541fbbd6863d1f1> > + 0xA bytes
d:\th\minkernel\crts\ucrt\inc\corecrt_internal.h (882): App!__acrt_lock_and_call<<lambda_e971338317bfa523bb8920b43d823727> >
d:\th\minkernel\crts\ucrt\src\appcrt\startup\onexit.cpp (222): App!_execute_onexit_table
d:\th\minkernel\crts\ucrt\src\appcrt\startup\exit.cpp (211): App!common_exit + 0xC bytes
d:\th\minkernel\crts\ucrt\src\appcrt\startup\exit.cpp (283): App!exit
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (275): App!__scrt_common_main_seh
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (309): App!__scrt_common_main
f:\dd\vctools\crt\vcstartup\src\startup\exe_main.cpp (17): App!mainCRTStartup
0x0000000089F513D2 (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0x22 bytes
0x000000008BCA5454 (File and line number not available): ntdll.dll!RtlUserThreadStart + 0x34 bytes


Reply to this email directly or view it on GitHub
#624 (comment).

@FrankStain
Copy link
Author

My main development flows using MS Visual Studio. My environment configured to use any of CRT leaks detection or VLD (Visual Leak Detector) tools. Both of them nagging me every time on same lines in code.

Seems i use old code. I had pulled it at september.
I'll update my local repo, but i definetly sure leaks not fixed yet as Mutex::~Mutex() looks same as in my code. And ThreadLocalRegistryImpl::OnThreadLocalDestroyed( ... ) as well.

First leak at:
https://github.com/google/googletest/blob/master/googletest/src/gtest-port.cc#L534
It can be seen from first reported callstack: testing::internal::ThreadLocalRegistryImpl::GetThreadLocalsMapLocked().

Second leak at:
https://github.com/google/googletest/blob/master/googletest/src/gtest-port.cc#L292
as can be seen from second callstack:
testing::internal::Mutex::ThreadSafeLazyInit.

@BillyDonahue
Copy link
Contributor

On Mon, Dec 14, 2015 at 3:35 AM, Franken notifications@github.com wrote:

My main development flows using MS Visual Studio. My environment
configured to use any of CRT leaks detection or VLD (Visual Leak Detector)
tools. Both of them nagging me every time on same lines in code.

Seems i use old code. I had pulled it at september.
I'll update my local repo, but i definetly sure leaks not fixed yet as
Mutex::~Mutex() looks same as in my code. And ThreadLocalRegistryImpl::OnThreadLocalDestroyed(
... ) as well.

First leak at:

https://github.com/google/googletest/blob/master/googletest/src/gtest-port.cc#L534
It can be seen from first reported callstack:
testing::internal::ThreadLocalRegistryImpl::GetThreadLocalsMapLocked().

static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals;

Static. Not a leak.

Second leak at:

https://github.com/google/googletest/blob/master/googletest/src/gtest-port.cc#L292
as can be seen from second callstack:
testing::internal::Mutex::ThreadSafeLazyInit.

This is a new CriticalSection inside a Mutex that owns it.
Where was the mutex made?


Reply to this email directly or view it on GitHub
#624 (comment).

@FrankStain
Copy link
Author

Static. Not a leak.

Sounds like as airplane constructors tell us that their major issues are only safe liftoff and flight, but safe landing is major issue of airport and passengers.
That is not approach of production development.

Take a look on some system with shared interprocess memory. All applications share same memory space and each of them must free all allocated memory. Or in other case memory will be lost until all system rebooted. A lot of embedded devices work with such systems. Also look at iPhone 3g and early Ios versions.
Lets try to develop Macos-x screensaver and use gtest as debugging self-testing subsystem. And some short time after we start development, we need reboot macos cuz all system memory will be flooded with memory leaked from this static pointer. (Macos-x screensaver is dynamic library, that always loaded and unloaded into screen manager. So this memory will be allocated at every load.)
Lets try develop plugin or library for some application and use gtest as testing subsystem. After some time memory of that application will be flooded and we will needs restart this application. But there are some critical moments where we just can't restart application at all. While debugging critical moments, main application must stay in single consistent state for a long time. And it just can't be restarted.
There are a lot of cases where one small leaked memory may cause huge problems.
This is a static variable and memory it points always leaked with 100% chance.

I had updated my local repo and got fresh report from VLD.
I think allocation of new objects inside _execute_onexit_table() call looks strange. It looks like unpredicted behaviour of code.

d:\th\minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp (359): App!heap_alloc_dbg_internal + 0x14 bytes
d:\th\minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp (450): App!heap_alloc_dbg + 0x18 bytes
d:\th\minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp (492): App!_malloc_dbg
d:\th\minkernel\crts\ucrt\src\appcrt\heap\malloc.cpp (22): App!malloc
f:\dd\vctools\crt\vcstartup\src\heap\new_scalar.cpp (19): App!operator new + 0xA bytes

d:\dev\googletest\googletest\src\gtest-port.cc (534): App!testing::internal::ThreadLocalRegistryImpl::GetThreadLocalsMapLocked + 0x44 bytes
d:\dev\googletest\googletest\src\gtest-port.cc (434): App!testing::internal::ThreadLocalRegistryImpl::OnThreadLocalDestroyed + 0x5 bytes
d:\dev\googletest\googletest\src\gtest-port.cc (556): App!testing::internal::ThreadLocalRegistry::OnThreadLocalDestroyed
d:\dev\googletest\googletest\include\gtest\internal\gtest-port.h (1852): App!testing::internal::ThreadLocal<std::vector<testing::internal::TraceInfo,std::allocator<testing::internal::TraceInfo> > >::~ThreadLocal<std::vector<testing::internal::TraceInfo,std::allocator<testing::internal::TraceInfo> > > + 0x2B bytes
d:\dev\googletest\googletest\src\gtest.cc (4363): App!testing::internal::UnitTestImpl::~UnitTestImpl + 0x13 bytes
0x000000009C3792D7 (File and line number not available): App!testing::internal::UnitTestImpl::`scalar deleting destructor' + 0x17 bytes
d:\dev\googletest\googletest\src\gtest.cc (4303): App!testing::UnitTest::~UnitTest + 0x34 bytes
0x000000009C5FBDE0 (File and line number not available): App!`testing::UnitTest::GetInstance'::`2'::`dynamic atexit destructor for 'instance'' + 0x10 bytes

d:\th\minkernel\crts\ucrt\src\appcrt\startup\onexit.cpp (198): App!<lambda_e971338317bfa523bb8920b43d823727>::operator()
d:\th\minkernel\crts\ucrt\devdiv\vcruntime\inc\internal_shared.h (199): App!__crt_seh_guarded_call<int>::operator()<<lambda_d22e02de4d14401f49897516b29a2b7c>,<lambda_e971338317bfa523bb8920b43d823727> & __ptr64,<lambda_b0b8599c9027f5b14541fbbd6863d1f1> > + 0xA bytes
d:\th\minkernel\crts\ucrt\inc\corecrt_internal.h (882): App!__acrt_lock_and_call<<lambda_e971338317bfa523bb8920b43d823727> >
d:\th\minkernel\crts\ucrt\src\appcrt\startup\onexit.cpp (222): App!_execute_onexit_table
d:\th\minkernel\crts\ucrt\src\appcrt\startup\exit.cpp (211): App!common_exit + 0xC bytes
d:\th\minkernel\crts\ucrt\src\appcrt\startup\exit.cpp (283): App!exit
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (275): App!__scrt_common_main_seh
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (309): App!__scrt_common_main
f:\dd\vctools\crt\vcstartup\src\startup\exe_main.cpp (17): App!mainCRTStartup
0x0000000089F513D2 (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0x22 bytes
0x000000008BCA5454 (File and line number not available): ntdll.dll!RtlUserThreadStart + 0x34 bytes
d:\th\minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp (359): App!heap_alloc_dbg_internal + 0x14 bytes
d:\th\minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp (450): App!heap_alloc_dbg + 0x18 bytes
d:\th\minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp (492): App!_malloc_dbg
d:\th\minkernel\crts\ucrt\src\appcrt\heap\malloc.cpp (22): App!malloc
f:\dd\vctools\crt\vcstartup\src\heap\new_scalar.cpp (19): App!operator new + 0xA bytes

d:\dev\googletest\googletest\src\gtest-port.cc (292): App!testing::internal::Mutex::ThreadSafeLazyInit + 0xA bytes
d:\dev\googletest\googletest\src\gtest-port.cc (261): App!testing::internal::Mutex::Lock
d:\dev\googletest\googletest\include\gtest\internal\gtest-port.h (1715): App!testing::internal::GTestMutexLock::GTestMutexLock + 0x1A bytes
d:\dev\googletest\googletest\src\gtest-port.cc (432): App!testing::internal::ThreadLocalRegistryImpl::OnThreadLocalDestroyed + 0x11 bytes
d:\dev\googletest\googletest\src\gtest-port.cc (556): App!testing::internal::ThreadLocalRegistry::OnThreadLocalDestroyed
d:\dev\googletest\googletest\include\gtest\internal\gtest-port.h (1852): App!testing::internal::ThreadLocal<std::vector<testing::internal::TraceInfo,std::allocator<testing::internal::TraceInfo> > >::~ThreadLocal<std::vector<testing::internal::TraceInfo,std::allocator<testing::internal::TraceInfo> > > + 0x2B bytes
d:\dev\googletest\googletest\src\gtest.cc (4363): App!testing::internal::UnitTestImpl::~UnitTestImpl + 0x13 bytes
0x000000009C3792D7 (File and line number not available): App!testing::internal::UnitTestImpl::`scalar deleting destructor' + 0x17 bytes
d:\dev\googletest\googletest\src\gtest.cc (4303): App!testing::UnitTest::~UnitTest + 0x34 bytes
0x000000009C5FBDE0 (File and line number not available): App!`testing::UnitTest::GetInstance'::`2'::`dynamic atexit destructor for 'instance'' + 0x10 bytes

d:\th\minkernel\crts\ucrt\src\appcrt\startup\onexit.cpp (198): App!<lambda_e971338317bfa523bb8920b43d823727>::operator()
d:\th\minkernel\crts\ucrt\devdiv\vcruntime\inc\internal_shared.h (199): App!__crt_seh_guarded_call<int>::operator()<<lambda_d22e02de4d14401f49897516b29a2b7c>,<lambda_e971338317bfa523bb8920b43d823727> & __ptr64,<lambda_b0b8599c9027f5b14541fbbd6863d1f1> > + 0xA bytes
d:\th\minkernel\crts\ucrt\inc\corecrt_internal.h (882): App!__acrt_lock_and_call<<lambda_e971338317bfa523bb8920b43d823727> >
d:\th\minkernel\crts\ucrt\src\appcrt\startup\onexit.cpp (222): App!_execute_onexit_table
d:\th\minkernel\crts\ucrt\src\appcrt\startup\exit.cpp (211): App!common_exit + 0xC bytes
d:\th\minkernel\crts\ucrt\src\appcrt\startup\exit.cpp (283): App!exit
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (275): App!__scrt_common_main_seh
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (309): App!__scrt_common_main
f:\dd\vctools\crt\vcstartup\src\startup\exe_main.cpp (17): App!mainCRTStartup
0x0000000089F513D2 (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0x22 bytes
0x000000008BCA5454 (File and line number not available): ntdll.dll!RtlUserThreadStart + 0x34 bytes

@BillyDonahue
Copy link
Contributor

On Mon, Dec 14, 2015 at 3:05 PM, Franken notifications@github.com wrote:

Static. Not a leak.

Sounds like as airplane constructors tell us that their major issues are
only safe liftoff and flight, but safe landing is major issue of airport
and passengers.
That is not approach of production development.

Take a look on some system with shared interprocess memory. All
applications share same memory space and each of them must free all
allocated memory. Or in other case memory will be lost until all system
rebooted. A lot of embedded devices work with such systems.

This is process-local memory is allocated from the free store with new.
There's no shared memory concern here.

Also look at iPhone 3g and early Ios versions.
Lets try to develop Macos-x screensaver and use gtest as debugging
self-testing subsystem. And some short time after we start development, we
need reboot macos cuz all system memory will be flooded with memory leaked
from this static pointer. (Macos-x screensaver is dynamic library, that
always loaded and unloaded into screen manager. So this memory will be
allocated at every load.)

I think you're asking a lot here. googletest is not designed to be used
that way. It make stand-alone binaries that run once, print a report, and
exit. It can't be dynamically loaded and unloaded multiple times.

What would a "self-testing subsystem" using dynamic loading of googletest
look like?
It's probably not a mode of operation that we ever considered.

Lets try develop plugin or library for some application and use gtest as
testing subsystem. After some time memory of that application will be
flooded and we will needs restart this application. But there are some
critical moments where we just can't restart application at all. While
debugging critical moments, main application must stay in single consistent
state for a long time. And it just can't be restarted.
There are a lot of cases where one small leaked memory may cause huge
problems.
This is a static variable and memory it points always leaked with 100%
chance.

I had updated my local repo and got fresh report from VLD.
I think allocation of new objects inside _execute_onexit_table() call
looks strange. It looks like unpredicted behaviour of code.

d:\th\minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp (359): App!heap_alloc_dbg_internal + 0x14 bytes
d:\th\minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp (450): App!heap_alloc_dbg + 0x18 bytes
d:\th\minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp (492): App!_malloc_dbg
d:\th\minkernel\crts\ucrt\src\appcrt\heap\malloc.cpp (22): App!malloc
f:\dd\vctools\crt\vcstartup\src\heap\new_scalar.cpp (19): App!operator new + 0xA bytes

d:\dev\googletest\googletest\src\gtest-port.cc (534): App!testing::internal::ThreadLocalRegistryImpl::GetThreadLocalsMapLocked + 0x44 bytes
d:\dev\googletest\googletest\src\gtest-port.cc (434): App!testing::internal::ThreadLocalRegistryImpl::OnThreadLocalDestroyed + 0x5 bytes
d:\dev\googletest\googletest\src\gtest-port.cc (556): App!testing::internal::ThreadLocalRegistry::OnThreadLocalDestroyed
d:\dev\googletest\googletest\include\gtest\internal\gtest-port.h (1852): App!testing::internal::ThreadLocalstd::vector<testing::internal::TraceInfo,std::allocator<testing::internal::TraceInfo > >::~ThreadLocalstd::vector<testing::internal::TraceInfo,std::allocator<testing::internal::TraceInfo > > + 0x2B bytes
d:\dev\googletest\googletest\src\gtest.cc (4363): App!testing::internal::UnitTestImpl::~UnitTestImpl + 0x13 bytes
0x000000009C3792D7 (File and line number not available): App!testing::internal::UnitTestImpl::scalar deleting destructor' + 0x17 bytes d:\dev\googletest\googletest\src\gtest.cc (4303): App!testing::UnitTest::~UnitTest + 0x34 bytes 0x000000009C5FBDE0 (File and line number not available): App!testing::UnitTest::GetInstance'::2'::dynamic atexit destructor for 'instance'' + 0x10 bytes

d:\th\minkernel\crts\ucrt\src\appcrt\startup\onexit.cpp (198): App!<lambda_e971338317bfa523bb8920b43d823727>::operator()
d:\th\minkernel\crts\ucrt\devdiv\vcruntime\inc\internal_shared.h (199): App!__crt_seh_guarded_call::operator()<<lambda_d22e02de4d14401f49897516b29a2b7c>,<lambda_e971338317bfa523bb8920b43d823727> & __ptr64,<lambda_b0b8599c9027f5b14541fbbd6863d1f1> > + 0xA bytes
d:\th\minkernel\crts\ucrt\inc\corecrt_internal.h (882): App!__acrt_lock_and_call<<lambda_e971338317bfa523bb8920b43d823727> >
d:\th\minkernel\crts\ucrt\src\appcrt\startup\onexit.cpp (222): App!_execute_onexit_table
d:\th\minkernel\crts\ucrt\src\appcrt\startup\exit.cpp (211): App!common_exit + 0xC bytes
d:\th\minkernel\crts\ucrt\src\appcrt\startup\exit.cpp (283): App!exit
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (275): App!__scrt_common_main_seh
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (309): App!__scrt_common_main
f:\dd\vctools\crt\vcstartup\src\startup\exe_main.cpp (17): App!mainCRTStartup
0x0000000089F513D2 (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0x22 bytes
0x000000008BCA5454 (File and line number not available): ntdll.dll!RtlUserThreadStart + 0x34 bytes

d:\th\minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp (359): App!heap_alloc_dbg_internal + 0x14 bytes
d:\th\minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp (450): App!heap_alloc_dbg + 0x18 bytes
d:\th\minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp (492): App!_malloc_dbg
d:\th\minkernel\crts\ucrt\src\appcrt\heap\malloc.cpp (22): App!malloc
f:\dd\vctools\crt\vcstartup\src\heap\new_scalar.cpp (19): App!operator new + 0xA bytes

d:\dev\googletest\googletest\src\gtest-port.cc (292): App!testing::internal::Mutex::ThreadSafeLazyInit + 0xA bytes
d:\dev\googletest\googletest\src\gtest-port.cc (261): App!testing::internal::Mutex::Lock
d:\dev\googletest\googletest\include\gtest\internal\gtest-port.h (1715): App!testing::internal::GTestMutexLock::GTestMutexLock + 0x1A bytes
d:\dev\googletest\googletest\src\gtest-port.cc (432): App!testing::internal::ThreadLocalRegistryImpl::OnThreadLocalDestroyed + 0x11 bytes
d:\dev\googletest\googletest\src\gtest-port.cc (556): App!testing::internal::ThreadLocalRegistry::OnThreadLocalDestroyed
d:\dev\googletest\googletest\include\gtest\internal\gtest-port.h (1852): App!testing::internal::ThreadLocalstd::vector<testing::internal::TraceInfo,std::allocator<testing::internal::TraceInfo > >::~ThreadLocalstd::vector<testing::internal::TraceInfo,std::allocator<testing::internal::TraceInfo > > + 0x2B bytes
d:\dev\googletest\googletest\src\gtest.cc (4363): App!testing::internal::UnitTestImpl::~UnitTestImpl + 0x13 bytes
0x000000009C3792D7 (File and line number not available): App!testing::internal::UnitTestImpl::scalar deleting destructor' + 0x17 bytes d:\dev\googletest\googletest\src\gtest.cc (4303): App!testing::UnitTest::~UnitTest + 0x34 bytes 0x000000009C5FBDE0 (File and line number not available): App!testing::UnitTest::GetInstance'::2'::dynamic atexit destructor for 'instance'' + 0x10 bytes

d:\th\minkernel\crts\ucrt\src\appcrt\startup\onexit.cpp (198): App!<lambda_e971338317bfa523bb8920b43d823727>::operator()
d:\th\minkernel\crts\ucrt\devdiv\vcruntime\inc\internal_shared.h (199): App!__crt_seh_guarded_call::operator()<<lambda_d22e02de4d14401f49897516b29a2b7c>,<lambda_e971338317bfa523bb8920b43d823727> & __ptr64,<lambda_b0b8599c9027f5b14541fbbd6863d1f1> > + 0xA bytes
d:\th\minkernel\crts\ucrt\inc\corecrt_internal.h (882): App!__acrt_lock_and_call<<lambda_e971338317bfa523bb8920b43d823727> >
d:\th\minkernel\crts\ucrt\src\appcrt\startup\onexit.cpp (222): App!_execute_onexit_table
d:\th\minkernel\crts\ucrt\src\appcrt\startup\exit.cpp (211): App!common_exit + 0xC bytes
d:\th\minkernel\crts\ucrt\src\appcrt\startup\exit.cpp (283): App!exit
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (275): App!__scrt_common_main_seh
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (309): App!__scrt_common_main
f:\dd\vctools\crt\vcstartup\src\startup\exe_main.cpp (17): App!mainCRTStartup
0x0000000089F513D2 (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0x22 bytes
0x000000008BCA5454 (File and line number not available): ntdll.dll!RtlUserThreadStart + 0x34 bytes


Reply to this email directly or view it on GitHub
#624 (comment).

@FrankStain
Copy link
Author

I just try point your attention that plane must lands safely too. And this is not a problem of OS or gtest users.
Gtest may be used as that 'standalone' binary in embedded or mobile OS for tests. I use it to test my framework on 5 operation systems (3 of them are mobile). And i worry about memory leaks gtest makes. And there is actually no metter how memory allocated, it just lost.

What would a "self-testing subsystem" using dynamic loading of googletest
look like?

It may be a .dll file with gtest + all tests inside, which may be loaded by main application as plugin, executed for tests (via interface function) and unloaded after tests passed. Dynamic libraries work in shared with main application memory.
Such self-testing subsystem may interact with application via interface, thinking it's a singleton. Or it just can examine memory of application to detect code modifications, code injections or memory manipulation as well.
Gtest may be pretty useful in this approach.

@gennadiycivil
Copy link
Contributor

Should be addressed by #1142

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants