Skip to content

Instantly share code, notes, and snippets.

@dnikku
Last active November 11, 2015 00:40
Show Gist options
  • Save dnikku/a18d94ccdcd8434a5b87 to your computer and use it in GitHub Desktop.
Save dnikku/a18d94ccdcd8434a5b87 to your computer and use it in GitHub Desktop.
_beginthreadex/CreateThread leaks when using CRT or not
#include "stdafx.h"
/*
stdafx.f:
#include <time.h>
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
#include <process.h>
*/
static LONG g_scheduledThreads = 0; // count nr of scheduled threads
static LONG g_executedThreads = 0; // count executed successfully
void printCounts(int step) {
printf(" step:%d, scheduled:%d, completed:%d\n", step, g_scheduledThreads, g_executedThreads);
}
/*
just paste the crt\src\time64.c, removing some comments ...
#define EPOCH_BIAS 116444736000000000i64
typedef union {
unsigned __int64 ft_scalar;
FILETIME ft_struct;
} FT;
__time64_t __cdecl _time64(
__time64_t *timeptr
)
{
__time64_t tim;
FT nt_time;
GetSystemTimeAsFileTime(&(nt_time.ft_struct));
tim = (__time64_t)((nt_time.ft_scalar - EPOCH_BIAS) / 10000000i64);
if (tim > _MAX__TIME64_T)
tim = (__time64_t)(-1);
if (timeptr)
*timeptr = tim;
return tim;
}
*/
void executeThread(int v){
//1. leaks:
time_t tt = _time64(NULL);
//2. leaks: FILETIME ft; GetSystemTimeAsFileTime(&ft);
//3. no leaks: SYSTEMTIME stm; GetSystemTime(&stm);
//4. no leaks: char sz[524 * 1024]; sprintf(sz, "Salutare de la mare");
InterlockedAdd(&g_executedThreads, v);
}
static DWORD WINAPI createthread_wrapper(void *arg) {
executeThread(1);
return 0;
}
bool createthread_factory() {
InterlockedAdd(&g_scheduledThreads, 1);
DWORD id;
HANDLE hThread = CreateThread(NULL, 640 * 1024, createthread_wrapper, NULL, 0x00010000, &id);
if (hThread == NULL) {
DWORD lastError = GetLastError();
printf("CreateThread failed. err(%d). exiting ...\n", lastError);
return false;
}
else {
CloseHandle(hThread);
return true;
}
}
static unsigned int __stdcall _beginthreadex_wrapper(void *arg) {
executeThread(1);
return 0;
}
bool _beginthreadex_factory() {
InterlockedAdd(&g_scheduledThreads, 1);
unsigned int id;
HANDLE handle = (HANDLE)_beginthreadex(NULL,
6400 * 1024, _beginthreadex_wrapper, NULL, STACK_SIZE_PARAM_IS_A_RESERVATION, &id);
if (handle == 0) {
DWORD lastError = GetLastError();
printf("_beginthreadex failed. err(%d); errno(%d). exiting ...\n", lastError, errno);
return false;
}
else {
CloseHandle(handle);
return true;
}
}
int _tmain(int argc, _TCHAR* argv[]) {
printf("starting ...\n");
bool(*f_wrapper) () = 1 ? _beginthreadex_factory : createthread_factory;
while (true) {
int i;
for (i = 0; i < 1000000; i++) {
if (!f_wrapper()){
Sleep(5 * 1000); // wait some time ...
printCounts(i);
// try to create 10 more threads
for (int j = 0; j < 10; j++) f_wrapper();
break; // exit from for ...
}
if (i % 10000 == 0) printCounts(i); // print progress
}
Sleep(4 * 1000); // wait to stop all threads
printCounts(i);
printf("read char:");
getchar(); // press enter to rerun
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment