Что является самым жестоким способом, которым приложение может завершить себя (Linux) - PullRequest
11 голосов
/ 19 мая 2009

Я хотел бы эмулировать принудительное отключение системы, то есть максимально приблизиться к отключению питания на уровне приложения. Мы говорим о приложении c / c ++ в Linux. Мне нужно, чтобы приложение прекратило работу.

В настоящее время я вижу несколько вариантов:

  1. вызов выход ()
  2. вызов _exit ()
  3. вызов abort ()
  4. деление на ноль или разыменование NULL.
  5. другие варианты?

Какой лучший выбор?

Частично дубликат этого вопроса

Ответы [ 14 ]

26 голосов
/ 19 мая 2009

ИМХО, наиболее близким к энергетическому насилию является запуск приложения в ВМ и включение ВМ без выключения. Во всех других случаях, когда ОС все еще работает, когда приложение завершает работу, ОС выполнит некоторую очистку, которая не произойдет при реальном отключении питания.

14 голосов
/ 19 мая 2009

На уровне приложения самое сильное, что вы можете получить, это _exit (). Деление на ноль, ошибки сегмента и т. Д. - это все сигналы, которые могут быть перехвачены - если их не захватывать, они в основном такие же, как _exit (), но могут оставить coredump в зависимости от сигнала.

Если вы действительно хотите жестко отключиться, лучшим вариантом будет отключение питания самым жестоким способом. Invoking / sbin / poweroff -fn примерно настолько близок, насколько это возможно, хотя он может выполнить некоторую очистку на аппаратном уровне при выходе.

Однако, если вы действительно хотите что-то подчеркнуть, лучше всего по-настоящему, по-настоящему отключить питание - установить какое-то программное реле с управлением на шнуре питания, а программное обеспечение отключить его. Неконтролируемая потеря энергии обернется всякими странными вещами. Например, данные на диске могут быть повреждены из-за потери питания ОЗУ перед контроллером DMA или жестким диском . Это не что-то, что вы можете протестировать с помощью чего-то другого, кроме фактического снижения мощности, в конфигурации вашего производственного оборудования, через несколько испытаний.

11 голосов
/ 19 мая 2009
kill -9

Он убивает процесс и не позволяет работать обработчикам сигналов.

7 голосов
/ 19 мая 2009

Попробуйте

raise(SIGKILL)

в процессе, или из командной строки:

kill -9 pid

где pid - это PID вашего процесса (эти два метода эквивалентны и не должны выполнять никакой очистки)

7 голосов
/ 19 мая 2009

Почему бы не остановиться? Или вызвать панику?

5 голосов
/ 19 мая 2009

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

Удаленный удлинитель может быть решением, если вам действительно нужно протестировать полный случай отказа.

2 голосов
/ 20 мая 2009

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

kill(getpid(), SIGKILL); // same as kill -9

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

2 голосов
/ 19 мая 2009

Вы можете попробовать использовать виртуальную машину. Заморозьте его, прикрутите его и посмотрите, что произойдет.

В противном случае kill -9 будет лучшим решением.

1 голос
/ 27 апреля 2011

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

Из ваших предложений

  • exit () определено как "завершать нормально, выполняя обычную очистку для завершающих процессов. " - вряд ли насильственное !

  • _exit () выполняет некоторое подмножество операций exit (), но остается «приятным» для приложения, ОС и его ресурсов.

  • abort () создает SIGABRT, и ОС может выбрать очистку некоторых ресурсов.

  • / 0, вероятно, ведет себя аналогично abort ()

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

1 голос
/ 20 мая 2009

В пределах одного запущенного процесса kill (getpid (), SIGKILL) является наиболее экстремальным, поскольку очистка невозможна.

В противном случае попробуйте ВМ или установите тест-машину на удлинитель и выключите питание, если вы проводите автоматическое тестирование.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...