<HTML><HEAD>
<META content="text/html; charset=utf-8" http-equiv=Content-Type>
<STYLE id=mysingle_style type=text/css>.search-word {
        BACKGROUND-COLOR: #ffee94
}
P {
        MARGIN-BOTTOM: 5px; FONT-SIZE: 10pt; FONT-FAMILY: Arial, arial; MARGIN-TOP: 5px
}
TD {
        MARGIN-BOTTOM: 5px; FONT-SIZE: 10pt; FONT-FAMILY: Arial, arial; MARGIN-TOP: 5px
}
LI {
        MARGIN-BOTTOM: 5px; FONT-SIZE: 10pt; FONT-FAMILY: Arial, arial; MARGIN-TOP: 5px
}
BODY {
        FONT-SIZE: 10pt; FONT-FAMILY: Arial, arial
}
</STYLE>

<META content=IE=5 http-equiv=X-UA-Compatible>
<META content=IE=5 http-equiv=X-UA-Compatible>
<STYLE id=knox_style type=text/css>P {
        MARGIN-BOTTOM: 5px; FONT-SIZE: 10pt; FONT-FAMILY: Arial, arial; MARGIN-TOP: 5px
}
</STYLE>

<META content=IE=5 http-equiv=X-UA-Compatible>
<META name=GENERATOR content="MSHTML 11.00.9600.18921"></HEAD>
<BODY>
<P></P>
<P>Hello Eric,</P>
<P> </P>
<P>Thank you for the reply.</P>
<P> </P>
<P>If it is intentionally leaked, Is it freed at any later stage and who is responsible for cleanup?</P>
<P> </P>
<P>In our case, below is the call sequence.</P>
<P> </P>
<P>======================<STRONG>First Time(No Memory Leak) </STRONG>==============================  <BR>1. malloc()    // ALLOC1                                                               <BR>                                                                                    <BR>2. malloc()    // ALLOC2                                                               <BR>                                                                                    <BR>3. malloc()    // ALLOC3                                                               <BR>                                                                                    <BR>4. pthread_create()       // pthread_create by std::thread                             <BR>                                                                                    <BR><STRONG>5. pthread_key_create()  // Key created                                               <BR>                                                                                 <BR>6. _aeabi_atexit()        // static storage destructor register to atexit              </STRONG><BR>                                                                                    <BR>7. free()      //ALLOC3 freed                                                         <BR>                                                                                    <BR>8. pthread_exit()                                                                      <BR>                                                                                    <BR><STRONG>9. std::__thread_specific_ptr<std::__thread_struct>::__at_thread_exit()                <BR>        //Key destructor called                                                     <BR>                                                                                    <BR>10. free()     //ALLOC2 freed                                                          <BR>                                                                                    <BR>11. free()     //ALOOC1 freed                                                          </STRONG><BR>                                                                                    <BR>12. std::__thread_specific_ptr<std::__thread_struct>::~__thread_specific_ptr            <BR>        //thread_specific_ptr static storage destructor called                      <BR>                                                                                    <BR>======================<STRONG>Second Time Onwards (Memory Leak)</STRONG> =======================  <BR>1. malloc()    // ALLOC1                                                               <BR>                                                                                    <BR>2. malloc()    // ALLOC2                                                               <BR>                                                                                    <BR>3. malloc()    // ALLOC3                                                               <BR>                                                                                    <BR>4. pthread_create()       // pthread_create by std::thread                             <BR>                                                                                    <BR>5. free()      //ALLOC3 free'd                                                         <BR>                                                                                    <BR>6. pthread_exit()  </P>
<P>   // ALLOC1 & ALLOC2 are not freed</P>
<P>   // No call to  __thread_specific_ptr destructor                                                                    <BR>============================================================================== </P>
<P> </P>
<P>If we observe in the leak case, thread key is not created and<STRONG> </STRONG>static storage destructor is not registered to atexit. Hence there is no<STRONG>  </STRONG>key destructor(::__at_thread_exit()) called during exit and ALLOC1 & ALLOC2  are not freed which were freed properly in the working case.</P>
<P>Also there is no call to  __thread_specific_ptr destructor.</P>
<P>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.</P>
<P> </P>
<P>Can you please suggest some methods to avoid these leaks.?</P>
<P> </P>
<P>Thanks,</P>
<P>Manohar</P>
<P>--------- <B>Original Message</B> ---------</P>
<P><B>Sender</B> : Eric Fiselier <eric@efcs.ca></P>
<P><B>Date</B> : 2018-05-19 12:30 (GMT+5:30)</P>
<P><B>Title</B> : Re: [cfe-dev] [Libcxx/TizenRT]: Memory leak in std::thread</P>
<P> </P>
<DIV dir=ltr><BR>
<DIV class=gmail_extra><BR>
<DIV class=gmail_quote>On Fri, May 18, 2018 at 4:39 AM, Manohara Hosakoppa Krishnamurt via cfe-dev <SPAN dir=ltr><<A href="mailto:cfe-dev@lists.llvm.org" target=_blank>cfe-dev@lists.llvm.org</A>></SPAN> wrote:<BR>
<BLOCKQUOTE class=gmail_quote style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">
<DIV>
<P>Hello Everyone,</P>
<P> </P>
<P>We are using <STRONG>LLVM libc++ </STRONG>in TizenRT IoT OS( <A href="https://github.com/Samsung/TizenRT" target=_blank>https://github.com/Samsung/<WBR>TizenRT</A>). We observed <STRONG>memory leak while using std::thread</STRONG></P>
<P> </P>
<P>About TizenRT:</P>
<P>LLVM libc++ source has been integrated to TizenRT and the whole platform(OS + libc + libcpp + App) is built into  a single elf executable.</P>
<P>TizenRT uses a FLAT memory model(physical memory), there is no virtual memory support and hence we cant run application executables (elf) directly.</P>
<P> </P>
<P>First time when we create a thread using std::thread , there is no memory leak after thread exits.</P>
<P>But next time onwards, if we create a thread using std::thread and after thread exits there is a memory leak.</P>
<P> </P>
<P>First time__thread_specific_ptr<__<WBR>thread_struct> is constructed in __thread_local_data()  and hence the pthread_key_create() and during exit key is destroyed.</P>
<P> </P>
<P>But second time onwards, __thread_specific_ptr<__<WBR>thread_struct> is not getting constructed in __thread_local_data().</P>
<P>__thread_local_data()         <WBR>                              <WBR>                     <BR>{                             <WBR>                              <WBR>                     <BR>    static __thread_specific_ptr<__<WBR>thread_struct> __p;                           <BR>    return __p;                          <WBR>                              <WBR>      <BR>}</P>
<P> </P>
<P>We suspect that the problem is with __thread_local_data(), and __thread_specific_ptr is getting constructed only once.</P>
<P>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.</P></DIV></BLOCKQUOTE>
<DIV>
<DIV style="FONT-SIZE: small; FONT-FAMILY: arial,sans-serif; WHITE-SPACE: normal; WORD-SPACING: 0px; TEXT-TRANSFORM: none; FONT-WEIGHT: 400; COLOR: rgb(34,34,34); FONT-STYLE: normal; LETTER-SPACING: normal; BACKGROUND-COLOR: rgb(255,255,255); TEXT-INDENT: 0px; font-variant-ligatures: normal; font-variant-caps: normal; text-decoration-style: initial; text-decoration-color: initial"><BR class=gmail-Apple-interchange-newline>__thread_specific_ptr intentionally leaks. See <A href="https://github.com/llvm-mirror/libcxx/blob/master/include/thread#L189">https://github.com/llvm-mirror/libcxx/blob/master/include/thread#L189</A></DIV> </DIV>
<BLOCKQUOTE class=gmail_quote style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">
<DIV>
<P> </P>
<P>Please guide us with,  how can we deallocate these objects after or during thread exit.</P>
<P>Also  what is the expected behavior of thread_local_data instance?<BR>1. One thread_local_data instance for a process/task and all of its threads(pthreads) share the same thread_local_data instance?</P>
<P>OR<BR>2. Each thread(pthread) should have a separate thread_local_data instance?</P>
<P> </P>
<P>Thanks,</P>
<P>Manohar</P>
<P> </P>
<P> </P>
<P> </P>
<P> </P>
<P> </P>
<P> </P>
<P> </P>
<P> </P>
<P> </P>
<P> </P>
<P> </P>
<P> </P>
<P> </P>
<P> </P>
<P> </P>
<P> </P>
<P> </P>
<P> </P>
<P> </P>
<P> </P>
<TABLE id=m_723327727297999446bannersignimg>
<TBODY>
<TR>
<TD>
<DIV id=m_723327727297999446cafe-note-contents style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; MARGIN: 10px">
<P> </P></DIV></TD></TR></TBODY></TABLE>
<TABLE id=m_723327727297999446confidentialsignimg>
<TBODY>
<TR>
<TD>
<DIV id=m_723327727297999446cafe-note-contents style="FONT-SIZE: 10pt; FONT-FAMILY: Arial; MARGIN: 10px">
<P><IMG style="BORDER-TOP: 0px solid; HEIGHT: 144px; BORDER-RIGHT: 0px solid; WIDTH: 520px; BORDER-BOTTOM: 0px solid; BORDER-LEFT: 0px solid; DISPLAY: inline-block" src="cid:3IN37TXXDPBB@namo.co.kr"><BR></P></DIV></TD></TR></TBODY></TABLE></DIV><BR>______________________________<WBR>_________________<BR>cfe-dev mailing list<BR><A href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</A><BR><A href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel=noreferrer target=_blank>http://lists.llvm.org/cgi-bin/<WBR>mailman/listinfo/cfe-dev</A><BR><BR></BLOCKQUOTE></DIV><BR></DIV></DIV><table id=confidentialsignimg><tr><td>
<!--<p> <img border="0" src="http://www.samsung.net/pt_images/PCL/securityimage/MSI_20140519003732214.gif"/></p> -->
<p><img border="0" src="cid:XOK0LK7CT9SZ@namo.co.kr"/></p> 
</td></tr></table></BODY></HTML><img src='http://ext.samsung.net/mail/ext/v1/external/status/update?userid=manohara.hk&do=bWFpbElEPTIwMTgwNTIxMTEzMDQwZXBjbXM1cDY0OGQ4NjViNGEwNmM4ZDdiNjI0OWMxNzgwZTljZDljOSZyZWNpcGllbnRBZGRyZXNzPWNmZS1kZXZAbGlzdHMubGx2bS5vcmc_' border=0 width=0 height=0 style='display:none'>