使用TerminateProcess时究竟有什么风险?

sha*_*oth 5 windows winapi process visual-c++

我的Win32控制台应用程序使用第三方库.退出WinMain后,全局对象破坏开始,AV发生在内部深处.我真的很想写

TerminateProcess( GetCurrentProcess(), 0 );
Run Code Online (Sandbox Code Playgroud)

在WinMain附近的某个地方.如果我这样做,应用程序将优雅地结束.

MSDN表示,这样做会损害动态链接库(DLL)维护的全局数据状态,这一点尚不清楚.我明白,如果我有一些全局对象,它的析构函数不会运行,我冒险没有最终确定数据库连接或类似的东西.我的程序中没有这样的东西.

使用TerminateProcess时究竟有什么风险?我如何确定是否可以将其用于我的目的?

Jar*_*Par 6

基于该文档和ExtiProcess,似乎主要关注的是在没有使用标志DLL_PROCESS_DETACH调用DllMain的情况下卸载DLL.

我的2cents:文档很偏执,你会破坏在DllMain + DLL_PROCESS_DETACH中运行的一些关键操作.任何依赖于维持关键状态的人都已经受到任务管理员的支配,所以我没有看到使用这个API的巨大风险.


j_r*_*ker 6

AFAIK,如果你没有做任何"花哨"(包括但不限于:创建线程,锁,数据库连接,使用COM对象),不会发生任何可怕的事情.但正如Earwicker所说,你不知道 DLL正在做什么操作系统的东西,你肯定不知道将来是否会改变,所以依赖它是非常脆弱的.

你不是很想知道为什么会发生这种访问冲突吗?它很可能是早期腐败的迹象.请至少确认该错误是由第三方库引起的,例如,通过编写与库链接但无效的程序main(),并确认这会导致同样的崩溃.


Ste*_*utt 5

通常,在与流程外部的对象进行交互时会发生不好的事情.例如,假设您有一些共享内存,您的进程将写入多个进程,并读取或写入其他进程.通常,为了同步读取和写入,使用互斥锁.如果进程中的线程已获取互斥锁并且在调用TerminatePorcess时正在进行更改,则互斥锁将被放弃,共享内存可能会处于不一致状态.

我怀疑你错过了使用其中一个第三方库.DllMain有点限制,因此库可能具有初始化和取消初始化您应该调用的函数.

  • 被选为可能导致问题的案例的一个很好的例子。在调试这个问题后,我发现问题是库并不总是调用我们的回调函数来在卸载之前执行正确的去初始化。如果没有取消初始化,静态全局对象将按照首先销毁带有对象池的堆然后尝试释放这些对象的顺序被销毁。这导致了崩溃,因为对象指针已经指向已释放的堆内存。 (2认同)