[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