[cfe-dev] [Libcxx/TizenRT]: Memory leak in std::thread
John McCall via cfe-dev
cfe-dev at lists.llvm.org
Tue May 22 13:24:56 PDT 2018
> On May 21, 2018, at 7:30 AM, Manohara Hosakoppa Krishnamurt via cfe-dev <cfe-dev at lists.llvm.org> wrote:
> Hello Eric,
>
> Thank you for the reply.
>
> If it is intentionally leaked, Is it freed at any later stage and who is responsible for cleanup?
Nothing; it's leaked under the assumption that normal memory allocations will be returned to the OS at exit. This is a common technique used in language libraries and runtimes. It's even considered good practice, at it allows the process to exit faster and eliminates a source of crashes during user-provided atexit() teardown. If Tizen doesn't return process memory automatically, you will need to change the code when compiling for Tizen.
John.
>
> In our case, below is the call sequence.
>
> ======================First Time(No Memory Leak) ==============================
> 1. malloc() // ALLOC1
>
> 2. malloc() // ALLOC2
>
> 3. malloc() // ALLOC3
>
> 4. pthread_create() // pthread_create by std::thread
>
> 5. pthread_key_create() // Key created
>
> 6. _aeabi_atexit() // static storage destructor register to atexit
>
> 7. free() //ALLOC3 freed
>
> 8. pthread_exit()
>
> 9. std::__thread_specific_ptr<std::__thread_struct>::__at_thread_exit()
> //Key destructor called
>
> 10. free() //ALLOC2 freed
>
> 11. free() //ALOOC1 freed
>
> 12. std::__thread_specific_ptr<std::__thread_struct>::~__thread_specific_ptr
> //thread_specific_ptr static storage destructor called
>
> ======================Second Time Onwards (Memory Leak)=======================
> 1. malloc() // ALLOC1
>
> 2. malloc() // ALLOC2
>
> 3. malloc() // ALLOC3
>
> 4. pthread_create() // pthread_create by std::thread
>
> 5. free() //ALLOC3 free'd
>
> 6. pthread_exit()
> // ALLOC1 & ALLOC2 are not freed
> // No call to __thread_specific_ptr destructor
> ==============================================================================
>
> If we observe in the leak case, thread key is not created and static storage destructor is not registered to atexit. Hence there is no key destructor(::__at_thread_exit()) called during exit and ALLOC1 & ALLOC2 are not freed which were freed properly in the working case.
> Also there is no call to __thread_specific_ptr destructor.
> Note : As TizenRT is a RTOS and works on flat memory model, global data space(data & bss) are not released when application exits. Hence any variables with global scope always persist till the device power off.
>
> Can you please suggest some methods to avoid these leaks.?
>
> Thanks,
> Manohar
> --------- Original Message ---------
> Sender : Eric Fiselier <eric at efcs.ca <mailto:eric at efcs.ca>>
> Date : 2018-05-19 12:30 (GMT+5:30)
> Title : Re: [cfe-dev] [Libcxx/TizenRT]: Memory leak in std::thread
>
>
>
> On Fri, May 18, 2018 at 4:39 AM, Manohara Hosakoppa Krishnamurt via cfe-dev <cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org>> wrote:
> Hello Everyone,
>
> We are using LLVM libc++ in TizenRT IoT OS( https://github.com/Samsung/TizenRT <https://github.com/Samsung/TizenRT>). We observed memory leak while using std::thread
>
> About TizenRT:
> LLVM libc++ source has been integrated to TizenRT and the whole platform(OS + libc + libcpp + App) is built into a single elf executable.
> TizenRT uses a FLAT memory model(physical memory), there is no virtual memory support and hence we cant run application executables (elf) directly.
>
> First time when we create a thread using std::thread , there is no memory leak after thread exits.
> But next time onwards, if we create a thread using std::thread and after thread exits there is a memory leak.
>
> First time__thread_specific_ptr<__thread_struct> is constructed in __thread_local_data() and hence the pthread_key_create() and during exit key is destroyed.
>
> But second time onwards, __thread_specific_ptr<__thread_struct> is not getting constructed in __thread_local_data().
> __thread_local_data()
> {
> static __thread_specific_ptr<__thread_struct> __p;
> return __p;
> }
>
> We suspect that the problem is with __thread_local_data(), and __thread_specific_ptr is getting constructed only once.
> Because of this we feel "__thread_struct and __thread_struct_impl " which are allocated earlier during thread create are not getting freed and there is a leak.
>
> __thread_specific_ptr intentionally leaks. See https://github.com/llvm-mirror/libcxx/blob/master/include/thread#L189 <https://github.com/llvm-mirror/libcxx/blob/master/include/thread#L189>
>
> Please guide us with, how can we deallocate these objects after or during thread exit.
> Also what is the expected behavior of thread_local_data instance?
> 1. One thread_local_data instance for a process/task and all of its threads(pthreads) share the same thread_local_data instance?
> OR
> 2. Each thread(pthread) should have a separate thread_local_data instance?
>
> Thanks,
> Manohar
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> <201805211700708_LCGFY2AH.gif>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org>
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev>
>
>
> <201602111742151_N3WZA6X7.png>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org>
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20180522/6a214802/attachment.html>
More information about the cfe-dev
mailing list