AfxBeginThread fails to create thread on Windows XP
How can AfxBeginThread fail when there are plenty of resources available and the application is a multi threaded one. That's what I thought when I saw this issue from a customer. I went and read the documentation for AfxBeginThread and I didn't see anything unusual that customer is doing. He also mentioned that CreateThread fails too!
Luckily for me the customer was nice enough to give a repro of the issue. So went on a debugging spree to find out the reason.
I saw that AfxBeginThread calls are failing as a result of CWinThread::CreateThread failing...
if (!pThread->CreateThread(dwCreateFlags|CREATE_SUSPENDED, nStackSize,
lpSecurityAttrs))
{
pThread->Delete();
return NULL;
}
CreateThread instead fails on...
// create the thread (it may or may not start to run)
m_hThread = (HANDLE)(ULONG_PTR)_beginthreadex(lpSecurityAttrs, nStackSize, &_AfxThreadEntry, &startup, dwCreateFlags | CREATE_SUSPENDED, (UINT*)&m_nThreadID);
Thread handle returned is NULL. Last error is as follows...
0:000> !gle
LastErrorValue: (Win32) 0x57 (87) - The parameter is incorrect.
LastStatusValue: (NTSTATUS) 0xc00000f2 - An invalid parameter was passed to a service or function as the fourth argument.
Since customer mentioned that CreateThread API is also failing so stepped into CreateThread to find out what is wrong. I saw that the call to kernel32!BaseCreateStack fails. That gave me a hint that something is wrong with the stack size that's passed to CreateThread/AfxBeginThread. Went checking in project properties to see what is the value of stack size that the customer had. I saw that he had '0' for both "Stack Reserve Size" and "Stack Commit Size". Created a repro in Visual Studio 2010 by setting both these values to 0 and voila I see that AfxBeginThread fails. So fix for this issue is that leave the Stack Reserve/Commit Size blank if you don't intend to specify a size in Visual Studio 2010.
In Visual Studio 2008 both these values were set to zero and we were not allowed to leave it blank but in Visual Studio 2010 we should leave it as blank if don't want to specify a value. This is what happened with customer; he had converted his existing project from Visual Studio 2008 to Visual Studio 2010 and for some unknown reason the values remained. I tried to repro the conversion issue at my end but for me the stack commit/reserve size values were converted properly, i.e they were left blank in Visual Studio 2010. Seems like at customer's side someone played around with it. ;) See below screenshot which shows '0' in the stack size fields, clear them out in Visual Studio 2010 if you didn't intend to set it.
For XP stack commit size cannot be zero, different operating systems have different interpretations for stack size values. On windows 7 the same application worked. Also note that you can edit the stack size values using editbin utility. Check this documentation out: msdn.microsoft.com/en-us/library/35yc2tc3.aspx.