This intreeged me also, so I decided to find my personal answer; As another poster says, its a bit of a "crystal ball" endevour, but...
The probable cause is one of your threads called either:
- WaitForSingleObject or
- WaitForMultipleObjects
The implementation of this in the latest versions of Windows seems to spawn a thread pool to facilitate waiting for objects (don't know why).
This might also possibly be happening before your main because you have some code which causes a global scoped object to be created which then starts off code before you even hit your entry point (this may even be in some standard library code for Windows 10 SDK).
For anyone wanting to find out their own SPECIFIC cause, you can TRY this:
class RunBeforeMain
{
public:
RunBeforeMain()
{
HMODULE hNtDll = (HMODULE)LoadLibrary(_T("ntdll.dll"));
FARPROC lpNeeded = GetProcAddress(hNtDll,"NtWaitForMultipleObjects");
DebugBreakPoint();
}
};
RunBeforeMain go;
int CALLBACK WinMain(
_In_ HINSTANCE hInstance,
_In_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nCmdShow
)
{
}
When you run this, you will get the library load location for NtDll procedure NtWaitForMultipleObjects in lpNeeded, grab that address and paste it into the disassembly view window then place a breakpoint on the first line.
Now continue running your solution.
Couple of caveats:
- We can't effectively control the initialisation order of globals, this is why if you've got good sense coding you avoid them at all costs (unless theres some exeptional need). Due to this fact, we can't guarentee our global will trigger before whatever other global causes additional threads.
- Whilst this is before main, the DLL loads of any libraries will proceed any of our calls, therefore, it might be already too late (you can use hacks like forcing no auto loading of libraries but that's way beyond my level of willingness to care here lol).
Hope this helps someone :)
CreateThread
. Note that placing breakpoints by name is very common using windbg, while in the Visual Studio debugger it's possible but requires learning some unusual menu commands. – Ben Voigt