Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从exe入口点返回不会终止Windows 10上的进程 我的尝试_C++_Windows_Threadpool_Main_Exit - Fatal编程技术网

C++ 从exe入口点返回不会终止Windows 10上的进程 我的尝试

C++ 从exe入口点返回不会终止Windows 10上的进程 我的尝试,c++,windows,threadpool,main,exit,C++,Windows,Threadpool,Main,Exit,通过指定/GS-编译器标志和/NoDefaultLib链接器标志,并命名主函数mainCRTStartup,我使用Microsoft Visual Studio创建了一个最小的、无CRT的、依赖性耗尽的可执行文件。应用程序不会创建额外的线程,并在

通过指定
/GS-
编译器标志和
/NoDefaultLib
链接器标志,并命名主函数
mainCRTStartup
,我使用Microsoft Visual Studio创建了一个最小的、无CRT的、依赖性耗尽的可执行文件。应用程序不会创建额外的线程,并在<5秒后从
mainCRTStartup
返回,但进程终止总共需要30秒

问题描述 根据我的经验,如果在Windows 10上执行的应用程序只依赖于默认情况下加载到每个Windows进程中的动态库,则通常是
ntdll.dll
KernelBase.dll
kernel32.dll
,当主线程从
mainCRTStartup
函数返回时,进程正常退出

如果静态或动态加载了其他库(例如通过调用),则从主函数返回将使进程保持活动状态:正常运行时保持30秒,在调试器下运行时保持无限期

上下文 在创建进程时,Windows 10进程加载器会创建更多线程以更快地加载动态库,请参阅:

赛伦斯在书中提到:

工作线程空闲超时设置为30秒。由于
ntdll,在30秒内执行的程序将出现挂起!TppWorkerThreadwaiting
等待进程终止前的空闲超时

微软提到:

请注意,如果进程的主线程返回,C运行时库(CRT)的某些实现将调用ExitProcess

另一方面,Microsoft在中提到:

请注意,从应用程序的主函数返回将导致调用
ExitProcess

测试代码 这是我使用的最小测试代码,我使用了
kernel32!关闭手柄
user32!CloseWindow
作为示例,对它们的调用实际上没有任何作用:

#包括
命名空间窗口{
typedef const intptr_t Handle;
typedef const void*模块;
constexpr Handle InvalidHandleValue=-1;
命名空间内核32{
外部“C”单元32标准球关闭手柄(手柄);
外部“C”uint32标准调用免费库(模块);
外部“C”模块-标准调用加载库W(常量wchar\u t*);
}
命名空间用户32{
外部“C”单元32标准呼叫关闭窗口(手柄);
}
}
int mainCRTStartup(){
//0秒
//windows::kernel32::CloseHandle(windows::InvalidHandleValue);
//30秒
//windows::user32::CloseWindow(windows::InvalidHandleValue);
//0秒
//windows::kernel32::FreeLibrary(windows::kernel32::LoadLibraryW(L“kernel32.dll”);
//30秒
//windows::kernel32::FreeLibrary(windows::kernel32::LoadLibraryW(L“user32.dll”);
//0秒
//windows::kernel32::FreeLibrary(windows::kernel32::LoadLibraryW(L“”);
返回0;
}
调试 在
mainCRTStartup
函数中注释WinAPI用法会导致上述各个WinAPI调用的执行时间

这是在伪C++中跟踪的程序的执行流:

ntdll.RtlUserThreadStart(){
kernel32.BaseThreadInitThunk(){
const auto return_code=test.mainCRTStartup();
ntdll.RtlExitUserThread(返回\u代码){
if(ntdll.NtQueryInformationThread(当前线程,线程AmILastThread)!=STATUS\u SUCCESS | |!AmILastThread){
//路径错误-持续“30秒”。
ntdll.LdrShutdownThread();
ntdll.TpCheckTerminateWorker(0);
ntdll.NtTerminateThread(0,返回_代码);
//线程执行不会从“NtTerminateThread”返回,但进程仍在运行。
}否则{
//良好路径-持续“0秒”。
ntdll.RtlExitUserProcess(返回\u代码){
ntdll.EtwpShutdownPrivateLoggers();
ntdll.LdrpDrainWorkQueue(0);
ntdll.LdrpAcquireLoaderLock();
ntdll.RtlEnterCriticalSection(ntdll.FastPebLock);
RtlLockHeap(peb.ProcessHeap);
ntdll.NtTerminateProcess(0,返回\u代码);
ntdll.RtlUnlockProcessHeapOnProcessTerminate();
ntdll.RtlLeaveCriticalSection(ntdll.FastPebLock);
ntdll.RtlReportSilentProcessExit(当前\u进程,返回\u代码);
ntdll.LdrShutdownProcess();
ntdll.NtTerminateProcess(当前进程,返回代码);
//线程执行不会从“NtTerminateProcess”返回,进程被终止。
}
}
}
}
}
预期结果 如果进程没有创建额外的线程并从主函数返回,我希望进程会终止

在主函数末尾调用会终止进程,即使调用了WinAPI,导致在执行前30秒执行。使用此API并不总是可能的,因为有问题的应用程序可能不是我的,而是像下面这样的第三方应用程序:

在我看来,即使是Microsoft进程的行为不正确,Windows 10进程加载器也已损坏

  • 这个问题有没有干净的解决办法
  • 如果最后一个用户创建的线程退出,那么这些加载程序线程需要做什么?抱歉,此时不可能加载任何其他库
  • 我预计,如果该过程没有创建额外的 线程并从主函数返回

    进程可以隐式创建其他线程。例如加载器。我们需要理解这意味着什么

    主功能返回

    这里指的是从标准CRT
    mainCR调用的函数