Можно ли убить приложение C ++ в Windows XP, не раскручивая стек вызовов? - PullRequest
2 голосов
/ 26 августа 2009

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

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

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

Edit:

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

Edit:

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

Ответы [ 9 ]

8 голосов
/ 26 августа 2009

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

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

TerminateProcess

например:.

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));
2 голосов
/ 26 августа 2009

Если я не ошибаюсь (и я только что провёл небольшое тестирование для подтверждения), диспетчер задач пытается закрыть программы по-разному, в зависимости от того, какую вкладку вы используете. Если вы перейдете на вкладку «Приложения» и нажмете «Завершить задачу», она попытается аккуратно закрыть программу, сначала отправив WM_CLOSE. Но если перейти на вкладку «Процессы» и нажать «Завершить процесс», она, похоже, использует что-то вроде TerminateProcess, что означает отсутствие разматывания стека и тому подобное.

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

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

2 голосов
/ 26 августа 2009

Стандартный способ Windows сделать это, не полагаясь на сторонние инструменты, это использовать taskkill /f:

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

/f означает здесь «форсировать» и гарантирует, что процесс завершается безоговорочно и немедленно, без запроса или предупреждения.

0 голосов
/ 26 августа 2009

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

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

0 голосов
/ 26 августа 2009

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

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

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

0 голосов
/ 26 августа 2009

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

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

kill /f <process>

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

0 голосов
/ 26 августа 2009

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

0 голосов
/ 26 августа 2009

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

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

и

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

0 голосов
/ 26 августа 2009

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

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

...