Поиск ошибок в проектах на основе Unreal Engine

В статическом анализаторе PVS-Studio начали появляться диагностические правила для выявления багов, специфичных для Unreal Engine проектов.

Однако без сообщества разработчиков игр здесь не обойтись.

Поиск ошибок в проектах на основе Unreal Engine

Первый пример.

Появилось диагностическое правило, анализирующее классы, не унаследованные от типа UObject. Если в таком классе есть нестатическое поле в виде указателя на тип, унаследованный от UObject, то это неправильно.

class SomeClass { .... UObject *m_ptr; .... };

Сборщик мусора Unreal Engine может уничтожить объект, адресуемый указателем m_ptr. Подробнее про это диагностическое правило: V1100.

Второй пример.

Выявляются сущности, несоответствующие соглашениям о наименованиях для проектов, основанных на Unreal Engine. Соответствие соглашениям требуется для корректной работы Unreal Header Tool:

  • Имена классов, наследуемых от UObject, следует начинать с префикса 'U';
  • Имена классов, наследуемых от AActor, следует начинать с префикса 'A';
  • Имена классов, наследуемых от SWidget, следует начинать с префикса 'S';
  • И так далее. Подробности см. в описании диагностического правила V1102 (войдёт в октябрьский релиз PVS-Studio 7.27).

Это только начало. Мы будем собирать паттерны подобных ошибок и реализовывать их выявление в анализаторе. Нюанс в том, что без помощи GameDev сообщества мы будем делать это очень медленно. Поскольку мы сами не разрабатываем игры, коллекционирование паттернов поначалу будет носить случайный характер.

Пишите в комментариях идеи по поиску багов!

4.7K4.7K показов
853853 открытия
9 комментариев

По первому примеру много вопросов:
1. Уже озвученный. Как анализатор реагирует, если класс унаследован от FGCObject?
2. А что, если унаследован, но в методе CollectReferencedObjects конкретно этот UObject не перечисляется?
3. Если класс таки унаследован от UObject, а вот объект-поле забыли пометить как UPROPERTY или использовать другие способы обозначить реф? Из опыта это гораздо более часто встречающаяся ошибка, чем приведенный вами пример

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

Ответить

Из дополнительных идей по GC. Если появилось желание уничтожить объект вручную, то офф. документация рекомендует использовать BeginDestroy. Но при этом умалчивает, что рефу на объект нужно обязательно присвоить nullptr или как-то иначе уничтожить реф на него. Иначе GC никогда не дойдет до уничтожения объекта. И если кто-то другой попытается снова сделать BeginDestroy, то получится краш.

Звучит как маловероятный сценарий, но тем не менее за последние 4 года работы с движком я постоянно сталкивался с этим. Было бы здорово, если бы такое можно было обнаружить заранее, а не в рантайме, когда имя объекта и полная информация об овнерах уже утеряна.

Ответить

1. Анализатор не ругается если класс унаследован от FGCObject.
2. Пока анализатор никак не реагирует если в методе CollectReferencedObjects, конкретно этот UObject не перечисляется, на такой случай планируется новая диагностика.
3. Также новая диагностика будет обрабатывать случай, если объект-поле унаследованного от UObject забыли пометить как UPROPERTY.
Диагностическое правило было добавлено по просьбе клиента, который хотел находить случаи, когда в классе ненаследнике от UObject есть указатель на тип, наследуемый от UObject.

Ответить

Комментарий недоступен

Ответить

Комментарий недоступен

Ответить

Вы же на Хабре раньше писали

Ответить