简体   繁体   English

是否有可能在不松开调用堆栈的情况下终止Windows XP上的C ++应用程序?

[英]Is it possible to kill a C++ application on Windows XP without unwinding the call stack?

My understanding is that when you kill a C++ application through Task Manager in Windows XP, the application is still "cleanly" destructed - ie the call stack will unwind and all the relevant object destructors will be invoked. 我的理解是,当您通过Windows XP中的任务管理器终止C ++应用程序时,应用程序仍然“干净地”被破坏 - 即调用堆栈将展开并且将调用所有相关的对象析构函数。 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. 例如,应用程序可以使用RAII模式,当对象被破坏时,RAII模式将破坏或释放资源。 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 (eg 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 (eg 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). 不幸的是,一些第三方开发人员“聪明”足以阻止我这样做,当我通过任务管理器终止进程时,系统将立即重启(我猜这是使用RAII来实现这一点)。

I believe task manager tries a "nice" shutdown by sending a WM_CLOSE message, then if the application doesn't respond it's killed. 我相信任务管理器通过发送WM_CLOSE消息尝试“好”关闭,然后如果应用程序没有响应它就被杀死了。

This call should kill the process immediately with no warning: 此调用应立即终止进程而不发出警告:

TerminateProcess 了TerminateProcess

eg: 例如:

TerminateProcess(GetCurrentProcess(), 1);

Update: 更新:

You may find this article interesting: 您可能会发现这篇文章很有趣:

Quitting time: exiting a C++ program 退出时间:退出C ++程序

Update 2: 更新2:

I should be able to use the solution on programs that I don't have the source code for 我应该能够在我没有源代码的程序上使用该解决方案

Hmm, well this is undesirable behavior 99.9% of the time. 嗯,这是99.9%的时间不良行为。

SysInternals has a utility called pskill : pskill有一个名为pskill的实用程序:

http://technet.microsoft.com/en-us/sysinternals/bb896683.aspx 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: 你可能需要自己动手,但它应该很简单:

DWORD pid = <get pid from command line>;

TerminateProcess(OpenProcess(PROCESS_TERMINATE, FALSE, pid));

The standard Windows way to do this, without relying on 3rd-party tools, is to use taskkill /f : 不依赖第三方工具的标准Windows方法是使用taskkill /f

taskkill /f <process-id>
taskkill /f /im <process-executable-name> 

/f means "force" here, and ensures that process is terminated unconditionally and immediately, with no query or warning. /f在这里表示“强制”,并确保无条件且立即终止进程,无需查询或警告。

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. 如果通过“应用程序”选项卡并按“结束任务”,它将尝试通过首先发送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. 但是如果通过Processes选项卡并按End Process,它似乎使用了TerminateProcess的内容,这意味着没有堆栈展开等等。

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. 其他人可能在正确的轨道上有关于其他进程。

I believe the C standard library method exit(0); 我相信C标准库方法退出(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? 试试看,让我知道它是否符合您的需求?

It looks like abort() will give you an abnormal exit. 看起来abort()会给你一个异常的退出。

ANSI 4.10.4.1 The behavior of the abort function with regard to open and temporary files The abort function does not close files that are open or temporary. ANSI 4.10.4.1关于打开和临时文件的中止函数的行为中止函数不会关闭打开或临时的文件。 It does not flush stream buffers [source] 它不会刷新流缓冲区[来源]

and

Abort current process Aborts the process with an abnormal program termination. 中止当前进程在程序异常终止时中止进程。 The function generates the SIGABRT signal, which by default causes the program to terminate >returning an unsuccessful termination error code to the host environment. 该函数生成SIGABRT信号,默认情况下会导致程序终止>将不成功的终止错误代码返回给主机环境。 The program is terminated without executing destructors for objects of automatic or static storage duration, and without calling any atexit function. 程序终止而不执行自动或静态存储持续时间对象的析构函数,并且不调用任何atexit函数。 The function never returns to its caller. 该函数永远不会返回其调用者。 [source] [资源]

I would try PSKill as suggested by Tim above . 我会按照Tim上面的建议尝试PSKill 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. 如果主服务未通知监视程序,则监视程序将重新启动计算机。

The aptly named Kill Tool , available from Microsoft Download. 名为Kill Tool的适当名称,可从Microsoft下载获得。 Is part of the Windbg suite also. 也是Windbg套件的一部分。

The Kill tool, kill.exe, terminates one or more processes and all of their threads. Kill工具kill.exe终止一个或多个进程及其所有线程。 This tool works only on processes running on the local computer. 此工具仅适用于在本地计算机上运行的进程。

kill /f <process>

For example, kill /f lsass (just kidding, do not kill LSA!). 例如, kill /f lsass (开个玩笑, 杀LSA!)。 If you want to roll your own, TerminateProcess is the way to go. 如果你想自己动手,可以选择TerminateProcess。

The C function abort() in the standard library will instantly kill your application with no cleanup. 标准库中的C函数abort()将立即终止您的应用程序而不进行清理。

C++ defines a standard global function terminate(). C ++定义了一个标准的全局函数terminate()。 Calling it will also instantly exit your application. 调用它也会立即退出您的应用程序。

Technically terminate()'s behavior could be overridden by the set_terminate function. 从技术上讲,set_terminate函数可以覆盖terminate()的行为。 It calls abort by default. 它默认调用abort。

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. HideToolz就是这样做的 - 有一个隐藏在某个地方的复选框会让它在你启动重启时询问你。 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) 它被许多防病毒软件检测为rootkit(它确实是驯服的,但这个应该是驯服的),所以在你无法完全控制的系统上运行(当域策略规定的防病毒等时)可能是探测性的

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM