Help:Match

From Svacer Wiki

Cопоставления предупреждений

Описание алгоритма

В данной секции описывается алгоритм сопоставления предупреждений используемый Svacer для переноса разметки.

Для каждого предупреждения в снимке (snapshot) вычисляется хэшкод из полей предупреждения и исходных файлов. В терминологии Svacer хэшкод именуется инвариантом. Инвариант используется для группировки предупреждений из разных снимков в рамках одной ветки. Каждое предупреждение в рамках одного снимка имеет уникальный инвариант.

Генерация инвариантов для снимка идет по следующему алгоритму:

Шаг 1 (формируем первый, основной инвариант):

  • Пути всех файлов из предупреждений в снимке сортируются лексикографически.
  • Для каждого пути вычисляется минимально возможный не конфликтующий суффикс пути (т. е. конец пути содержащий имя файла), имеющий по крайней мере два сегмента (т. е. включающий имя директории). Для Java файлов минимальный путь учитывает имя пакета, объявленного внутри файла (при наличии package declaration внутри). Данный минимальный суффикс добавляется в хэш код инварианта.
  • В инвариант добавляются хэш коды следующих полей предупреждения: MTid (если поле пустое, то используются поля Msg, warnClass), Function, Lang, Tool. Поля Lang и Tool нормализуются, т. к. разные версии Svace могли иметь отличные именования полей.
  • Формируется хэш-код строки кода из объекта сборки. При формировании хэшкода строки все whitespace-ы игнорируются. Если объект сборки отсутствует, то используется поле details у предупреждения.
  • Если для нескольких предупреждений в снимке получился одинаковый инвариант, то конфликтующие предупреждения упорядочиваются по line и locID предупреждения (порядковый номер предупреждения в svres или sarif файле, в данном случае полагаемся на детерминизм анализатора). В инвариант добавляется индекс предупреждения в данной конфликтной группе. Таким образом получаем уникальный инвариант для каждого предупреждения в снимке.

Шаг 2 (формируем второй инвариант):

  • Пути всех файлов в снимке сортируются лексикографически.
  • Для каждого пути вычисляется минимально возможный не конфликтующий путь, содержащий по крайней мере два сегмента (т. е. включающий имя директории). Для Java файлов минимальный путь учитывает имя пакета, объявленного внутри файла (при наличии package declaration внутри). Минимальный путь добавляется в хэш код инварианта.
  • В инвариант добавляются хэш коды следующих полей предупреждения: MTid (если поле пустое, то используется поля Msg, warnClass), Function, Lang, Tool, Details (важное отличие от шага 1 — здесь используется поле Details у предупреждения). Поля Lang и Tool нормализуются, т. к. разные версии Svace могли иметь отличные именования полей.
  • Предупреждения в снимке делятся на группы по инварианту. В рамках одной группы предупреждения сортируются по Function, строке (line) и locID. Индекс предупреждения в группе добавляется к инварианту группы. Таким образом получаем уникальный инвариант для каждого предупреждения в снимке.

Шаг 3:

  • Если предупреждения на ветке (branch) попали согласно инварианту 1 в разные группы, а инварианту 2 в одну, то для данных предупреждений будет использован инвариант 2, как более строгий.

Шаг 4:

  • Проверяется, были ли ручные сопоставления предупреждений на ветке (branch) и инварианты корректируются исходя из таблицы ручных сопоставлений. При ручном сопоставлении предупреждениям назначается уникальный инвариант и запоминается информация об эквивалентности назначенного инварианта инвариантам полученным на шагах 1 и 2.

Опции сервера, влияющие на алгоритм генерации инвариантов

Отключение минимизации путей

При использовании следующей опции или соответствующей переменной окружения, механизм минимизации путей будет отключен.

--no-path-min 
env variable: SVACER_NO_PATH_MIN=true|false

Отключение шагов 2, 3

Для отключения шагов 2 и 3 необходимо использовать переменную окружения

