我正在运行一个简单的Windows控制台应用程序: - 当控件进入main时,我倾倒了堆栈 -
_ 我的主线程堆栈:
5840 0 Main Thread Main Thread Normal
console.exe!wmain(int argc=1, wchar_t * * argv=0x006831a0)
console.exe!__tmainCRTStartup()
console.exe!wmainCRTStartup()
kernel32.dll!@BaseThreadInitThunk@12()
ntdll.dll!___RtlUserThreadStart@8()
ntdll.dll!__RtlUserThreadStart@8()
__
以上情况很好,为什么我在启动时会看到这个?:
3740 0 Worker Thread Win32 Thread Normal
堆栈:
ntdll.dll!_KiFastSystemCallRet@0()
ntdll.dll!_ZwDelayExecution@8()
ntdll.dll!__LdrpInitialize@8()
ntdll.dll!_LdrInitializeThunk@8()
答案 0 :(得分:1)
LdrInitializeThunk是设置新线程的方法。我确实用VS2008创建了一个普通的Win32控制台应用程序(没有MFC,ATL)并且只获得一个线程。只有当我附加一个调试器时,我得到第二个,因为调试器注入一个线程来启用进程的调试。 在here一书中详细介绍了流程启动,其中没有提到需要第二个线程的内容。异步过程调用APCs也不应该受到指责。也许您的调用堆栈是在未加载所有符号的情况下创建的,并且您错误地怀疑调试器帮助程序线程是应用程序中的隐藏线程。当您使用没有调试器的进程资源管理器查看您的进程时,您应该只看到一个线程。
阶段6:执行过程 在语境中初始化 新流程
KiInitializeContextThread,即 由KeInitializeThread调用,构建 线程的初始上下文和 线程的内核堆栈。新的 线程开始生命运行 内核模式线程启动例程 KiThreadStartup。 (更详细的说明 线程启动的描述 通往此的步骤,请参阅本节 “CreateThread的流程。”) KiThreadStartup例程执行 以下步骤:
将IRQL级别从DPC /调度级别降低到APC (异步程序调用)级别。
启用工作集扩展。
- 醇>
将用户模式APC排队到新线程以执行用户模式 线程启动例程 Ntdll.dll里面的LdrInitializeThunk。