是否有可能杀死 C++ Windows XP 上的应用程序无需展开调用堆栈?
我的理解是,当您在 Windows XP 中通过任务管理器终止 C++ 应用程序时,该应用程序仍然“干净”地被破坏 - 即调用堆栈将展开并且所有相关的对象析构函数将被调用。不知道我的理解是否有误。
是否可以立即终止这样的应用程序而不展开堆栈?
例如,应用程序可以采用 RAII 模式,当对象被破坏时,该模式将破坏或释放资源。如果通过任务管理器的传统“终止进程”是正常的,那么提供一种立即终止应用程序的方法将允许我测试非正常关闭(例如断电)。
编辑:
澄清一下,我正在寻找一个可以让我做到这一点的现有实用程序或程序。我应该能够在没有源代码的程序上使用该解决方案,这意味着编程解决方案实际上是不可接受的。
编辑:
只是为了提供更多背景信息,有时我必须使用非常具有侵入性的第三方服务(例如,每小时催促我重新启动)。因为我知道我不需要重新启动,所以我想终止进程/服务,这样它就不会再困扰我了。不幸的是,一些 3rd 方开发人员非常“聪明”,足以阻止我这样做,当我通过任务管理器终止该进程时,系统将立即重新启动(我猜测他们正在使用 RAII 来实现此目的)。
My understanding is that when you kill a C++ application through Task Manager in Windows XP, the application is still "cleanly" destructed - i.e. the call stack will unwind and all the relevant object destructors will be invoked. Not sure if my understanding is wrong here.
Is it possible to kill such an application immediately, without unwinding the stack?
For example, the application may employ RAII patterns which will destroy or release resources when an object is destructed. If the traditional "kill process" through Task Manager is graceful, providing a way to kill the application immediately would allow me to test ungraceful shutdown (e.g. a power outage).
Edit:
Just to clarify, I was after an existing utility or program that would allow me to do this. I should be able to use the solution on programs that I don't have the source code for, meaning that a programmatic solution is not really acceptable.
Edit:
Just to provide more context, sometimes I have to work with 3rd party services which are very intrusive (e.g. nagging me to reboot every hour). Since I know that I don't need to reboot, I want to kill the process/service so it doesn't nag me anymore. Unfortunately some of the 3rd party developers were "smart" enough to prevent me from doing this, and when I kill the process through Task Manager, the system will reboot immediately (I'm guessing that are using RAII to achieve this).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
我相信任务管理器通过发送 WM_CLOSE 消息来尝试“正常”关闭,然后如果应用程序没有响应,它就会被终止。
此调用应立即终止进程,且不发出警告:
TerminateProcess< /a>
例如:
更新:
您可能会发现这篇文章很有趣:
退出时间:退出 C++ 程序
更新2:
嗯,这在 99.9% 的情况下都是不良行为。
SysInternals 有一个名为
pskill
的实用程序:http://technet .microsoft.com/en-us/sysinternals/bb896683.aspx
但我不确定它有多“好”。
您可能需要自己动手,但这应该很简单:
I believe task manager tries a "nice" shutdown by sending a WM_CLOSE message, then if the application doesn't respond it's killed.
This call should kill the process immediately with no warning:
TerminateProcess
e.g.:
Update:
You may find this article interesting:
Quitting time: exiting a C++ program
Update 2:
Hmm, well this is undesirable behavior 99.9% of the time.
SysInternals has a utility called
pskill
:http://technet.microsoft.com/en-us/sysinternals/bb896683.aspx
but I'm not sure how "nice" it is.
You might need to roll your own, but it should be pretty easy:
执行此操作的标准 Windows 方法(不依赖第 3 方工具)是使用
taskkill /f
:/f
在此表示“强制”,并确保该进程是立即无条件终止,没有任何询问或警告。The standard Windows way to do this, without relying on 3rd-party tools, is to use
taskkill /f
:/f
means "force" here, and ensures that process is terminated unconditionally and immediately, with no query or warning.除非我犯了很大的错误(我只是做了一些测试来确认),否则任务管理器会尝试根据您使用的选项卡以不同的方式关闭程序。如果浏览“应用程序”选项卡并按“结束任务”,它将尝试通过首先发送 WM_CLOSE 彻底关闭程序。但是,如果浏览“进程”选项卡并按“结束进程”,它似乎使用了类似于 TerminateProcess 的东西,这意味着没有堆栈展开等。
因此,首先,如果您没有在“进程”选项卡上使用“结束进程”,请尝试一下。
如果这就是您已经尝试过的方法,并且他们的软件仍然设法以某种方式重新启动系统,那么就会发生更复杂的事情。其他人可能对额外流程的看法是正确的。
Unless I'm terribly mistaken (and I just did a little testing to confirm), Task Manager tries to close programs in different ways depending on which tab you're using. If going through the Applications tab and pressing End Task, it will try to close the program cleanly by first sending a WM_CLOSE. But if going through the Processes tab and pressing End Process, it seems to use something along the lines of TerminateProcess, which means no stack unwinding and such.
So first, if you aren't using End Process on the Processes tab, try that.
If that's what you already tried and their software still manages to reboot the system somehow, then there is something more complicated going on. Other people may be on the right track about there being additional processes.
我相信 C 标准库方法 exit(0); 会做到这一点,中止程序而不调用任何析构函数、解除分配器等。
尝试一下,让我知道它是否满足您的需求?
I believe the C standard library method exit(0); will do exactly that, abort the program without calling any destructors, deallocators, etc.
Try that, and let me know if it meets your needs?
看起来 abort() 会给你一个异常退出。
和
It looks like abort() will give you an abnormal exit.
and
我会按照 蒂姆以上。我猜这也会失败。如果第 3 方服务确实认真地避免死亡,那么服务定义可以设置为“崩溃时重新启动”。另一种常见的方法是使用另一种服务来监视主要服务。主服务通常设置全局事件或采用看门狗服务监视的某些其他通知机制。如果主服务未通知看门狗,则看门狗将重新启动计算机。
I would try PSKill as suggested by Tim above. I would guess that this will fail as well. If the 3rd party services are really serious about avoiding death, then the service definition may be set to "reboot on crash". The other common approach is to have another service that watchdogs the primary one. The primary service usually sets a global event or employs some other notification mechanism that the watchdog service watches. If the primary service doesn't notify the watchdog, then the watchdog restarts the computer.
恰如其分的
Kill Tool
,可从 Microsoft 下载获得。也是 Windbg 套件的一部分。例如,
kill /f lsass
(开玩笑,不要杀死 LSA!)。如果您想自己动手,TerminateProcess 就是您的最佳选择。
The aptly named
Kill Tool
, available from Microsoft Download. Is part of the Windbg suite also.For example,
kill /f lsass
(just kidding, do not kill LSA!).If you want to roll your own, TerminateProcess is the way to go.
标准库中的 C 函数 abort() 将立即终止您的应用程序,无需清理。
C++定义了一个标准的全局函数terminate()。调用它也会立即退出您的应用程序。
从技术上讲,terminate() 的行为可以被 set_terminate 函数覆盖。它默认调用 abort。
The C function abort() in the standard library will instantly kill your application with no cleanup.
C++ defines a standard global function terminate(). Calling it will also instantly exit your application.
Technically terminate()'s behavior could be overridden by the set_terminate function. It calls abort by default.
周围有一些实用程序可以禁止重新启动。
例如, HideToolz 就是这样做的——有一个复选框埋在某处会让它询问您何时启动重新启动。它被许多防病毒软件检测为 Rootkit(确实如此,但这一款据说很温和),因此在您无法完全控制的系统上运行可能会存在问题(当防病毒软件由域策略强制执行时等)
There are utilities around that can forbid reboot.
HideToolz does that for example -- there is a checkbox buried somewhere that will make it ask you when something initiates reboot. It is detected by many antiviruses as rootkit (which it is, but this one is supposedly tame), so it might be probematic to run on systems you don't have full control over (when antivirus mandated by domain policy, etc)
扩展 Pavel 的答案:
Extending Pavel's answer: