
- •4. Інженерія систем і програмного забезпечення
- •4.1. Складні та великі системи
- •4.1.1. Властивості систем: емерджентність, адитивність, еквіфінальність
- •4.1.2. Відкриті та закриті системи; класифікація за призначенням, походженням, видом елементів, способом організації
- •4.1.3. Спільне та відмінності складних і великих систем
- •4.2. Моделі систем
- •4.2.1. Склад і структура системи; моделі типу чорної та білої скриньки.
- •4.2.2. Концептуальні, математичні і комп’ютерні моделі
- •4.2.3. Зв’язок між системою та моделлю. Ізо- та гомоморфізм
- •Гомоморфізм
- •Гомоморфізм Гомоморфізм Ізоморфізм
- •4.3. Інформаційні системи
- •4.3.1. Поняття, цілі, значення, класифікація за функціональністю, масштабом, сферою застосування
- •4.3.2. Забезпечення інформаційних систем: організаційне, інформаційне, математичне, програмне, технічне, лінгвістичне, методичне, правове.
- •4.4. Аналіз вимог
- •4.4.1. Класифікація вимог до програмного забезпечення. Джерела та методи збирання вимог
- •4.4.2. Вимоги користувача (варіанти використання та історії користувачів).
- •4.4.3. Функціональні та нефункціональні вимоги, обмеження, структуризація функціональних вимог.
- •4.5. Проєктування програмного забезпечення
- •4.5.1. Види проєктування: структурне, обєктно-орієнтоване, архітектурне, інтерфейсне
- •4.5.2. Парадигми проєктування: функціональна декомпозиція згори вниз, архітектура, орієнтована на дані, об'єктно-орієнтований аналіз та проєктування, подієво-керована архітектура
- •4.5.3. Ідентифікація класів предметної області. Uml-діаграми ієрархії класів: моделювання підсистем, класів та зв’язків між ними
- •4.5.4. Проєктування сценаріїв реалізації варіантів використання на основі uml-діаграм послідовностей та комунікації
- •4.5.5. Основні патерни проєктування mvc, Abstract Factory, Facade, Decorator, Flyweight, Visitor, Observer, Proxy, Strategy, Chain of Responsibility
- •4.6. Реалізація програмного забезпечення
- •4.6.1. Вимоги до оформлення коду: стиль, розбиття на структуровані одиниці, найменування змінних, класів, об’єктів.
- •4.6.2. Засоби автоматичної ґенерації програмного коду
- •4.6.3. Налагодження: Точки зупинки (Breakpoints), Спостереження за змінними (Variable Watch), Виведення на консоль (Console Output), Налагоджувач (Debugger), Аналізатори коду (Code Analyzers)
- •4.6.4. Керування конфігурацією програмного забезпечення та контроль версій
- •4.6.5. Постійна інтеграція/постійне впровадження (Continuous Integration/Continuous Delivery)
- •4.7. Забезпечення якості: спільне та відмінності процесів тестування, верифікації, валідації
- •4.7.1. Тестування методами білої та чорної скрині
- •4.7.2. Рівні тестування: модульний, інтеграційний, системний, валідаційний.
- •4.7.3. Розробка через тестування (Test-driven development)
- •2. Види тестування зручности використання:
- •3. Проведення ефективного тестування зручности використання
- •4. Вирішення крайніх випадків в тестуванні зручности використання
- •4.8. Командна робота, підходи до розробки програмного забезпечення (пз)
- •4.8.1. Класичні моделі розробки пз: каскадна (водопадна), ітераційна, інкрементна
- •4.8.2. Промислові технології розробки. Rup, msf, Agile, Scrum, Extreme Programming (xp), Kamban.
- •4.8.3. Ролі та обов'язки у команді проекту, переваги командної роботи, ризики та складність такої співпраці
- •3. Ролі членів групи в моделі процесу розробки
- •4.8.4. Основні етапи планування і виконання іт проекту. Життєвий цикл іт проекту.
4.6.3. Налагодження: Точки зупинки (Breakpoints), Спостереження за змінними (Variable Watch), Виведення на консоль (Console Output), Налагоджувач (Debugger), Аналізатори коду (Code Analyzers)
Налагодження програми, в мережі рідше знева́дження[8] (англ. debugging) — методичний процес пошуку та зменшення числа помилок або дефектів у комп'ютерній програмі або електронному обладнанні з метою отримання очікуваної поведінки. Зневадження, як правило, ускладнюється, коли різні підсистеми міцно пов'язані між собою, оскільки зміни в одній частині можуть викликати помилки в іншій.
Вади. Пошук і виправлення помилок, які програмісти називають багами, — трудомісткий процес. Програмістський напівжарт визначає цикл життя програми, як 1:3:1 (написання:налагодження:використання). Вади трапляються переважно через неуважність або втому програміста, але інколи через непродуманий до кінця алгоритм. Кількість багів зростає зі зростанням розміру програми, а з її ускладненням виникають нові помилки, пов'язані зі взаємодією та взаємовпливом різних модулів.
Частина багів виправляється уже на етапі написання програми. Інша частина — після незалежного тестування. Зазвичай тестування, яке проводить користувач, який не знає механізму роботи програми, дозволяє виловити нові помилки, які програмісти не помічають, бо мають схильність робити тільки «правильні дії». Ще одна частина багів проявляється уже в роботі програми і потребує пізнього латання, чому служать патчі і сервісні пакунки.
Засоби. Пошук помилки в програмі, як правило, — тривале і клопітке завдання. Найважливішим чинником успішності та швидкості цього процесу є, мабуть, досвід програміста, але труднощі зі зневадженням програмного забезпечення також залежать значною мірою від мови програмування. Чимало середовищ розробки програмного забезпечення мають серед своїх інструментів спеціальну програму зневаджувач. Зневаджувач є програмним інструментом, який дозволяє програмісту контролювати виконання програми, зупиняти його, знову запускати, встановлювати точки зупинки, змінювати значення змінних у пам'яті й навіть, у деяких випадках, надає можливість повернутися в минуле. Термін зневаджувач може також стосуватися програміста.
Мови програмування високого рівня, наприклад, Java, спрощують зневадження, оскільки мають спеціальні програмні засоби, як, наприклад, обробка виняткових ситуацій, що дозволяють швидше локалізувати помилку. У мов програмування нижчого рівня, таких як C або Асемблер, помилка в програмі часто може створити проблеми, що проявляються не зразу, такі, як пошкодження цілісності пам'яті, і їх набагато важче виявити, оскільки зовнішньо проблема може проявитися набагато пізніше і в несподіваній формі. В таких випадках, надзвичайно корисними є спеціальні програми на кшталт зневаджувача пам'яті.
У деяких ситуаціях можуть бути дуже корисними програмні засоби загального призначення, що прив'язані до конкретної мови. Прикладом можуть бути інструменти статичного аналізу коду. Ці інструменти виконують пошук дуже конкретних відомих (поширених та рідкісних) проблем у тексті програми. Вони дозволяють знаходити помилки, які рідко фіксуються компілятором або транслятором, оскільки вони не синтаксичні, а семантичні. Наприклад, інструкція С if (x = foo()) bar(); підозріла. Можливо, програміст помилково використав присвоювання замість порівняння. Однак, вона є цілком легальною в С, компілятор її пропустить.
Деякі виробники таких інструментів стверджують, що їхні програми можуть виявити понад 300 різних потенційних проблем. Такі засоби можуть бути надзвичайно корисними при перевірці дуже великих обсягів сирцевого коду, коли дуже неефективно переглядати весь код чи відстежувати всі шляхи його виконання. Типовим прикладом виявленої проблеми може бути звернення до змінної до її ініціалізації. Іншим прикладом може бути суворіша перевірка типів, якщо мова такої не має. Таким чином, ці засоби є кращими для виявлення потенційних вад, на противагу фактичним вадам. Як наслідок, ці засоби мають високий рівень помилкового спрацьовування. Давня утиліта Unix lint є одним з найстаріших прикладів засобів такого типу.
Для налагодження електронних пристроїв (наприклад, комп'ютерного обладнання), а також програмного забезпечення низького рівня (BIOS, драйвери пристроїв тощо) і вбудованих програм, застосовують такі інструменти, як осцилограф, аналізатор логіки, ICE, POST-контролери, які часто використовується і в комбінації. Вони можуть виконувати багато типових дій звичайних зневаджувачів для програмного забезпечення мікропроцесорних систем.
Процес зневадження. Відтворення помилки
Часто перший крок зневадження полягає в тому, щоб спробувати відтворити проблему, тобто точно визначити ситуацію, коли програма працює неправильно. Випадок, коли програма працює неправильно завжди є відносно простим, але часто проблеми проявляються тільки при експлуатації, уже після того, як програма пройшла тестування, яке не може перевірити всі можливі ситуації. Відтворення проблеми може бути особливо нетривіальним завданням, наприклад, у випадку паралельних процесів або незвичайних помилок. Крім того, специфічне вживання програми користувачем, або незвичайне оточення може значно ускладнити відтворення проблеми.
Після того, як помилку відтворено, потрібно виділити ту частину програми, де виникає збій, щоб працювати тільки з нею. Часто достатньо обмежитися тільки кількома рядами коду. Таке спрощення можна зробити вручну, за допомогою підходу «розділяй і володарюй». Програміст пробує вилучити деякі частини програми і перевіряє чи проблема все ще існує. При роботі з програмами, що використовують графічному інтерфейсі користувача, програміст спрощуватиме вікно програми, прибираючи контрольні елементи й перевіряючи, чи помилка все ще залишається. Для автоматизації цього процесу може використовуватися зневадження дельтою.
Трасування. Після того, як випробування випадку спрощено достатньо, програміст може розпочати пошук та виправлення помилки. Це можна робити або вручну, або з використанням зневаджувача. Поширеним є вставляння в програму додаткових інструкції, що регулярно роздруковували б інформацію про хід виконання програми. Такий метод називається трасуванням. У простих випадках трасування — лише декілька інструкцій виводу, що показує значення змінних в певних точках виконання програми. Наприклад,
#ifdef DEBUG
printf ("Перед викликом foo x= %d\n", x);
#endif
x = foo();
#ifdef DEBUG
printf ("Після виклику foo x= %d\n", x);
#endif
Можна використати зневаджувач, який дає доступ до стану програми (значення змінних, стек викликів) і відстежити походження помилки. Якщо мова програмування використовує компілятор, то зазвичай у бінарному коді програми вже втрачено відповідність між інструкціями процесору та рядками тексту програми. Тому для зневаджувача програму потрібно відкомпілювати в спеціальному режимі, де така відповідність збережена. При цьому розмір бінарного файлу програми зростає, а її виконання сповільнюється. Після того як помилку знайдено й виправлено, відповідний файл потрібно відкомпілювати в звичайному режимі. Зазвичай, при розробці програмного забезпечення в інтегрованому середовищі режим зневадження використовується за умовчанням, а перед поставкою програмного забезпечення замовнику його відключають.
Post mortem. Іноді помилку можна знайти, аналізуючи дамп процесу. Таке зневадження називають посмертним (post mortem). Деякі операційні системи створюють дамп (відбиток пам'яті процесу) при аварійному завершенні програми, програміст може утворити його вручну, за потреби, наприклад командою dump операційної системи Unix. Для зіставлення пам'яті зі змінними програми бажано мати таблицю символів. В роботі допомагають спеціальні програми — аналізатори дампу. Дебаґери на зразок gdb теж можуть зчитати і проаналізувати дамп.
Інші методи. Шукати помилку можна, спостерігаючи за процесом з іншого комп'ютера. Для запуску віддаленого зневадження зневаджувач підключається до віддаленої системи через мережу. Після того, як зв'язок встановлено, зневаджувач може контролювати виконання програми на віддаленій системі та отримувати інформацію про її стан.
Антизневадження є «застосування в комп'ютерному коді одного або декількох методів, що перешкоджають спробам зворотної розробки та зневадження цільового процесу». Види підходів:
На основі API: перевірка на наявність зневаджувачів, використовуючи інформацію про систему
На основі обробки виняткових ситуацій: перевіряється, чи йде перехоплення виняткових ситуацій
Блокування процесів і потоків: перевіряється, чи були маніпуляції з блокуванням процесу або потоків
Зміна коду: перевіряється чи були зміни в коді внесені зневаджувачем для обробки програмних точок зупину
На основі обладнання та регістрів: перевіряються апаратні точки зупину і регістри процесора
Час і латентність: перевіряється час виконання інструкцій.
Зневадження може бути перешкодою при використанні одного або кількох з вищезазначених методів. Є достатньо багато методів антизневадження для захисту програмного забезпечення від більшості загроз.
Точка розбиття або точка зупину (англ. breakpoint; сленнґ. бря́ка) — це позначка місця припинення чи призупинення виконання програми, яка застосовується для відладки ПЗ. Точки розбиття також називають просто паузами або точками зупину.
Взагалі, їх використовують, щоб досліджувати сам процес виконання програми. По зупинці виконання програми програміст перевіряє середовище (регістри загального призначення, пам'ять, журнали, файли тощо) для того, щоб з'ясувати, чи програма працює належним чином. На практиці точка розбиття визначається однією або кількома умовами.
Умови призупинення програми. Найбільш поширеним способом застосування точки розбиття є зупинення виконання програми перед місцем, визначеним програмістом. Такі точки називають заданими. Також використовуються й інші умови, такі як читання, запис або модифікація визначеного місця в пам'яті. Такі точки називають умовними, інформаційними точками зупинки, точками спостереження. ТЗ також можуть перервати виконання програми в певний момент часу, наприклад по натисканню на клавішу і т. д.
Інструменти перевірки. По досягненню ТЗ використовуються різні інструменти для перевірки стану програми або його редагування. Для того щоб побачити які функції були потрібні щоб викликати ТЗ, необхідно трасувати стек кожного потоку виконання. Список точок спостереження (watches) дозволяє дослідити, які значення мають певні змінні і твердження. Також існують інструменти, що використовуються для відображення вмісту регістрів, завантажених модулів програми та іншої інформації.
Варіанти реалізації. Апаратними засобами. Багато процесорів забезпечують апаратну підтримку для використання точок розбиття (типово, командні та інформаційні ТЗ). Набори команд архітектури x86 процесорів забезпечують апаратну підтримку для ТЗ із x86 зневаджувальними регістрами. В деяких випадках в мікроархітектурі процесора укладається обмеження, що не дозволяє застосовувати ТЗ, які встановлені на код в командних слотах. Наявність такого обмеження залежить від типу процесора.
Програмним забезпеченням. Без використання апаратного забезпечення, зневаджувачі реалізовуються програмно. Для того щоб застосувати ТЗ достатньо замінити команду в необхідному місці на одну з наведених нижче:
Команда, яка викликає зневаджувач напряму (напр. системний виклик(system call));
Неправильна команда, навмисно вставлена в місце, де необхідно зупинити програму (така, що потім буде оброблятись зневаджувачем);
АБО
За допомогою набору команд симулятору можливо реалізувати умовні і безумовні точки зупинки, через просте вкладення відповідних умов тестів в ході виконання нормального програмного циклу — це також закономірно дозволяє реалізувати непримусові точки зупину (наприклад в програмах призначених тільки для читання).
Інтерпретовані мови також можуть ефективно використовувати зазначену вище концепцію у своєму програмному циклі.
Оснащення сирцевого коду додатковими структурами коду, які породжують функції виклику внутрішніх чи зовнішніх засобів зневадження, є ще одним альтернативним варіантом. Використання цього методу призводить до зростання обсягу бінарного коду та може перешкоджати звичайному доступу до пам'яті та обробці винятків. Опція «Зневадження» («Debug») присутня у деяких компіляторів та напів-прозоро втілює даний підхід.
Деякі налагоджувачі дозволяють модифікувати програму «на льоту» (під час паузи при виконанні програмного циклу). Зазвичай це дає можливість обійтися без повторного компілювання програми і уникнути її перезапуску. Також це дає змогу застосувати власноруч написані, тимчасові команди для проведення тестування. Деякий код часто може бути просто пропущеним для того, щоб визначити вплив такої дії на логіку програми; можна наприклад пропустити перевірку якоїсь умови, опинившись у блоці коду, який за нормальних умов ніколи не виконується. У багатьох випадках це може бути єдиним можливим засобом для тестування незрозумілих помилок, спричинених подіями підпрограми, які рідко, якщо взагалі коли-небудь, правильно виконуються — без додаткового ризику зберегти тимчасові зміни сирцевого коду.
Програмні точки зупинки використовують додаткові ресурси процесора, а тому їх використання сильно сповільняє роботу налагоджуваної програми. Однак це цілком прийнятно під час тестування. До того ж, у цьому випадку інформація зібрана налагоджувачем не обмежується форматом налагоджувальної інформації апаратного забезпечення. Наприклад, програмний налагоджувач може збирати інформацію про шлях виконання на рівні програм/підпрограм/окремих інструкцій, що може значно перевищувати можливості інспектування конкретної апаратної платформи. Також, для зменшення промахів кешу, може застосовуватися метод симуляції набору інструкцій замість методу (повторюваної) заміни інструкцій.
Наприклад, деякі діалекти мови FORTRAN мають команду AT, яка з самого початку була створена щоб слугувати інструкцією зупинки. Python реалізує дебагер доступний з програм на Python. Такими можливостями можна (і часом так роблять) зловживати використовуючи їх як аналог команди COMEFROM.
Отже, ви зупинили програму у контрольній точці. Зазвичай потім дивляться, які значення тих чи інших змінних. Це називається спостереженням змінних (watching variables).
У IDE є спеціальне вікно списку змінних, що спостерігаються.
Найпростіше додати змінну до списку спостереження можна, помістивши курсор редактора коду на її ім'я та вибрати контекстне меню редактора Add Watch at Cursor. У вікні спостережень буде показано ім'я змінної та її поточне значення або повідомлення, що показує, що змінна зараз недоступна або спостереження вимкнено.
Редактор коду має вбудований інструмент, що дозволяє надзвичайно швидко дізнатися про поточне значення змінної або виразу. Він називається підказкою оцінки висловлювання. Достатньо на секунду затримати курсор миші над ім'ям змінної або виділеному вираженні, і під курсором з'явиться віконце інструментальної підказки з ім'ям змінної та її поточним значенням. Причому, на відміну від вікна спостережень, у такий спосіб можна переглядати і змінні, що знаходяться за межами поточної області дії (оскільки тут не може виникнути неоднозначності з іменами).
Відлагоджувач (зневаджувач, англ. debugger, також зустр. англіцизм: деба́гер, українською означає відлагоджувати (програма що допомагає виявити помилки в програмному коді, в даному випадку) — комп'ютерна програма, яка використовується для тестування і виправлення вад інших програм. Як варіант, код для розгляду може бути запущено на емуляторі інструкцій, що дозволяє більший контроль зупинки процесу при заданих умовах, але, як правило, тоді виконання коду відбувається набагато повільніше, ніж якщо це робиться напряму на процесорі.
Опис. Якщо програма завершується аварійно, буде показано позицію у вихідному коді, якщо це відлагоджувач рівня вихідних кодів або відлагоджувач символьний, що як правило присутні в інтегрованих середовищах розробки. Відлагоджувачі таких типів показують рядок у дизасемблері. («Аварійне завершення» відбувається, коли програма не може продовжуватися через помилку. Наприклад, програма намагається використати інструкцію, відсутню на поточній версії центрального процесора або при спробі доступу до відсутньої або захищеної пам'яті.
Як правило, відлагоджувач також пропонує складніші функції, як, наприклад, просування програми крок за кроком, зупинки (можна призупинити програму для вивчення поточного стану) при деякій події за допомогою точки зупину, а також відстеження значення змінних. Деякі відлагоджувачі мають можливість змінити стан програми, поки вона працює, а не лише просто спостерігати її.
Важливість гарного відлагоджувача важко переоцінити. Більш того, наявність та якість такого інструменту для конкретної мови та платформи можуть бути вирішальним фактором у їх використанні, навіть якщо інша мова або платформа краще підходять для виконання завдання. Разом з тим, важливо також зазначити, що програмне забезпечення може поводитися (і часто поводиться) інакше під керуванням відлагоджувача, ніж при прямому виконанні, через неминучі зміни в оточенні, що вносяться відлагоджувачем. В результаті, навіть при потужному інструменті зневадження, часто дуже важко відслідковувати виконання завдань у складних багатопотокових або розподілених системах.
Та ж функціональність, що робить відлагоджувач корисною для усунення помилок, дозволяє його використання з хакерською метою, наприклад, при спробі уникнути захисту від копіювання, керування цифровими правами та інших програмних функцій захисту.
Більшість основних рушіїв зневадження, таких як GDB і DBX надають інтерфейс командного рядка. Графічні оболонки відлагоджувачів є популярними розширеннями для рушіїв зневадження, які забезпечують інтегрування в інтегроване середовище розробки, анімацію та візуалізацію функцій.
Апаратна підтримка для відлагодження. Більшість сучасних мікропроцесорів мають принаймні одну з цих функцій полегшення зневадження у своїй архітектурі:
апаратна підтримка покрокового виконання програми, наприклад, прапорець пастки[en]
набір інструкцій, що відповідає вимогам до віртуалізації від Popek та Goldberg, що дозволяє простіше побудувати відлагоджувач програмного забезпечення, яке працює на тому ж процесорі, що й програма зневадження; такі процесори можуть виконувати внутрішні цикли програми на повній швидкості, але залишаються під контролем відлагоджувача
внутрішньосхемне програмування дозволяє відлагоджувачу виконати програму заново на зовнішніх апаратних засобах задля її тестування (наприклад, для додавання або вилучення точок зупину на інструкціях)
апаратне забезпечення точок зупину при зміні даних, наприклад, виключна ситуація при відсутності сторінки
контакти JTAG або новіші інтерфейси зневадження Nexus[en] та ETM (Embedded Trace Macrocell від ARM).
Відлагоджувач є невід'ємною складовою частиною вбудованого середовища розробки, а відтак всі такі середовища мають у своєму складі відлагоджувачі, або повністю вбудовані, або ж надають користувацький інтерфейс до зовнішніх програм чи розширень.
Для перевірки якості програмного забезпечення доводиться застосовувати багато різних інструментів. Зокрема, до них належать інструменти статичного та динамічного аналізу. У цій статті ми спробуємо розібратися, чому однієї методології, чи то статичний, чи то динамічний аналіз, може виявитися недостатньо для проведення комплексного аналізу програм і чому краще спільно використовувати ці два підходи. Статичний аналіз коду – це процес виявлення помилок і недоліків у вихідному коді програм. Для його виконання не потрібно запускати програму, весь аналіз буде виконано на наявній кодовій базі. Найближча аналогія, яку можна провести зі статичним аналізом коду, це так званий процес code review, тільки автоматизований (який виконує програма-робот). Зазначимо, що використання статичного аналізу коду не обмежується лише виявленням помилок у програмі. Деякі статичні аналізатори дають змогу перевіряти, чи відповідає вихідний код прийнятому в компанії стандарту оформлення коду.
Динамічний аналіз коду – це спосіб аналізу програми безпосередньо під час її виконання. Аналіз виконується за допомогою набору даних, які подаються на вхід досліджуваній програмі. Тому ефективність аналізу безпосередньо залежить від якості та кількості вхідних даних для тестування. Саме від них залежить повнота покриття коду, яка буде отримана за результатами тестування. Динамічне тестування найбільш важливе в тих галузях, де головним критерієм є надійність програми, час відгуку або споживані ресурси. Це може бути, наприклад, система реального часу, що керує відповідальною ділянкою виробництва, або сервер бази даних. У таких областях будь-яка допущена помилка може виявитися критичною.
Статичний аналіз коду (англ. static code analysis) — аналіз програмного забезпечення, який здійснюють (на відміну від динамічного аналізу) без реального виконання програм, що досліджуються. Зазвичай аналізу піддають початковий код, хоча іноді аналізу піддається об'єктний код, наприклад, P-код або код CIL. Термін зазвичай застосовують до аналізу, який проводить спеціальне програмне забезпечення (ПЗ), тоді як ручний аналіз називають «program understanding», «program comprehension» (розумінням або осягненням програми).
В залежності від використаного інструменту глибина аналізу може змінюватись від визначення поведінки окремих операторів до глобальнішого аналізу, що включає весь наявний вихідний код. Способи використання отриманої в ході аналізу інформації також різні — від виявлення місць, які можливо містять помилки (утиліти на кшталт Lint), до формальних методів, що дозволяють математично довести деякі властивості програми (наприклад, відповідність її поведінки до специфікації).
Деякі люди вважають програмні метрики і зворотне проектування формами статичного аналізу. Отримання метрик (англ. software quality objectives) та статичний аналіз часто поєднуються, особливо при створенні вбудованих систем.
Статичний аналіз дедалі більше використовується у верифікації властивостей ПЗ, що використовується в комп'ютерних системах високої надійності, особливо критичних для життя (safety-critical[en]). Також застосовується для пошуку коду, що потенційно містить вразливості (іноді це застосування називається Static Application Security Testing, SAST).
Статичний аналіз ПЗ постійно застосовується в наступних областях:
Для медичних пристроїв.
Для ядерних станцій і систем захисту реактора.
Для авіації (в комбінації з динамічним аналізом).
За даними VDC на 2012 рік, приблизно 28 % розробників вбудованого ПЗ застосовували засоби статичного аналізу, а 39 % збирались почати їх використання протягом 2 років.
Принципи статичного аналізу. Більшість компіляторів (наприклад, GNU C Compiler) виводять на екран «попередження» (англ. warnings) — повідомлення про те, що код, будучи синтаксично правильним, швидше за все, містить помилку. Наприклад:
int x;
int y = x+2; // Змінну x не ініціалізовано!
Це найпростіший статичний аналіз. У компілятора є багато інших важливих характеристик — в першу чергу швидкість роботи і якість машинного коду, тому компілятори перевіряють код лише на очевидні помилки. Статичні аналізатори призначені для детальнішого дослідження.
Типи помилок, що виявляються статичними аналізаторами
Невизначена поведінка — неініціалізовані змінні, звернення до NULL-вказівників. Про найпростіші випадки сигналізують також компілятори.
Порушення алгоритму користування бібліотекою. Наприклад, для кожного fopen потрібен fclose. І якщо файлова змінна втрачається раніше, ніж файл закривається, аналізатор може повідомити про помилку.
Типові сценарії, що призводять до недокументованої поведінки. Стандартна бібліотека мови Сі відома великою кількістю невдалих технічних рішень. Деякі функції, наприклад, gets, в принципі небезпечні. sprintf і strcpy безпечні лише при певних умовах.
Переповнення буфера — коли комп'ютерна програма записує дані за межами виділеного в пам'яті буферу.
Динамічний аналіз коду (англ. Dynamic program analysis) — аналіз програмного забезпечення, що виконується за допомогою виконання програм на реальному або віртуальному процесорі (на відміну від статичного аналізу). Утиліти динамічного аналізу можуть вимагати завантаження спеціальних бібліотек, перекомпіляцію програмного коду. Деякі утиліти можуть інструментувати код, що виконується, у процесі виконання або перед ним. Для більшої ефективності динамічного аналізу вимагається подача досліджуваної програмі достатньої кількості вхідних даних, щоб отримати повніше покриття коду. Також потрібно подбати про мінімізації впливу інструментування на виконання програми, що досліджується (включаючи часові характеристики). Приклади утиліт:
Valgrind[1], виконує програму на віртуальному процесорі, може виявляти помилки пам'яті (наприклад, пов'язані з неправильним використанням функцій malloc і free), ситуації гонки потоків (race conditions) в багатопоточних програмах.
Pin[1]
DynamoRIO[1]
Dmalloc, бібліотека для перевірки виділення і звільнення пам'яті, а також витоків пам'яті, повторного звільнення тощо. Програму треба перекомпілювати, крім того, у всі файли необхідно підключити заголовковий файл мови Сі dmalloc.h для отримання точніших звітів.
jTracert[недоступне посилання з квітня 2019], Java агент (що завантажується за допомогою аргументу -javaagent:), який інструментує код існуючих додатків, що працюють у віртуальній машині JVM, і автоматично будує діаграми послідовності (sequence diagrams).
Daikon [Архівовано 24 грудня 2013 у Wayback Machine.] — реалізація динамічного детектора інваріантів. Проводиться пошук значень, обчислених програмою і пошук властивостей, які були вірні при запуску, і, найбільш імовірно, будуть вірні при всіх запусках.
DynInst — бібліотека, що модифікує код під час виконання. Корисна при розробці програм динамічного аналізу, допомагає додавати в ПЗ, що досліджується, налагоджувальні точки (probes). В основному Dyninst, не вимагає перекомпіляції програм, однак, non-stripped executables і файли, що виконуються, з налагоджувальною інформацією простіше піддаються інструментуванню.
Holodeck від компанії Security innovation це програма, яка симулює помилки для динамічного аналізу і надійності програм для Windows.
IBM Rational Purify: в основному виявляє помилки при роботі з пам'яттю (вихід за межі масивів, витоки пам'яті).
BoundsChecker: можливості, схожі з IBM Purify.
VB Watch додає код динамічного аналізу в програми на мові Visual Basic для моніторингу їх продуктивності, стеку викликів, траси виконання, змінних і покриття коду.
Insure++ — аналізатор пам'яті і детектор помилок. Компонент Inuse дозволяє побачити графічно історію виділення пам'яті, аналізувати використання купи, шукати витоку пам'яті тощо
Intel Thread Checker — аналізатор помилок у багатопотокових застосунках. Виявляє помилки конкурентного доступу до даних і ситуації взаємоблокувань. Працює з додатками для Windows і Linux.
CHESS — інструмент для тестування багатопотокових .Net (керованих) і Win32, 64 програм
Більша частина програм аналізу продуктивності[en] використовує методи динамічного аналізу програм.
Історичні приклади
IBM OLIVER: інтерактивна система тестування і налагодження CICS, що використовує симулятор набору команд
SIMON аналізатор пакетних програм, система тестування і налагодження, використовує симулятор
SIMMON: внутрішній симулятор IBM, що застосовувався при розробці компонент ОС, утиліт і процесорів вводу-виводу.