Можно ли завершить приложение C++ в Windows XP, не раскручивая стек вызовов?

StackOverflow https://stackoverflow.com/questions/1331954

Вопрос

Насколько я понимаю, когда вы завершаете приложение C++ через диспетчер задач в Windows XP, приложение все равно «чисто» уничтожается, т.е.стек вызовов будет развернут и будут вызваны все соответствующие деструкторы объектов.Не уверен, что мое понимание здесь неверно.

Можно ли убить такое приложение сразу, не раскручивая стек?

Например, приложение может использовать шаблоны RAII, которые уничтожают или освобождают ресурсы при разрушении объекта.Если традиционный «процесс уничтожения» через диспетчер задач является изящным, он дает возможность завершить приложение. немедленно позволит мне протестировать некорректное завершение работы (например.отключение электроэнергии).

Редактировать:

Просто чтобы уточнить: мне нужна была существующая утилита или программа, которая позволила бы мне это сделать.Я должен иметь возможность использовать это решение в программах, исходного кода которых у меня нет, а это означает, что программное решение на самом деле неприемлемо.

Редактировать:

Просто чтобы предоставить больше контекста, иногда мне приходится работать со сторонними сервисами, которые очень навязчивы (например,заставляет меня перезагружаться каждый час).Поскольку я знаю, что я не нуждаться для перезагрузки я хочу завершить процесс/службу, чтобы он меня больше не беспокоил.К сожалению, некоторые сторонние разработчики были достаточно «умны», чтобы помешать мне сделать это, и когда я завершаю процесс через диспетчер задач, система немедленно перезагрузится (я предполагаю, что для этого используется RAII).

Это было полезно?

Решение

Я считаю, что диспетчер задач пытается «хорошее» завершение работы, отправляя сообщение WM_CLOSE, а затем, если приложение не отвечает, оно закрывается.

Этот вызов должен немедленно завершить процесс без предупреждения:

Прервать процесс

например.:

TerminateProcess(GetCurrentProcess(), 1);

Обновлять:

Возможно, вам будет интересна эта статья:

Время выхода:выход из программы C++

Обновление 2:

Я смогу использовать это решение в программах, для которых у меня нет исходного кода.

Хм, ну, это нежелательное поведение в 99,9% случаев.

В SysInternals есть утилита под названием 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.Но если перейти на вкладку «Процессы» и нажать «Завершить процесс», кажется, что используется что-то вроде TerminateProcess, что означает отсутствие раскручивания стека и тому подобного.

Итак, сначала, если вы не используете «Завершить процесс» на вкладке «Процессы», попробуйте это.

Если это то, что вы уже пробовали, и их программному обеспечению все же удается каким-то образом перезагрузить систему, то происходит что-то более сложное.Другие люди могут быть на правильном пути относительно наличия дополнительных процессов.

Я считаю, что метод стандартной библиотеки C выход (0); сделает именно это, прервет программу без вызова каких-либо деструкторов, освободителей и т. д.

Попробуйте это и дайте мне знать, соответствует ли это вашим потребностям?

Похоже, что abort() даст вам ненормальный выход.

ANSI 4.10.4.1. Поведение функции Abort в отношении открытых и временных файлов Функция Abort не закрывает файлы, которые являются открытыми или временными.Он не промывает буферы потока [источник]

и

Прерывание текущего процесса прерывает процесс с аномальным прекращением программы.Функция генерирует сигнал SIGABRT, который по умолчанию приводит к завершению программы > возвращая код ошибки неудачного завершения в среду хоста.Программа прекращается без выполнения деструкторов для объектов автоматического или статического хранения и без вызова функции Atexit.Функция никогда не возвращается к вызывающему объекту. [источник]

я бы попробовал PSKill как было предложено Тим выше.Я предполагаю, что это тоже потерпит неудачу.Если сторонние службы действительно серьезно относятся к предотвращению смерти, то в определении службы может быть установлено значение «перезагрузка при сбое».Другой распространенный подход — создать еще один сервис, который сторожевые собаки первичный.Основная служба обычно устанавливает глобальное событие или использует какой-либо другой механизм уведомления, за которым следит служба наблюдения.Если основная служба не уведомляет сторожевой таймер, сторожевой таймер перезагружает компьютер.

Точно названный Kill Tool, доступный на сайте Microsoft Download.Также является частью пакета Windbg.

Инструмент убийства, kill.exe, завершает один или несколько процессов и все их потоки.Этот инструмент работает только на процессах, работающих на локальном компьютере.

kill /f <process>

Например, kill /f lsass (шучу, делай нет убить ЛСА!).Если вы хотите создать свой собственный, вам подойдет TerminateProcess.

Функция C abort() в стандартной библиотеке мгновенно завершит ваше приложение без очистки.

В C++ определена стандартная глобальная функция завершения().Вызов также мгновенно закроет ваше приложение.

Технически поведение Terminate() может быть переопределено функцией set_terminate.По умолчанию он вызывает отмену.

Есть утилиты, которые могут запретить перезагрузку.

HideToolz например, делает это - где-то спрятан флажок, который заставит вас спросить, когда что-то инициирует перезагрузку.Многие антивирусы распознают его как руткит (так оно и есть, но этот предположительно ручной), поэтому может быть проблематично запускать его в системах, над которыми вы не имеете полного контроля (когда антивирус требуется политикой домена и т. д.).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top