# Понятие веса фаззера ###### tags: `weight` Файл реализации - [`fuzzer_and_job_weights.py`](https://github.com/google/clusterfuzz/blob/master/src/appengine/handlers/cron/fuzzer_and_job_weights.py) Для выбора следующего фаззера для запуска используется его *вес* (weight). Вес принимает значения от 0 и более, где нулевой вес означает минимальное время для фаззинга. Для новых фаззеров `weight=5`, для обычных `weight=1` Метрики фаззеров, а также их веса хранятся в БД. На изменение веса влияют спецификации (содержат правила для корректиовки работы фаззера). Логика: - Новые фаззеры создаются с большим весом. Это для того, чтобы собрать с них побольше метрик. - Ко всем фаззерам периодически применяются правила спецификаций. Если фаззер содержит косяки или фигово фаззит, то у него будет уменьшаться квота на выполнение. - Если фаззер не попал ни под одно правило корректировки, то ему устанавливается `weight=1`. С точки зрения спецификаций он идеален, и штрафы к нему применяться больше не будут. Примеры спецификаций (libfuzzer): - COVERAGE_UNCHANGED_SPECIFICATION - CRASH_SPECIFICATION - NEW_FUZZER_SPECIFICATION - OOM_SPECIFICATION - SLOW_UNIT_SPECIFICATION - STARTUP_CRASH_SPECIFICATION - TIMEOUT_SPECIFICATION Каждая спецификация описывает ситуации, при возникновении которых необходимо изменить вес (квоту) фаззера. Новые веса подсчитываются прямо в запросах sql. Ниже перечислены возможные спецификации для фаззеров. ### Спецификации для новых фаззеров При создании фаззера ему присваивается `new_weight=5.0`. Сначала надо дать фаззеру большой вес, чтобы он работал подольше остальных. После этого можно вычислить адекватный вес для этого фаззера > New fuzzers/jobs should run much more frequently than others. In this case, we test the fraction of days for which we have no stats for this fuzzer/job pair and increase if it's nonzero. ### Спецификации для уже запущенных фаззеров (1 день) Для фаззеров, отработавших 24 часа, вычисляются новые веса. Для рассчёта нового веса используется следующая формула: ``` new_weight = 1.0 - (1.0 - min_weight) * AVG(field_name) ``` Здесь `min_weight` характеризует величину уменьшения веса. Чем она меньше, тем больше времени отнимается у фаззера. `AVG(field_name)` - среднее значение поля `field_name` в колонке. Название поля `field_name` различается в разных спецификациях. #### Уменьшение квоты при частых падениях фаззера на старте ```python= field_name='startup_crash_count' min_weight=0.10 ``` Если фаззер часто падал на старте, то он фиговый. Отнимаем у него много времени, чтобы люди это заметили и пофиксили его. > Heavily reduce the weight for fuzzers which frequently crash on startup. This is indicitave of a very serious problem that makes it highly unlikely that we'll find anything during fuzzing. #### Уменьшение квоты для фаззеров медленными юнитами 1. Малое количество запусков в секунду (сколько?) 2. Резкое снижение скорости запусков относительно предыдущего замера (сколько процентов?) ```python= field_name='slow_unit_count' min_weight=0.25 ``` > Reduce weight somewhat for fuzzers with many slow units. If a particular unit runs for so long that we detect it as a slow unit, it usually means that the fuzzer is not making good use of its cycles while running or needs a fix. #### Уменьшение квоты для фаззеров с частыми таймаутами Если произошёл таймаут, то убавить вес фаззеру ```python= field_name='timeout_count' min_weight=0.25 ``` Что-то похожее на спецификацию медленных юнитов, только с timeouts > This should end up being very similar to the slow unit specification, and is included for the same reason. #### Уменьшение квоты для фаззеров с большим потреблением памяти Необходимо отличать баги, связанные с OOM, от утечек в памяти фазера. Парсить логи каждого запуска ```python= field_name='oom_count' min_weight=0.25 ``` Если у фаззера часто возникают OOM (Out-of-memory), то это значит, что в фаззере могут быть утечки и другие нехорошие штуки. Уменьшаем квоту, ждем когда пофиксят > Fuzzers with extremely frequent OOMs may contain leaks or other issues that signal that they need some improvement. Run with a slightly reduced weight until the issues are fixed. #### Уменьшение квоты для фаззеров с частыми крешами Сколько крешей есть много. Что значит часто? Лимит на день, на час ```python= field_name='crash_count' min_weight=0.50 ``` Если фаззер часто находит креши, то он не тратит всё своё время на фаззинг (увеличение покрытия). Пусть лучше он уступит время другим, пока люди не заделают огромную дырку, найденную им. Это правило отнимает не так много времени, поскольку хороший фаззер должен находить какие-то баги > Fuzzers which are crashing frequently may not be making full use of their allotted time for fuzzing, and may end up being more effective once the known issues are fixed. This rule is more lenient than some of the others as even healthy fuzzers are expected to have some crashes. ### Спецификации для уже запущенных фаззеров (1 неделя) Когда проходит неделя, фаззерам назвачаются новые веса в соотвествтии с изменением их покрытия кода. > Format to query for fuzzers with minimal change in week to week coverage. Алгоритм: 1. Составить пары фаззеров `<recent, older>` (Текущие показатели и показатели с прошлой недели) 2. Вычислить `cov=edges_coverage/edges_total` для `older` и `recent` (Отношение исследованных ветвей к их общему количеству) 3. Удалить все `cov==1.0` 4. Если `|recent_cov-older_cov| < 0.01`, то назначить фаззеру `new_weight=0.75`