Какой самый жестокий способ, которым приложение может завершать себя (linux)

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

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

  • вызов exit()
  • вызов _ exit()
  • вызов abort()
  • выполнить деление на ноль или разыменовать NULL.
  • другие параметры?

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

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

Ответ 1

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

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

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

Ответ 2

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

Ответ 3

kill -9

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

Ответ 4

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

Ответ 5

Try

raise(SIGKILL)

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

kill -9 pid

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

Ответ 6

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

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

Ответ 7

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

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

Ответ 8

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

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

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

Ответ 9

У меня были регрессионные тесты, которые мы выполняли, когда мы переключали переключатель питания в положение OFF. Выполняя диск IO.

Не удалось восстановить позже, ну: неудача.

Вы можете купить такую ​​надежность: обычно вам нужен "сертификат конечного пользователя".

Вы можете попасть в программное обеспечение, поговорив (грязно) с вашим ИБП. UPS APC, безусловно, отключится от программного обеспечения!

Кто говорит, что системы не могут самостоятельно задействовать цикл?

Ответ 10

Бесконечная рекурсия должна заканчиваться из пространства стека (если нет, убийца OOM завершит задание):

void a() { a(); }

Взрывная бомба (если у приложения нет ограничений на вилку, тогда убийца OOM должен убить приложение в какой-то момент):

  while(1)
    fork();

Недостаточно памяти:

  while(1)
    malloc(1);

Ответ 11

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

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

Ответ 12

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

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

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

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

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

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

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

Ответ 13

Как указано, попробуйте использовать как можно больше ресурсов, пока ядро ​​не убьет вас:

while(1)
    {
    malloc(1);
    fork();
    }

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

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

Ответ 14

В недавней системе процесс с привилегиями суперпользователя мог принимать приоритет CPU/IO в реальном времени, блокировать всю адресную память, выворачивать мусор через /proc, /dev, /sys, LAN/WiFi, прошивку ioctls и flash памяти одновременно, разгонять/перенапрягать CPU/GPU/RAM и иметь хорошие шансы на выход из-за чего-то рядом с Halt and Catch Fire.

Если процесс требует только метафорического насилия, он может остановиться на /proc/sysrq-trigger.