Как стать автором
Обновить

CodeChecker: анализируем большой проект на С++ быстро, эффективно и бесплатно

Время на прочтение8 мин
Количество просмотров8K
Всего голосов 37: ↑37 и ↓0+52
Комментарии10

Комментарии 10

есть большой проект на более 100 000 строк

работает — не трогай

Зачем в итоге понадобилось что-то "анализировать"? Оно работать перестало?

работает — не трогай

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

работает - не трогай

))

Но ведь этот принцип "осуждается" в статье.

за самим проектом на правах легаси особо никто не следил: работает — не трогай


Никто не следил за проектом, так как все жили по правилу "работает - не трогай", а надо бы и за легаси кодом последить. Вот и решили анализировать.

Вообще, на такие вещи, как отсутствие break, компиляторы без всяких анализаторов вполне себе ругаться умеют -- надо лишь компилировать со всеми предупреждениями, превращёнными в ошибки (что, естественно, не отменяет пользу от анализаторов -- но не для таких элементарных ошибок, как мне кажется)

В команде проекта джун, мидл, лид и архитектор.
Произошёл баг на проде. Джун, не раздумывая, сразу полез в код чинить, думает, 
что сейчас всё быстренько поправит. Мидл сидит рядом, смотрит на это дело, но 
пальцем не шевелит — у него кофе и отпуск на носу. Лид смотрит логи.
Архитектор, заходя в комнату, видит это безобразие, медленно поднимает бровь
и спокойно спрашивает: — "И нафига ты туда полез?"
Джун, слегка нервничая: — "Ну... я подумал..."
Архитектор, улыбнувшись: — "Вот когда начнёшь думать, тогда и полезешь."

Не знаю правильно ли поступаю, но делаю так. Если нужен статический анализатор — PVS и clang-tidy без вариантов. Чтобы отловить ошибки памяти, использую address sanitizer

target_compile_options(${PROJECT_NAME}_compiler_flags_c INTERFACE  "$<${gcc_like_c}:$<BUILD_INTERFACE:-fsanitize=address>>"
)
target_compile_options(${PROJECT_NAME}_compiler_flags_cxx INTERFACE  "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-fsanitize=address>>"
)
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address")

Чтобы он нормально выводил текст, а не адреса, прямо в main пишу

#ifndef __has_feature
// GCC does not have __has_feature...
#define __has_feature(feature) 0
#endif
#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
#ifdef __cplusplus
extern "C"
#endif
const char *__asan_default_options() {  // Clang reports ODR Violation errors in mbedtls/library/certs.c.  // NEED TO REPORT THIS ISSUE  return "symbolize=1:detect_stack_use_after_return=1:external_symbolizer_path=/usr/bin/llvm-symbolizer";
}
const char *__lsan_default_options() {  // Clang reports ODR Violation errors in mbedtls/library/certs.c.  // NEED TO REPORT THIS ISSUE  return "verbosity=1:log_threads=1:fast_unwind_on_malloc=0";
}
#endif

Вполне рабочий вариант, но не работает под отладкой. Может кто подскажет что не так?

Код почему-то съехал

#ifndef __has_feature
// GCC does not have __has_feature...
#define __has_feature(feature) 0
#endif

#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
#ifdef __cplusplus
extern "C"
#endif
const char *__asan_default_options() {
  // Clang reports ODR Violation errors in mbedtls/library/certs.c.
  // NEED TO REPORT THIS ISSUE
  return "symbolize=1:detect_stack_use_after_return=1:external_symbolizer_path=/usr/bin/llvm-symbolizer";

}
const char *__lsan_default_options() {
  // Clang reports ODR Violation errors in mbedtls/library/certs.c.
  // NEED TO REPORT THIS ISSUE
  return "verbosity=1:log_threads=1:fast_unwind_on_malloc=0";
}
#endif

Пишите что Clang Static Analyzer позволяет находить дедлоки, но, кажется, что это неправда. Не увидел подходящих чекеров там. Написал даже тривиальное приложение которое приводит к дедлоку, но ни один статический анализатор (clangsa, clang-tidy и cppcheck) не смог найти проблему. Или, может быть, есть какие-то секретные флаги для Clang Static Analyzer? Ну и вопрос в зал - есть ли вообще возможность используя только статический анализатор (а не санитайзер) найти дедлоки? Какие инструменты для этого используете?

P.S. --enable-all для clangsa пробовал, конечно.
P.P.S. Да-да, я знаю про то что не надо писать код с дедлоками и как его писать правильно.

Чекер на дедлоки у Clang SA действительно сырой (из группы alpha, она как раз не подключается при --enable-all, поэтому не сработало). Но дедлоки он замечает, зачастую связанные с повторным lock уже залоченного мьютекса. Включить чекер можно либо подключив группу alpha, либо его самого напрямую (--enable=alpha или --enable=alpha.unix.PthreadLock).

Зарегистрируйтесь на Хабре, чтобы оставить комментарий