jmeubank / tdm-gcc

TDM-GCC is a cleverly disguised GCC compiler for Windows!
https://jmeubank.github.io/tdm-gcc/
584 stars 49 forks source link

With exceptions enabled, each thread leaks its handle #39

Open justanotheranonymoususer opened 3 years ago

justanotheranonymoususer commented 3 years ago

That's a critical problem that took me several hours to pinpoint to TDM-GCC, and looks like the root cause is in the same place as the problem from my previous bug report.

It's easy to reproduce: Create several threads with code that uses exceptions, and check the amount of handles that the process uses. For example:

#include <mutex>

volatile bool volatile_bool_false = false;
std::mutex test_mutex;

DWORD WINAPI test(LPVOID)
{
    if (volatile_bool_false)
        std::lock_guard<std::mutex> guard(test_mutex);
    return 0;
}

int main()
{
    for (int i=0; i<1000; i++)
        CreateThread(nullptr, 0, test, nullptr, 0, nullptr);
    return 0;
}

The handle is created by Winpthreads by using DuplicateHandle in a function called pthread_getspecific, and is never closed. By looking at the source code, the handle is closed in two scenarios:

Neither of them are executed, and so the thread handle is left dangling forever. This causes a handle leak, and a memory leak of non-paged memory, which gets worse with time as more threads are created and destroyed.