2010-11-22 4 views
51

Если я бег классических оргий forkbomb:Почему C-forkbombs не работают как bash?

:(){ :&:&};: 

моей система зависание через несколько секунд.

Я попытался написать forkbomb в C, вот код:

#include <unistd.h> 

int main() 
{ 
    while(1) { 
     fork(); 
    } 
    return 0; 
} 

Когда я запускаю его система становится менее чувствительной, но я могу убить этот процесс (даже после того, как минут), просто нажав ^C.


Приведенный выше код отличается от оригинального Баш forkbomb я отправил: это что-то подобное:

:() 
{ 
    while true 
    do 
     : 
    done 
} 

(я не проверял, не знаю, если это было бы похмелья системы).

Так что я также попытался реализовать оригинальную версию; здесь код:

#include <unistd.h> 

inline void colon(const char *path) 
{ 
    pid_t pid = fork(); 
    if(pid == 0) { 
     execl(path, path, 0); 
    } 
} 

int main(int argc, char **argv) 
{ 
    colon(argv[0]); 
    colon(argv[0]); 
    return 0; 
} 

Но все же ничего: я могу запустить его, а затем легко его убить. Это не висит моя система.


Почему?

Что такого особенного в forkbombs bash? Это потому, что bash использует намного больше памяти/процессора? Поскольку процессы bash требуют гораздо больше системных вызовов (например, для доступа к файловой системе), чем у меня?

+0

Как говорится, научные прорывы редко сопровождаются «Эврика!», Которые обычно сопровождаются «Хм, это странно». –

ответ

44

Эта программа на C крошечная, серьезно крошечная. Кроме того, fork() такая программа очень и очень эффективна. Однако интерпретатор, такой как Bash, намного дороже с точки зрения использования ОЗУ и должен постоянно обращаться к диску.

Попробуйте запустить его гораздо дольше. :)

+26

Кроме того, современные Unix-приложения, как правило, используют копирование-на-запись для виртуальной памяти. Если каждый процесс фактически не записывается в ячейку памяти, все они будут использовать одни и те же физические страницы даже после 'exec'. Поместите несколько случайных mallocs и запишите в malloced память. Я думаю, что это убьет машину. – JeremyP

+0

Да, я уже процитировал эти вещи, но какие из них являются теми, кто висит в системе и почему? Если для любого процесса, который я создаю, я выделяю 1 Мб памяти в куче/стеке, будет ли она зависать моя система? Или, если какой-либо процесс выполняет 1 секунду интенсивного расчета? Или если какой-либо процесс вызывает некоторые системные вызовы? – peoro

+3

@peoro: Технически вы этого не сделали. Я был не в том, что каждый новый процесс использует небольшую память, но фактически не использует лишнюю память (кроме структур ядра). Когда вы делаете вилку, дочерний процесс использует точно такие же физические страницы, что и родительский, до тех пор, пока не запишет что-нибудь в память. Даже с exec исполняемое изображение является общим. Будет создана новая страница стека, но большой убийца производительности будет заменен, и это не произойдет, если вы не выполните некоторые записи. – JeremyP

3

В вашей bash forkbomb вы помещаете новые процессы в новые группы фонового процесса, так что вы не сможете получить их ^C.

0

В основном из-за размера. Когда вы запускаете бомбу fork fork, она загружает в память большие программы-монстры (по отношению к вашей c-программе), каждый из которых начинает болеть за ваши ресурсы процессора. Конечно, когда большие монстры начинают воспроизводить проблемы, происходит быстрее, чем если пчелы начинают делать одна и та же. Итак, компьютер зависает немедленно. Однако, если вы продолжите выполнение исполняемого файла c долгое время, он также повесит систему. Просто, что время будет намного больше. Если вы хотите сравнить размер bash с размером c программы check/proc // status. первого с ВЗОМТ из любого запущенного экземпляра Баша, а затем с ВЗОМТ из любого запущенного экземпляра С Программой

3

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

Я еще не придумал реализацию C-forkbomb, которая отделяет дочерние процессы, чтобы они не были убиты, если родитель умирает. Ссылки на такие реализации будут оценены.

Смежные вопросы