Issue 126541
Summary [asan][win] 'CreateThread' leaks on Windows
Labels new issue
Assignees
Reporter GkvJwa
    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.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to