簡體   English   中英

是否有可能在不松開調用堆棧的情況下終止Windows XP上的C ++應用程序?

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

我的理解是,當您通過Windows XP中的任務管理器終止C ++應用程序時,應用程序仍然“干凈地”被破壞 - 即調用堆棧將展開並且將調用所有相關的對象析構函數。 不確定我的理解是不是錯了。

是否有可能立即殺死這樣的應用程序,而無需展開堆棧?

例如,應用程序可以使用RAII模式,當對象被破壞時,RAII模式將破壞或釋放資源。 如果通過任務管理器的傳統“終止進程”是優雅的,提供一種立即終止應用程序的方法將允許我測試非正常關閉(例如斷電)。

編輯:

只是為了澄清,我正在使用現有的實用程序或程序來允許我這樣做。 我應該能夠在我沒有源代碼的程序上使用該解決方案,這意味着程序化解決方案不是真的可以接受。

編輯:

只是為了提供更多的上下文,有時我必須使用非常具有干擾性的第三方服務(例如,每隔一小時嘮叨我就重新啟動)。 因為我知道我不需要重新啟動,所以我想殺死進程/服務,所以它不再惹惱我了。 不幸的是,一些第三方開發人員“聰明”足以阻止我這樣做,當我通過任務管理器終止進程時,系統將立即重啟(我猜這是使用RAII來實現這一點)。

我相信任務管理器通過發送WM_CLOSE消息嘗試“好”關閉,然后如果應用程序沒有響應它就被殺死了。

此調用應立即終止進程而不發出警告:

了TerminateProcess

例如:

TerminateProcess(GetCurrentProcess(), 1);

更新:

您可能會發現這篇文章很有趣:

退出時間:退出C ++程序

更新2:

我應該能夠在我沒有源代碼的程序上使用該解決方案

嗯,這是99.9%的時間不良行為。

pskill有一個名為pskill的實用程序:

http://technet.microsoft.com/en-us/sysinternals/bb896683.aspx

但我不確定它是多么“好”。

你可能需要自己動手,但它應該很簡單:

DWORD pid = <get pid from command line>;

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

不依賴第三方工具的標准Windows方法是使用taskkill /f

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

/f在這里表示“強制”,並確保無條件且立即終止進程,無需查詢或警告。

除非我非常錯誤(我只是做了一些測試以確認),任務管理器會嘗試以不同的方式關閉程序,具體取決於您使用的是哪個選項卡。 如果通過“應用程序”選項卡並按“結束任務”,它將嘗試通過首先發送WM_CLOSE來干凈地關閉程序。 但是如果通過Processes選項卡並按End Process,它似乎使用了TerminateProcess的內容,這意味着沒有堆棧展開等等。

首先,如果您沒有在“進程”選項卡上使用“結束進程”,請嘗試這樣做。

如果那是你已經嘗試過的,而且他們的軟件仍然設法以某種方式重新啟動系統,那么就會發生更復雜的事情。 其他人可能在正確的軌道上有關於其他進程。

我相信C標准庫方法退出(0); 將完全這樣做,中止程序而不調用任何析構函數,解除分配器等。

試試看,讓我知道它是否符合您的需求?

看起來abort()會給你一個異常的退出。

ANSI 4.10.4.1關於打開和臨時文件的中止函數的行為中止函數不會關閉打開或臨時的文件。 它不會刷新流緩沖區[來源]

中止當前進程在程序異常終止時中止進程。 該函數生成SIGABRT信號,默認情況下會導致程序終止>將不成功的終止錯誤代碼返回給主機環境。 程序終止而不執行自動或靜態存儲持續時間對象的析構函數,並且不調用任何atexit函數。 該函數永遠不會返回其調用者。 [資源]

我會按照Tim上面的建議嘗試PSKill 我猜這也會失敗。 如果第三方服務真的非常重視避免死亡,那么服務定義可能被設置為“崩潰時重啟”。 另一種常見方法是使用另一種服務來監視主要服務。 主服務通常設置全局事件或使用監視服務監視的其他一些通知機制。 如果主服務未通知監視程序,則監視程序將重新啟動計算機。

名為Kill Tool的適當名稱,可從Microsoft下載獲得。 也是Windbg套件的一部分。

Kill工具kill.exe終止一個或多個進程及其所有線程。 此工具僅適用於在本地計算機上運行的進程。

kill /f <process>

例如, kill /f lsass (開個玩笑, 殺LSA!)。 如果你想自己動手,可以選擇TerminateProcess。

標准庫中的C函數abort()將立即終止您的應用程序而不進行清理。

C ++定義了一個標准的全局函數terminate()。 調用它也會立即退出您的應用程序。

從技術上講,set_terminate函數可以覆蓋terminate()的行為。 它默認調用abort。

有些實用程序可以禁止重啟。

HideToolz就是這樣做的 - 有一個隱藏在某個地方的復選框會讓它在你啟動重啟時詢問你。 它被許多防病毒軟件檢測為rootkit(它確實是馴服的,但這個應該是馴服的),所以在你無法完全控制的系統上運行(當域策略規定的防病毒等時)可能是探測性的

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM