<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/126541>126541</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [asan][win] 'CreateThread' leaks on Windows
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          GkvJwa
      </td>
    </tr>
</table>

<pre>
    When I used asan for detection on Windows, I found that oom occurred every time

Judging from ```vmmap```, there is a large amount of 'privatedata' that has not been released after new.

![Image](https://github.com/user-attachments/assets/29c424f9-cc8b-4c1f-9c17-85e4b4435d4f)

![Image](https://github.com/user-attachments/assets/e9466666-d50a-4b50-8a69-29b06849643a)

Due to the call to ```Virtualalloc```, I spent a lot of time finding the cause of the problem

1.Call the ```Virtualalloc``` here to create space
https://github.com/llvm/llvm-project/blob/7ae78a6cdb6ce9ad1534ed10519649fb3d47aca9/compiler-rt/lib/asan/asan_thread.cpp#L96-L112

2.After ```start_routine```, Destory it
https://github.com/llvm/llvm-project/blob/7ae78a6cdb6ce9ad1534ed10519649fb3d47aca9/compiler-rt/lib/asan/asan_win.cpp#L138-L153

The problem here is that when a thread ends on Windows, it will not be called next
```
  t->Destroy();  // POSIX calls this from TSD destructor.
```

```
template <typename ThreadProcedure, bool Ex>
static unsigned long WINAPI thread_start(void* const parameter) throw()
{
 ...

    __try
    {
        ThreadProcedure const procedure = reinterpret_cast<ThreadProcedure>(context->_procedure);
        if constexpr (Ex)
        {
            _endthreadex(procedure(context->_context));
 }
```


```
static void __cdecl common_end_thread(unsigned int const return_code) throw()
{
    __acrt_ptd* const ptd = __acrt_getptd_noexit();
    if (!ptd)
    {
 ExitThread(return_code);
    }

    __acrt_thread_parameter* const parameter = ptd->_beginthread_context;
    if (!parameter)
    {
 ExitThread(return_code);
    }

    if (parameter->_initialized_apartment)
    {
 __acrt_RoUninitialize();
    }

    if (parameter->_thread_handle != INVALID_HANDLE_VALUE && parameter->_thread_handle != nullptr)
    {
 CloseHandle(parameter->_thread_handle);
    }

    if (parameter->_module_handle != INVALID_HANDLE_VALUE && parameter->_module_handle != nullptr)
    {
 FreeLibraryAndExitThread(parameter->_module_handle, return_code);
 }

```

Usually the system calls FreeLibraryAndExitThread to end the thread, As a result, memory cannot be released.
And because my test program happened to frequently create threads and end them normally quickly, it eventually led to oom.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzMVl-T4rgR_zTipQvKlm2wH3hghpkcV1Obrdz-yRslSw0oK0s-qT1APn1KtmGG2dm9XJKHUFOFPUL9-9MtdYsQ9N4iLllxx4r1RHR0cH75l2_Pvx7FpHbqvPx6QAsb6AIqEEFY2DkPCgklaWfBWfiqrXLHwPg9bGDnOquADoLAuQaclJ33qACf0Z-BdIMsWbFk9Wun9truYeddA2yeDH_PTSPa61uMSAf0CDqAACP8HkE0rrMEbgeML1qvnwWhEiQYXwywBxHAOoIa0YJHg6KnviP0YPE4G_AZT1lxt2nEHlmxZrw8ELWBZSvGHxl_3Gs6dPVMuobxxy6gnwoiIQ8NWgqMP4oQsH_glcx5vqumUpb1NJfpblrJdDEtC8zrPM8Kle8Yr_63oFjl8_iZqiIR07wukmkp5tWUV3UyL_NqnmfiCrruEMhFI0EKY-Lz1eEv2lMnjDDGyRvbNxBatBRdd73ZMXOw01bFpA2xuoD9ygGh9a422AyA6ey-xzngHwBBn1tyID0KQgitkLE8fuKKMc-Xr2nr3T9QEuOPtXE1448LgYtSzKWq5xIrodIiy1GlSZFW87za1ZnKF0KKivFH6ZpWG_RTH_cbXff2Cjt-bengUaiZbFvGs6dqPn1KUz7I47NVX0tXGYGEp613HWmLNy6uMZDzZ9D0_6HqqO1FUpqV06e0yAZNn15yCJcD1x-mYzz9AgY7AK0Kb068JjhqY8YT11cYKrB4ipJfzEhWADRl2UO0xLsz42Us0OwOYPADPv71t83f-_0RWofhZvj02xpU3NJJcn72JuabV8KmNbGQWHZP5xataBA-9dQ_eidRdR4j59o5Aw8nlj2wZBVIkJbQ2f4mVGCc3cPXzYfVx80oe9snmPHy2WnF-Aqks4GgFV40SOgZr-Iv3XEUlazY4i4qns3GywYAYLslfx6fx_Xx84bhJfz1nWVr8KgtoW890laKQCy7fysse2C8lM4Snnqnt-2L5uj0K0S9G0Dw1HpgvHw4Dbwv67f8evZo1eAGnhgvX4W-gRyfY7QrJlus30nb7X_GJESDYbuVCqUB6ZrG2Qg8nkbGy2uWtKXRJ4_UebuVTuEPE9HbL6SnbUuvM0iqN3dc2yO1pLbW4UnTtUDH_Tr2m5LxtI9Q3Sby4aTp04XjLaGXCKMPN3TGAntVSt9VV8-wJdX7W-Ne23HTxet3KL6qzP-W6BD0GrFnoa0mLYz-J6qtaIWn2KC-wxol_s19ti8b3tr6h1ij2IOwyiDEBpqtYfPhy-pps97-svqwfnrYflk9fX4AxueMz-Hf2G47Y1r63p174wL-0v_05zz-nITGqc7gfyzh3e0_kvDoEZ907YU_r6y6SfdPosZL8d1quGp7c3w_h04Yc-57fDgHwma8uX-EH7s89oMhwuU038MqjnUeQ2covjbYxG4phR27yWV6i9foyiqocZg6mjMQDnfk3osGDqJtMV4L5GDn8fcOLZnzZawY8AIIqy4cGrDON72E3zstv5nz2MvwGS0N2swQz7lmNlHLTFVZJSa4TBdZxZOiSIvJYSmqalHX6WKRlHUuy12WlIuymqtSZtlCpHyilzzhRcLTJJ1nZVbMVMrlnM9lmu1klVSc5Qk2QptZbP4z5_cTHUKHy5TPizydGFGjCf14zrnFI_SrjPM4rftlPzHU3T6wPDE6UHgJQ5pMP9f3A0CxZsXdUceHODff985cSmMBBsW315190nmz_NMDS88tzqcj-ecl_1cAAAD__70f268">