Статический анализ Си++ кодаКарпов Андрей Николаевичк.ф.-м.н., технический директорООО «Системы программной верификации»E-mail: karpov@viva64.com
О чем докладМы вседопускаем ошибки при программировании и тратим массу времени на их устранение.Один из методов который позволяет быстро диагностировать дефекты – статический анализ исходного кода.
«Надо сразу писать хороший код» - не работает на практике!даже лучшие программисты ошибаются и делают опечатки;далее - ряд примеров ошибок, обнаруженных статическим анализатором кода в известных проектах;для анализа использовался инструмент PVS-Studio.
Приоритет операций & и !ReturntoCastleWolfenstein - компьютерная игра, шутер от первого лица, разработанный компанией id Software. Движок игры распространяется по GPL лицензии.#define SVF_CASTAI  0x00000010if ( !ent->r.svFlags& SVF_CASTAI )if ( ! (ent->r.svFlags & SVF_CASTAI) )
Использование && вместо &Stickies- желтые клеящиеся бумажки, только на мониторе.#define REO_INPLACEACTIVE  (0x02000000L)#define REO_OPEN           (0x04000000L)if (reObj.dwFlags&& REO_INPLACEACTIVE)m_pRichEditOle->InPlaceDeactivate();if(reObj.dwFlags&& REO_OPEN)  hr = reObj.poleobj->Close(OLECLOSE_NOSAVE);
Undefined behaviorMiranda IM (Miranda Instant Messenger) - программа мгновенного обмена сообщениями для Microsoft Windows.while (*(n = ++s + strspn(s, EZXML_WS)) && *n != '>') {
Использование delete для массиваChromium - веб-браузер с открытым исходным кодом, разработанный компанией Google. На основе Chromium создаётся браузер GoogleChrome.auto_ptr<VARIANT> child_array(new VARIANT[child_count]);Использовать auto_ptrдля массивов нельзя. В деструкторе auto_ptrуничтожается только один элемент:~auto_ptr() {  delete _Myptr;}В качестве альтернативы, например, можно использовать boost::scoped_array.
Всегда истинное условиеWinDjView - быстрая и компактная программа для просмотра файлов формата DjVu.inline boolIsValidChar(int c){  return c == 0x9 || 0xA || c == 0xD || c >= 0x20 && c <= 0xD7FF         || c >= 0xE000 && c <= 0xFFFD || c >= 0x10000 && c <= 0x10FFFF;}
Оформление кода отличается от его логикиSquirrel - интерпретируемый язык программирования, разработанный специально для использования в качестве скриптового языка в приложениях реального времени, таких как компьютерные игры. if(pushval != 0)    if(pushval) v->GetUp(-1) = t;  else    v->Pop(1);v->Pop(1); - никогда не вызывается
Случайное объявление локальной переменнойFCE Ultra – открытый эмулятор приставки  Nintendo Entertainment SystemintiNesSaveAs(char* name){  ...fp = fopen(name,"wb");int x = 0;  if (!fp)int x = 1;  ...}
Работа с char как с unsigned char// check each line for illegal utf8 sequences.// If one is found, we treatthe file as ASCII,// otherwise we assumean UTF8 file.char * utf8CheckBuf = lineptr;while ((bUTF8)&&(*utf8CheckBuf)){  if ((*utf8CheckBuf == 0xC0)||      (*utf8CheckBuf == 0xC1)||      (*utf8CheckBuf >= 0xF5))  {    bUTF8 = false;   break;  }TortoiseSVN — клиент для системы контроля версий Subversion, выполненный как расширение оболочки Windows.
Случайные восьмеричные числаoCell._luminance = uint16(0.2220f*iPixel._red +0.7067f*iPixel._blue +0.0713f*iPixel._green);....oCell._luminance = 2220*iPixel._red +7067*iPixel._blue +0713*iPixel._green;eLynx Image Processing SDK and Lab
Одна переменная для двух цикловLugaru— первая коммерческая игра, созданная командой независимых разработчиков WolfireGames.static inti,j,k,l,m;...for(j=0; j<numrepeats; j++){  ...  for(i=0; i<num_joints; i++){    ...    for(j=0;j<num_joints;j++){      if(joints[j].locked)freely=0;    }    ...  }  ...}
Выход за границы массиваLAME - свободное приложение для кодирования аудио в формат MP3. #define SBMAX_l22int l[1+SBMAX_l]; for (r0 = 0; r0 < 16; r0++) {    ...    for (r1 = 0; r1 < 8; r1++) {      int a2 = gfc->scalefac_band.l[r0 + r1 + 2];
Приоритет операций * и ++eMule - это клиент для сети обмена файлами ED2K. STDMETHODIMP CCustomAutoComplete::Next(...,ULONG *pceltFetched){  ...  if (pceltFetched != NULL)    *pceltFetched++;  ...}(*pceltFetched)++;
Ошибка в сравненииWinMerge — свободное ПО с открытым исходным кодом для сравнения и синхронизации файлов и директорий.BUFFERTYPE m_nBufferType[2];...// Handle unnamed buffersif ((m_nBufferType[nBuffer] == BUFFER_UNNAMED) ||    (m_nBufferType[nBuffer] == BUFFER_UNNAMED))nSaveErrorCode = SAVE_NO_FILENAME;Если посмотреть код рядом, то по аналогии здесь должно быть:(m_nBufferType[0] == BUFFER_UNNAMED)  ||(m_nBufferType[1] == BUFFER_UNNAMED)
Забытый индекс массиваvoid lNormalizeVector_32f_P3IM(..., Ipp32s* mask, ...) {  Ipp32s  i;  Ipp32f  norm;  for(i=0; i<len; i++) {    if(mask<0) continue;    ...}}if(mask[i]<0) continue;IPP Samples - примеры, демонстрирующие работу с библиотекой Intel Performance Primitives Library 7.0.
Одинаковые ветви кодаNotepad++ - свободный текстовый редактор для Windows с подсветкой синтаксиса большого количества языков программирования и разметки. if (!_isVertical)    Flags |=DT_VCENTER;  else    Flags |= DT_BOTTOM;if (!_isVertical)  Flags |= DT_BOTTOM;else  Flags |= DT_BOTTOM;
Вызов неверной функции со схожим именемКакой замечательный комментарий. Жаль только не то делаем, что хотим./** Deletes all previous field specifiers.  * This should be used when dealing  * with clients that send multiple NEP_PACKET_SPEC  * messages, so only the lastPacketSpec is taken  * into account. */intNEPContext::resetClientFieldSpecs(){  this->fspecs.empty();  return OP_SUCCESS;} /* End of resetClientFieldSpecs() */Nmap Security Scanner - свободная утилита, предназначенная для разнообразного настраиваемого сканирования IP-сетей с любым количеством объектов, определения состояния объектов сканируемой сети.
Опасный оператор ?:NewtonGameDynamics- популярный физический движок, который предоставляет надежное и быстрое решение для симуляции физического поведения объектов окружающей среды. den = dgFloat32 (1.0e-24f) * (den > dgFloat32(0.0f)) ? dgFloat32(1.0f) : dgFloat32(-1.0f);Приоритет оператора ?: ниже, чем у оператора умножения *.
И так далее, и так далее…if (m_szPassword != NULL){if (m_szPassword != '\0')  {Библиотека Ultimate TCP/IPif (*m_szPassword != '\0')bleeding = 0;bleedx = 0,bleedy;direction = 0;Lugarubleedx = 0;bleedy = 0;
И так далее, и так далее…if((t=(char *)realloc(  next->name, strlen(name+1))))FCE Ultraif((t=(char *)realloc(  next->name, strlen(name)+1)))minX=max(0,minX+mcLeftStart-2);minY=max(0,minY+mcTopStart-2);maxX=min((int)width,maxX+mcRightEnd-1);maxY=min((int)height,maxX+mcBottomEnd-1);minX=max(0,minX+mcLeftStart-2);minY=max(0,minY+mcTopStart-2);maxX=min((int)width,maxX+mcRightEnd-1);maxY=min((int)height,maxY+mcBottomEnd-1);
Низкоуровневые операции работы с памятьюХочется отдельно остановиться на наследии программ на Си, где использовались функции:ZeroMemory;memset;memcpy;memcmp;…
Низкоуровневые операции работы с памятьюID_INLINE mat3_t::mat3_t( float src[3][3] ){memcpy( mat, src, sizeof( src ) );}Return to Castle WolfensteinID_INLINE mat3_t::mat3_t( float (&src)[3][3] ){memcpy( mat, src, sizeof( src ) );}itemInfo_t *itemInfo;memset( itemInfo, 0, sizeof( &itemInfo ) );memset( itemInfo, 0, sizeof( *itemInfo ) );
Низкоуровневые операции работы с памятьюCxImage - открытая библиотека обработки изображений.memset(tcmpt->stepsizes, 0,sizeof(tcmpt->numstepsizes * sizeof(uint_fast16_t)));memset(tcmpt->stepsizes, 0,tcmpt->numstepsizes * sizeof(uint_fast16_t));
Низкоуровневые операции работы с памятьюКрасивый пример 64-битной ошибки:dgInt32 faceOffsetHitogram[256];dgSubMesh* mainSegmenst[256];memset (faceOffsetHitogram, 0, sizeof (faceOffsetHitogram));memset (mainSegmenst, 0, sizeof (faceOffsetHitogram));Скопировали код и не полностью поправили. В результате в Win64 размер указателя станет не равен размеру типа dgInt32 и мы очистим только часть массива mainSegmenst.
Низкоуровневые операции работы с памятью#define CONT_MAP_MAX 50int _iContMap[CONT_MAP_MAX];...memset(_iContMap, -1, CONT_MAP_MAX);memset(_iContMap, -1, CONT_MAP_MAX * sizeof(int));
Низкоуровневые операции работы с памятьюOGRE (Object-OrientedGraphicsRenderingEngine) - объектно-ориентированный графический движок с открытым исходным кодом, написанный на C++.Real w, x, y, z;...inline Quaternion(Real* valptr){memcpy(&w, valptr, sizeof(Real)*4);}Да, сейчас это не ошибка.Но это мина!
Чем раньше – тем лучше
Почему все-таки не только юнит-тесты?проверка мест, редко получающих управления;обнаружение плавающих ошибок (undefined behavior, гейзенбаги);не на все варианты кода можно написать юнит-тест:сложные счетные алгоритмы;интерфейс.
Здесь не поможет юнит-тест, но поможет статический анализFennecMediaProject- универсальный медиа-плеер ориентированный на воспроизведение аудио и видео в высоком разрешении.OPENFILENAME  lofn;...lofn.lpstrFilter = uni("All Files (*.*)\0*.*");lofn.lpstrFilter = uni("All Files (*.*)\0*.*\0");
Здесь не поможет юнит-тест, но поможет статический анализstatic INT_PTR CALLBACK DlgProcTrayOpts(...){  ...EnableWindow(GetDlgItem(hwndDlg,IDC_PRIMARYSTATUS),TRUE);EnableWindow(GetDlgItem(hwndDlg,IDC_CYCLETIMESPIN),FALSE);EnableWindow(GetDlgItem(hwndDlg,IDC_CYCLETIME),FALSE);				EnableWindow(GetDlgItem(hwndDlg,IDC_ALWAYSPRIMARY),FALSE);EnableWindow(GetDlgItem(hwndDlg,IDC_ALWAYSPRIMARY),FALSE);EnableWindow(GetDlgItem(hwndDlg,IDC_CYCLE),FALSE);EnableWindow(GetDlgItem(hwndDlg,IDC_MULTITRAY),FALSE);  ...}
Где подробнее узнать проPVS-Studio?Страница продукта: http://www.viva64.com/ru/pvs-studio/
Демонстрационная версия: http://www.viva64.com/ru/pvs-studio-download/

More Related Content

PPTX
PVS-Studio, решение для разработки современных ресурсоемких приложений
PDF
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
PDF
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
PDF
Метапрограммирование в C++11/14 и C++17. Новые инструменты - новые проблемы.
PDF
хитрости выведения типов
PDF
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
PDF
Догнать и перегнать boost::lexical_cast
PDF
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
PVS-Studio, решение для разработки современных ресурсоемких приложений
Дмитрий Кашицын, Троллейбус из буханки: алиасинг и векторизация в LLVM
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Метапрограммирование в C++11/14 и C++17. Новые инструменты - новые проблемы.
хитрости выведения типов
ПВТ - весна 2015 - Лекция 8. Многопоточное программирование без использования...
Догнать и перегнать boost::lexical_cast
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения

What's hot (19)

PPTX
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
PDF
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
PDF
Intel IPP Samples for Windows - работа над ошибками
PPTX
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
PDF
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
PDF
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...
PDF
ПВТ - весна 2015 - Лекция 7. Модель памяти С++. Внеочередное выполнение инстр...
PDF
Модель памяти C++ - Андрей Янковский, Яндекс
PDF
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
PDF
Для чего мы делали свой акторный фреймворк и что из этого вышло?
PDF
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
PDF
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
PDF
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
PDF
Лекция 6. Стандарт OpenMP
PDF
Антон Полухин, Немного о Boost
PPTX
Евгений Зуев, С++ в России: Стандарт языка и его реализация
PDF
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
PDF
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
PDF
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...
Некоторые паттерны реализации полиморфного поведения в C++ – Дмитрий Леванов,...
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Intel IPP Samples for Windows - работа над ошибками
Использование шаблонов и RTTI для конфигурации симулятора флеш-накопителя - Г...
Лекция 7: Многопоточное программирование: часть 3 (OpenMP)
Кулагин И.И., Пазников А.А., Курносов М.Г. Оптимизация информационных обменов...
ПВТ - весна 2015 - Лекция 7. Модель памяти С++. Внеочередное выполнение инстр...
Модель памяти C++ - Андрей Янковский, Яндекс
Лекция 2. Оптимизация ветвлений и циклов (Branch prediction and loop optimiz...
Для чего мы делали свой акторный фреймворк и что из этого вышло?
ПВТ - осень 2014 - Лекция 7. Многопоточное программирование без блокировок. М...
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
ПВТ - весна 2015 - Лекция 2. POSIX Threads. Основные понятия многопоточного п...
Лекция 6. Стандарт OpenMP
Антон Полухин, Немного о Boost
Евгений Зуев, С++ в России: Стандарт языка и его реализация
ПВТ - осень 2014 - Лекция 6 - Атомарные операции. Внеочередное выполнение инс...
ПВТ - весна 2015 - Лекция 4. Шаблоны многопоточного программирования
ПВТ - весна 2015 - Лекция 6. Разработка параллельных структур данных на основ...

Similar to Статический анализ Си++ кода (20)

PDF
Статический анализ: ошибки в медиаплеере и безглючная аська
PPTX
статический анализ кода
PPTX
Статический анализ кода
PPTX
Эффективный C++
PDF
20130429 dynamic c_c++_program_analysis-alexey_samsonov
PDF
static - defcon russia 20
PDF
Разница в подходах анализа кода компилятором и выделенным инструментом
PDF
11 встреча — Введение в GPGPU (А. Свириденков)
PDF
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
PDF
«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...
PDF
Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...
PPTX
Обзор программных средств Майкрософт для графики и визуализации: коммерческой...
PPTX
DSLs in Lisp and Clojure
PPTX
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
PPTX
200 open source проектов спустя: опыт статического анализа исходного кода
PPTX
200 open source проектов спустя: опыт статического анализа исходного кода
PDF
Статический анализ исходного кода на примере WinMerge
PPTX
Всё о статическом анализе кода для Java программиста
PPTX
Статический анализ: ищем ошибки... и уязвимости?
PPTX
Основы и применение статического анализа кода при разработке лекция 1
Статический анализ: ошибки в медиаплеере и безглючная аська
статический анализ кода
Статический анализ кода
Эффективный C++
20130429 dynamic c_c++_program_analysis-alexey_samsonov
static - defcon russia 20
Разница в подходах анализа кода компилятором и выделенным инструментом
11 встреча — Введение в GPGPU (А. Свириденков)
Евгений Крутько — Опыт внедрения технологий параллельных вычислений для повыш...
«Статический анализ: гордость и предубеждения», Алексей Кузьменко, аналитик И...
Использование C++ для низкоуровневой платформозависимой разработки — Кирилл ...
Обзор программных средств Майкрософт для графики и визуализации: коммерческой...
DSLs in Lisp and Clojure
C++ CoreHard Autumn 2018. Информационная безопасность и разработка ПО - Евген...
200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода
Статический анализ исходного кода на примере WinMerge
Всё о статическом анализе кода для Java программиста
Статический анализ: ищем ошибки... и уязвимости?
Основы и применение статического анализа кода при разработке лекция 1

More from Tatyanazaxarova (20)

PDF
Урок 27. Особенности создания инсталляторов для 64-битного окружения
PDF
Урок 26. Оптимизация 64-битных программ
PDF
Урок 25. Практическое знакомство с паттернами 64-битных ошибок
PDF
Урок 24. Фантомные ошибки
PDF
Урок 23. Паттерн 15. Рост размеров структур
PDF
Урок 21. Паттерн 13. Выравнивание данных
PDF
Урок 20. Паттерн 12. Исключения
PDF
Урок 19. Паттерн 11. Сериализация и обмен данными
PDF
Урок 17. Паттерн 9. Смешанная арифметика
PDF
Урок 16. Паттерн 8. Memsize-типы в объединениях
PDF
Урок 15. Паттерн 7. Упаковка указателей
PDF
Урок 13. Паттерн 5. Адресная арифметика
PDF
Урок 11. Паттерн 3. Операции сдвига
PDF
Урок 10. Паттерн 2. Функции с переменным количеством аргументов
PDF
Урок 9. Паттерн 1. Магические числа
PDF
Урок 8. Статический анализ для выявления 64-битных ошибок
PDF
Урок 7. Проблемы выявления 64-битных ошибок
PDF
Урок 6. Ошибки в 64-битном коде
PDF
Урок 5. Сборка 64-битного приложения
PDF
Урок 4. Создание 64-битной конфигурации
Урок 27. Особенности создания инсталляторов для 64-битного окружения
Урок 26. Оптимизация 64-битных программ
Урок 25. Практическое знакомство с паттернами 64-битных ошибок
Урок 24. Фантомные ошибки
Урок 23. Паттерн 15. Рост размеров структур
Урок 21. Паттерн 13. Выравнивание данных
Урок 20. Паттерн 12. Исключения
Урок 19. Паттерн 11. Сериализация и обмен данными
Урок 17. Паттерн 9. Смешанная арифметика
Урок 16. Паттерн 8. Memsize-типы в объединениях
Урок 15. Паттерн 7. Упаковка указателей
Урок 13. Паттерн 5. Адресная арифметика
Урок 11. Паттерн 3. Операции сдвига
Урок 10. Паттерн 2. Функции с переменным количеством аргументов
Урок 9. Паттерн 1. Магические числа
Урок 8. Статический анализ для выявления 64-битных ошибок
Урок 7. Проблемы выявления 64-битных ошибок
Урок 6. Ошибки в 64-битном коде
Урок 5. Сборка 64-битного приложения
Урок 4. Создание 64-битной конфигурации

Статический анализ Си++ кода

  • 1. Статический анализ Си++ кодаКарпов Андрей Николаевичк.ф.-м.н., технический директорООО «Системы программной верификации»E-mail: [email protected]
  • 2. О чем докладМы вседопускаем ошибки при программировании и тратим массу времени на их устранение.Один из методов который позволяет быстро диагностировать дефекты – статический анализ исходного кода.
  • 3. «Надо сразу писать хороший код» - не работает на практике!даже лучшие программисты ошибаются и делают опечатки;далее - ряд примеров ошибок, обнаруженных статическим анализатором кода в известных проектах;для анализа использовался инструмент PVS-Studio.
  • 4. Приоритет операций & и !ReturntoCastleWolfenstein - компьютерная игра, шутер от первого лица, разработанный компанией id Software. Движок игры распространяется по GPL лицензии.#define SVF_CASTAI 0x00000010if ( !ent->r.svFlags& SVF_CASTAI )if ( ! (ent->r.svFlags & SVF_CASTAI) )
  • 5. Использование && вместо &Stickies- желтые клеящиеся бумажки, только на мониторе.#define REO_INPLACEACTIVE (0x02000000L)#define REO_OPEN (0x04000000L)if (reObj.dwFlags&& REO_INPLACEACTIVE)m_pRichEditOle->InPlaceDeactivate();if(reObj.dwFlags&& REO_OPEN) hr = reObj.poleobj->Close(OLECLOSE_NOSAVE);
  • 6. Undefined behaviorMiranda IM (Miranda Instant Messenger) - программа мгновенного обмена сообщениями для Microsoft Windows.while (*(n = ++s + strspn(s, EZXML_WS)) && *n != '>') {
  • 7. Использование delete для массиваChromium - веб-браузер с открытым исходным кодом, разработанный компанией Google. На основе Chromium создаётся браузер GoogleChrome.auto_ptr<VARIANT> child_array(new VARIANT[child_count]);Использовать auto_ptrдля массивов нельзя. В деструкторе auto_ptrуничтожается только один элемент:~auto_ptr() { delete _Myptr;}В качестве альтернативы, например, можно использовать boost::scoped_array.
  • 8. Всегда истинное условиеWinDjView - быстрая и компактная программа для просмотра файлов формата DjVu.inline boolIsValidChar(int c){ return c == 0x9 || 0xA || c == 0xD || c >= 0x20 && c <= 0xD7FF || c >= 0xE000 && c <= 0xFFFD || c >= 0x10000 && c <= 0x10FFFF;}
  • 9. Оформление кода отличается от его логикиSquirrel - интерпретируемый язык программирования, разработанный специально для использования в качестве скриптового языка в приложениях реального времени, таких как компьютерные игры. if(pushval != 0) if(pushval) v->GetUp(-1) = t; else v->Pop(1);v->Pop(1); - никогда не вызывается
  • 10. Случайное объявление локальной переменнойFCE Ultra – открытый эмулятор приставки Nintendo Entertainment SystemintiNesSaveAs(char* name){ ...fp = fopen(name,"wb");int x = 0; if (!fp)int x = 1; ...}
  • 11. Работа с char как с unsigned char// check each line for illegal utf8 sequences.// If one is found, we treatthe file as ASCII,// otherwise we assumean UTF8 file.char * utf8CheckBuf = lineptr;while ((bUTF8)&&(*utf8CheckBuf)){ if ((*utf8CheckBuf == 0xC0)|| (*utf8CheckBuf == 0xC1)|| (*utf8CheckBuf >= 0xF5)) { bUTF8 = false; break; }TortoiseSVN — клиент для системы контроля версий Subversion, выполненный как расширение оболочки Windows.
  • 12. Случайные восьмеричные числаoCell._luminance = uint16(0.2220f*iPixel._red +0.7067f*iPixel._blue +0.0713f*iPixel._green);....oCell._luminance = 2220*iPixel._red +7067*iPixel._blue +0713*iPixel._green;eLynx Image Processing SDK and Lab
  • 13. Одна переменная для двух цикловLugaru— первая коммерческая игра, созданная командой независимых разработчиков WolfireGames.static inti,j,k,l,m;...for(j=0; j<numrepeats; j++){ ... for(i=0; i<num_joints; i++){ ... for(j=0;j<num_joints;j++){ if(joints[j].locked)freely=0; } ... } ...}
  • 14. Выход за границы массиваLAME - свободное приложение для кодирования аудио в формат MP3. #define SBMAX_l22int l[1+SBMAX_l]; for (r0 = 0; r0 < 16; r0++) { ... for (r1 = 0; r1 < 8; r1++) { int a2 = gfc->scalefac_band.l[r0 + r1 + 2];
  • 15. Приоритет операций * и ++eMule - это клиент для сети обмена файлами ED2K. STDMETHODIMP CCustomAutoComplete::Next(...,ULONG *pceltFetched){ ... if (pceltFetched != NULL) *pceltFetched++; ...}(*pceltFetched)++;
  • 16. Ошибка в сравненииWinMerge — свободное ПО с открытым исходным кодом для сравнения и синхронизации файлов и директорий.BUFFERTYPE m_nBufferType[2];...// Handle unnamed buffersif ((m_nBufferType[nBuffer] == BUFFER_UNNAMED) || (m_nBufferType[nBuffer] == BUFFER_UNNAMED))nSaveErrorCode = SAVE_NO_FILENAME;Если посмотреть код рядом, то по аналогии здесь должно быть:(m_nBufferType[0] == BUFFER_UNNAMED) ||(m_nBufferType[1] == BUFFER_UNNAMED)
  • 17. Забытый индекс массиваvoid lNormalizeVector_32f_P3IM(..., Ipp32s* mask, ...) { Ipp32s i; Ipp32f norm; for(i=0; i<len; i++) { if(mask<0) continue; ...}}if(mask[i]<0) continue;IPP Samples - примеры, демонстрирующие работу с библиотекой Intel Performance Primitives Library 7.0.
  • 18. Одинаковые ветви кодаNotepad++ - свободный текстовый редактор для Windows с подсветкой синтаксиса большого количества языков программирования и разметки. if (!_isVertical) Flags |=DT_VCENTER; else Flags |= DT_BOTTOM;if (!_isVertical) Flags |= DT_BOTTOM;else Flags |= DT_BOTTOM;
  • 19. Вызов неверной функции со схожим именемКакой замечательный комментарий. Жаль только не то делаем, что хотим./** Deletes all previous field specifiers. * This should be used when dealing * with clients that send multiple NEP_PACKET_SPEC * messages, so only the lastPacketSpec is taken * into account. */intNEPContext::resetClientFieldSpecs(){ this->fspecs.empty(); return OP_SUCCESS;} /* End of resetClientFieldSpecs() */Nmap Security Scanner - свободная утилита, предназначенная для разнообразного настраиваемого сканирования IP-сетей с любым количеством объектов, определения состояния объектов сканируемой сети.
  • 20. Опасный оператор ?:NewtonGameDynamics- популярный физический движок, который предоставляет надежное и быстрое решение для симуляции физического поведения объектов окружающей среды. den = dgFloat32 (1.0e-24f) * (den > dgFloat32(0.0f)) ? dgFloat32(1.0f) : dgFloat32(-1.0f);Приоритет оператора ?: ниже, чем у оператора умножения *.
  • 21. И так далее, и так далее…if (m_szPassword != NULL){if (m_szPassword != '\0') {Библиотека Ultimate TCP/IPif (*m_szPassword != '\0')bleeding = 0;bleedx = 0,bleedy;direction = 0;Lugarubleedx = 0;bleedy = 0;
  • 22. И так далее, и так далее…if((t=(char *)realloc( next->name, strlen(name+1))))FCE Ultraif((t=(char *)realloc( next->name, strlen(name)+1)))minX=max(0,minX+mcLeftStart-2);minY=max(0,minY+mcTopStart-2);maxX=min((int)width,maxX+mcRightEnd-1);maxY=min((int)height,maxX+mcBottomEnd-1);minX=max(0,minX+mcLeftStart-2);minY=max(0,minY+mcTopStart-2);maxX=min((int)width,maxX+mcRightEnd-1);maxY=min((int)height,maxY+mcBottomEnd-1);
  • 23. Низкоуровневые операции работы с памятьюХочется отдельно остановиться на наследии программ на Си, где использовались функции:ZeroMemory;memset;memcpy;memcmp;…
  • 24. Низкоуровневые операции работы с памятьюID_INLINE mat3_t::mat3_t( float src[3][3] ){memcpy( mat, src, sizeof( src ) );}Return to Castle WolfensteinID_INLINE mat3_t::mat3_t( float (&src)[3][3] ){memcpy( mat, src, sizeof( src ) );}itemInfo_t *itemInfo;memset( itemInfo, 0, sizeof( &itemInfo ) );memset( itemInfo, 0, sizeof( *itemInfo ) );
  • 25. Низкоуровневые операции работы с памятьюCxImage - открытая библиотека обработки изображений.memset(tcmpt->stepsizes, 0,sizeof(tcmpt->numstepsizes * sizeof(uint_fast16_t)));memset(tcmpt->stepsizes, 0,tcmpt->numstepsizes * sizeof(uint_fast16_t));
  • 26. Низкоуровневые операции работы с памятьюКрасивый пример 64-битной ошибки:dgInt32 faceOffsetHitogram[256];dgSubMesh* mainSegmenst[256];memset (faceOffsetHitogram, 0, sizeof (faceOffsetHitogram));memset (mainSegmenst, 0, sizeof (faceOffsetHitogram));Скопировали код и не полностью поправили. В результате в Win64 размер указателя станет не равен размеру типа dgInt32 и мы очистим только часть массива mainSegmenst.
  • 27. Низкоуровневые операции работы с памятью#define CONT_MAP_MAX 50int _iContMap[CONT_MAP_MAX];...memset(_iContMap, -1, CONT_MAP_MAX);memset(_iContMap, -1, CONT_MAP_MAX * sizeof(int));
  • 28. Низкоуровневые операции работы с памятьюOGRE (Object-OrientedGraphicsRenderingEngine) - объектно-ориентированный графический движок с открытым исходным кодом, написанный на C++.Real w, x, y, z;...inline Quaternion(Real* valptr){memcpy(&w, valptr, sizeof(Real)*4);}Да, сейчас это не ошибка.Но это мина!
  • 29. Чем раньше – тем лучше
  • 30. Почему все-таки не только юнит-тесты?проверка мест, редко получающих управления;обнаружение плавающих ошибок (undefined behavior, гейзенбаги);не на все варианты кода можно написать юнит-тест:сложные счетные алгоритмы;интерфейс.
  • 31. Здесь не поможет юнит-тест, но поможет статический анализFennecMediaProject- универсальный медиа-плеер ориентированный на воспроизведение аудио и видео в высоком разрешении.OPENFILENAME lofn;...lofn.lpstrFilter = uni("All Files (*.*)\0*.*");lofn.lpstrFilter = uni("All Files (*.*)\0*.*\0");
  • 32. Здесь не поможет юнит-тест, но поможет статический анализstatic INT_PTR CALLBACK DlgProcTrayOpts(...){ ...EnableWindow(GetDlgItem(hwndDlg,IDC_PRIMARYSTATUS),TRUE);EnableWindow(GetDlgItem(hwndDlg,IDC_CYCLETIMESPIN),FALSE);EnableWindow(GetDlgItem(hwndDlg,IDC_CYCLETIME),FALSE); EnableWindow(GetDlgItem(hwndDlg,IDC_ALWAYSPRIMARY),FALSE);EnableWindow(GetDlgItem(hwndDlg,IDC_ALWAYSPRIMARY),FALSE);EnableWindow(GetDlgItem(hwndDlg,IDC_CYCLE),FALSE);EnableWindow(GetDlgItem(hwndDlg,IDC_MULTITRAY),FALSE); ...}
  • 33. Где подробнее узнать проPVS-Studio?Страница продукта: http://www.viva64.com/ru/pvs-studio/
  • 35. Документация на русском языке: http://www.viva64.com/ru/d/PVS-Studio - статический анализатор, выявляющий ошибки в исходном коде приложений на языке C/C++/C++0x.PVS-Studio интегрируется в среду разработки VisualStudio 2005/2008/2010.
  • 36. Вопросы?Контактная информация:Карпов Андрей Николаевичк.ф.-м.н., технический директорООО «Системы программной верификации»Сайт: http://www.viva64.com/ru/E-mail: [email protected]Тел.: +7 (4872) 38-59-95 (GMT + 03:00)Twitter: https://twitter.com/Code_Analysis