Как работает эта другая версия бомбы? - PullRequest
4 голосов
/ 06 декабря 2011

Я получаю общее представление о том, как эта распространенная версия

:(){ :|:& };:

бомбы, работающей на вилке, работает.

Однако я видел другую версию (в частности, для bash)

#!/bin/bash
$0 &
$0 &

в статье о вилочной бомбе *1011* Wikipedia * и в ответе SO на закрытый дубликат оригиналаВопрос о вилочной бомбе, о котором я упоминал выше.

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

#!/bin/bash    # Specifies the location of the executable
               # to use in executing this script.
$0 &           # Duplicates (executes a new instance
               # of) the current running process ('$0')
               # (which would be the invocation of bash used
               # to start running the script, right?)
               # and background it ('&').
$0 &           # Do the same as above, where $0 would be
               # equivalent to the initial call to bash
               # used to start the script, right? Or, would
               # it be the backgrounded call to bash from the
               # second line? I'm leaning towards the former.

РЕДАКТИРОВАТЬ: мое пересмотренное понимание сценария (по крайней мере на уровне абстракции, о котором я сейчас беспокоюсь) ниже в виде закомментированного кода.Я оставил свой исходный закомментированный код для будущих зрителей, которые могут иметь те же первоначальные недоразумения, что и я.Предположим, что сценарий живет в bomb.sh.

#!/bin/bash    # Script will execute using /bin/bash executable.
$0 &           # The current process (P) will spawn a child process (C1)
               # by invoking the command that spawned P
               # (/bin/bash ./bomb.sh). This makes the script recursive.
               # & allows processes to run in the background
               # (allowing process death and avoiding a potential
               # process limit).
$0 &           # Process P spawns a second child process (C2), also 
               # in the background, which gives us the exponential growth
               # (in base 2) that we want per level of recursion.

Ответы [ 3 ]

6 голосов
/ 06 декабря 2011

Если вы немного сломаете эту бомбу, это может иметь больше смысла.Измените это на:

#!/bin/bash
$0

Эта бомба будет порождать новую копию сценария оболочки снова и снова:

$ ps auxw | grep pts/2
sarnold   2410  0.0  0.1  24840  6340 pts/2    Ss   Nov17   0:01 bash
sarnold  17280  0.0  0.0  12296  1600 pts/2    S+   18:01   0:00 /bin/bash ./bomb.sh
sarnold  17281  0.0  0.0  12296  1600 pts/2    S+   18:01   0:00 /bin/bash ./bomb.sh
sarnold  17282  0.0  0.0  12296  1600 pts/2    S+   18:01   0:00 /bin/bash ./bomb.sh
sarnold  17283  0.0  0.0  12296  1596 pts/2    S+   18:01   0:00 /bin/bash ./bomb.sh
sarnold  17284  0.0  0.0  12296  1600 pts/2    S+   18:01   0:00 /bin/bash ./bomb.sh
...
$ ps auxw | grep pts/2 | wc -l
2077

Каждый старый по сути "мертв" - ожидаетпожинать статус выхода из казненного ребенка.Конечно, этого не произойдет до тех пор, пока один из выполненных потомков не сможет выполнить его из-за ограничений процесса.(Что, кстати, напоминает мне, что, возможно, установка nproc rlimit была бы хорошей идеей, прежде чем играть намного дальше.)

Так что это дерево процессов выглядит так:

1
 2
  3
   4
    5
     6

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

1
 2
  3

    5
     6

       8

Добавление строки second $0 & приведет к тому, что дерево будет выглядеть немного иначе:

           1
        2     3
      4   5 6   7

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

Каждый «слой» в целом удвоит размер предыдущего слоя, но execve(2) можно вызывать только так часто - хитрость в том, что эта бомба вероятно вызывает гораздо больше переключений контекста процесса, чем более простые бомбы, и все эти TLB сбрасывания значительно повлияют на производительность системы.Поскольку родители будут по существу случайным образом отмирать после казни обоих детей, init(8) будет иметь намного больше процессов, переизобретенных заново.Все это увеличит количество сигналов, отправляемых на init(8) для очистки, что затруднит администратору вход в систему и устранение проблемы.

2 голосов
/ 06 декабря 2011

Когда вы запускаете $0 &, Bash запускает новый процесс в фоновом режиме, который запускает этот скрипт. Вы начинаете делать это дважды. Затем каждый из этих сценариев делает это дважды, поэтому второй раунд экземпляров запускает четыре экземпляра. Следующий раунд начинается восемь, потом 16, потом 32 и т. Д.

1 голос
/ 06 декабря 2011

$0 - это переменная, содержащая самую первую часть команды, которая использовалась для вызова этого скрипта: имя и местоположение скрипта.Например, если команда, которую вы использовали для вызова скрипта, - /home/user/bin/bomb foo bar, $0 будет содержать /home/user/bin/bomb.Так что $0 & означает запустить этот же скрипт в фоновом режиме.Так как он есть в сценарии дважды, он породит 2 детей.Каждый из детей будет порождать еще 2 детей, и так далее, в геометрической прогрессии.

...