SVACER_NO_MATCH_BY_CORE=true

ВНИМАНИЕ: данная опция не рекомендуется, т. к. нарушает совместимость с алгоритмом генерации, используемом в прежних версиях Svacer.

Ручное сопоставление предупреждений (экспериментальная возможность)

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

Для ручного сопоставления предупреждений из CLI пользователь должен использовать команду svacer marker match. Команда требует обязательной аутентификации и пользователь должен иметь права на разметку в проекте и ветке, где хочет выполнить сопоставление. Сопоставить можно предупреждения из разных снимков одной ветки. При ручном сопоставлении все предупреждения, какие эквивалентны по инвариантам первому предупреждению или второму, будут автоматически считаться эквивалентными. Одно и то же предупреждение может быть сопоставлено с множеством других предупреждений, но каждое из выбранных предупреждений должно находиться в различных снимках. Нельзя сопоставить два или более предупреждений из одного снимка одному предупреждению из другого снимка.

svacer marker match --user user --password password --host host --project project --branch branch --v1 snapshot1 --v2 snapshot2  id11=id21  id12=id22 id13=id23 

Под аргументами операции подразумеваются пары ID маркеров из снимков указанных в параметрах --v1 и --v2. Для удобства пользователя, можно использовать числовой ID маркера, который может быть получен через CLI команду

svacer marker list --host host --user user --password pwd --project project

Данная команда выдает список предупреждений в виде таблицы

#     warn                                 file                            line   review  msg                                                 
1000  INVARIANT_RESULT                     /.build/subst.c                 7080           Expression 'tl->word->flags | (1 << 21)' is always  
                                                                                          true , which may be caused by a logical error       
1001  DEREF_AFTER_NULL.LOOP                /.build/execute_cmd.c           3327           After having been compared to NULL value at execut  
                                                                                          e_cmd.c:3325, pointer 'l' is dereferenced at execu  
                                                                                          te_cmd.c:3327.                                      
1002  DEREF_AFTER_NULL.LOOP                /.build/variables.c             2749           After having been compared to NULL value at variab  
                                                                                          les.c:2656, pointer 'vc' is dereferenced at variab  
                                                                                          les.c:2749.

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

При использовании команды `svacer marker match` пользователь может указывать как имя проекта и ветки. так и их ID.

Для получения списка ручных сопоставлений пользователь должен использовать команду `svacer marker match-journal`

svacer marker match-journal --host host --user user --password password  --project project --branch branch

Формат вывода контролируется опцией --out-format и может быть json , текст (txt, default), csv.

#  v   marker                        snapshot_id                           snapshot_name  created_by  create_ts
2  v1  DEREF_OF_NULL.CONST:test.c:9  b51009b6-cdbe-463a-b324-c87143bb0372  S3             admin       Fri Mar 22 08:16:03 UTC 2024
   v2  DEREF_OF_NULL.CONST:test.c:8  8a9c4330-c131-44e1-bf09-b1d3a245b317  S1
1  v1  DEREF_OF_NULL.CONST:test.c:8  3c20cd4e-e5d9-479b-b618-7db852ed0133  S2             admin       Fri Mar 22 08:01:06 UTC 2024
   v2  DEREF_OF_NULL.CONST:test.c:8  8a9c4330-c131-44e1-bf09-b1d3a245b317  S1

Для отмены ручных сопоставлений пользователь должен использовать команду

svacer marker unapply-match --host host --user user --password password  --project project --branch branch id1 id2 id2 ...

Где id1, id2, ... - список id операций полученных командой svacer marker match-journal. Внимание: при отмене ручных сопоставлений вычисляется замыкание всех связанных сопоставлений и, далее, отменяется всё замыкание. Таким образом, если пользователь сопоставил два предупреждения, а потом одно из сопоставленных сопоставил с еще одним новым предупреждением, то при отмене первой операции будет отменена и вторая.