Откуда берутся ошибки в ПО?
Почему бывает так, что программы работают неправильно? Все очень просто – они создаются и используются людьми. Если пользователь допустит ошибку, то это может привести к проблеме в работе программы – она используется неправильно, значит, может повести себя не так, как ожидалось.
Ошибка (error) – это действие человека, которое порождает неправильный результат.
Однако программы разрабатываются и создаются людьми, которые также могут допускать (и допускают) ошибки. Это значит, что недостатки есть и в самом программном обеспечении. Они называются дефектами или багами (оба обозначения равносильны). Здесь важно помнить, что программное обеспечение – нечто большее, чем просто код.
Дефект, Баг (Defect, Bug) – недостаток компонента или системы, который может привести к отказу определенной функциональности. Дефект, обнаруженный во время исполнения программы, может вызвать отказ отдельного компонента или всей системы.
При исполнении кода программы дефекты, заложенные еще во время его написания, могут проявиться: программа может не делать того, что должна или наоборот делать то, чего не должна – происходит сбой.
Сбой (failure) – несоответствие фактического результата (actual result) работы компонента или системы ожидаемому результату (expected result).
Сбой в работе программы может являться индикатором наличия в ней дефекта.
Таким образом, баг существует при одновременном выполнении трех условий:
Важно понимать, что не все баги становятся причиной сбоев – некоторые из них могут никак себя не проявлять и оставаться незамеченными (или проявляться только при очень специфических обстоятельствах).
Причиной сбоев могут быть не только дефекты, но также и условия окружающей среды: например, радиация, электромагнитные поля или загрязнение также могут влиять на работу как программного, так и аппаратного обеспечения.
Всего существует несколько источников дефектов и, соответственно, сбоев:
Дефекты могут возникать на разных уровнях, и от того, будут ли они исправлены и когда, будет напрямую зависеть качество системы.
Качество (Quality) – степень, в которой совокупность присущих характеристик соответствует требованиям.
Качество программного обеспечения (Software Quality) – это совокупность характеристик программного обеспечения, отражающих его способность удовлетворять установленные и предполагаемые потребности.
Требование (Requirement) – потребность или ожидание, которое установлено. Обычно предполагается или является обязательным.
В первом случае все было сделано правильно и мы получили продукт, полностью соответствующий ожиданиям заказчика и удовлетворяющий критериям качества.
Во втором случае ошибки были допущены уже при кодировании, что привело к появлению дефектов в готовом продукте. Но на этом уровне баги достаточно легко обнаружить и исправить, поскольку мы видим несоответствие требованиям.
Третий вариант хуже – здесь ошибки были допущены на этапе проектирования системы. Заметить это можно лишь проведя тщательную сверку со спецификацией. Исправить такие дефекты тоже непросто – нужно заново перерабатывать дизайн продукта.
В четвертом случае дефекты были заложены еще на этапе формирования требований; вся дальнейшая разработка и даже тестирование пошли по изначально неправильному пути. Во время тестирования мы не найдем багов – программа пройдет все тесты, но может быть забракована заказчиком.
Условно можно выделить пять причин появления дефектов в программном коде.
Программная ошибка
Термин «программная ошибка» обычно употребляется для обозначения ошибок, проявляющих себя на стадии работы программы, в отличие, например, от ошибок проектирования или синтаксических ошибок. Отчет, содержащий информацию об ошибке также называют отчетом о проблеме (англ. bug report). Отчет о критической проблеме (англ. crash), вызывающей аварийное завершение программы, называют крэш-репортом (англ. crash report).
Программные ошибки локализуются и устраняются в процессе тестирования и отладки программы.
Связанные понятия
Упоминания в литературе
Связанные понятия (продолжение)
Не путать с голосовым движком, который формирует звуковую речь в соответствии с текстом.Звуковой движок (англ. sound/audio engine) — программный компонент игрового движка, отвечающий за воспроизведение звука (шумовое и музыкальное оформление, голосов персонажей) в компьютерной игре или другом приложении. Звуковой движок часто отвечает также за имитацию определённых акустических условий, воспроизведение звука согласно местоположению, эхо и т. д.
Фанатские игры — компьютерные игры, сделанные поклонниками одной или нескольких существующих игр или игровых серий. Многие фан-игры создаются как в качестве попытки клонирования или создания ремейка оригинального дизайна, геймплея и персонажей. Однако в большинстве случаев, фанаты создают уникальную игру, используя вдохновившую игру в качестве прообраза. Хотя качество фан-игр всегда варьировалось, но при текущем уровне развития технологий существует огромное число инструментов, упрощающих создание.
СОДЕРЖАНИЕ
История
Среднеанглийское слово bugge является основой терминов « bugbear » и « bugaboo » как терминов, используемых для обозначения монстра.
Термин «ошибка» для описания дефектов был частью инженерного жаргона с 1870-х годов и появился еще до электронных компьютеров и компьютерного программного обеспечения; возможно, изначально он использовался в аппаратной инженерии для описания механических неисправностей. Например, Томас Эдисон написал следующие слова в письме своему сотруднику в 1878 году:
Айзек Азимов использовал термин «ошибка» для обозначения проблем с роботом в своем рассказе « Поймай этого кролика », опубликованном в 1944 году.
. процесс анализа также должен быть выполнен, чтобы предоставить аналитической машине необходимые оперативные данные; и в этом также может заключаться возможный источник ошибки. При условии, что реальный механизм безошибочен в своих процессах, карты могут отдавать ему неправильные приказы.
Отчет «Ошибки в системе»
Институт открытых технологий, управляемый группой New America, в августе 2016 года выпустил отчет «Ошибки в системе», в котором говорится, что политики США должны провести реформы, чтобы помочь исследователям выявлять и устранять ошибки программного обеспечения. В отчете «подчеркивается необходимость реформы в области обнаружения и раскрытия уязвимостей программного обеспечения». Один из авторов отчета сказал, что Конгресс сделал недостаточно для устранения уязвимости киберпрограмм, хотя Конгресс принял ряд законопроектов, направленных на борьбу с более серьезной проблемой кибербезопасности.
В докладе говорится, что Закон о компьютерном мошенничестве и злоупотреблениях, Закон об авторском праве в цифровую эпоху и Закон о конфиденциальности электронных коммуникаций криминализируют и вводят гражданские санкции за действия, которые исследователи в области безопасности регулярно совершают при проведении законных исследований в области безопасности.
Терминология
Хотя термин «ошибка» используется для описания ошибок программного обеспечения, многие считают, что от него следует отказаться. Один из аргументов состоит в том, что слово «ошибка» не связано с тем, что проблема была вызвана человеком, и вместо этого подразумевает, что дефект возник сам по себе, что привело к отказу от термина «ошибка» в пользу таких терминов, как «дефект» с ограниченным успехом. С 1970-х годов Гэри Килдалл с некоторой юмором предложил использовать термин «грубая ошибка».
В программной инженерии метаморфизм ошибки (от греческого meta = «изменение», morph = «форма») относится к развитию дефекта на заключительном этапе развертывания программного обеспечения. Преобразование «ошибки», совершенной аналитиком на ранних стадиях жизненного цикла разработки программного обеспечения, которая приводит к «дефекту» на заключительной стадии цикла, было названо «метаморфизмом ошибки».
Профилактика
Индустрия программного обеспечения приложила много усилий для сокращения количества ошибок. Это включает:
Типографические ошибки
Методологии разработки
Модульное тестирование включает в себя написание теста для каждой функции (модуля), которую должна выполнять программа.
В управляемой тестированием разработке модульные тесты пишутся до кода, и код не считается завершенным до тех пор, пока все тесты не будут успешно завершены.
Гибкая разработка программного обеспечения включает частые выпуски программного обеспечения с относительно небольшими изменениями. Дефекты выявляются по отзывам пользователей.
Поддержка языков программирования
Анализ кода
Инструменты для анализа кода помогают разработчикам, проверяя текст программы за пределами возможностей компилятора, чтобы выявить потенциальные проблемы. Хотя в целом проблема поиска всех ошибок программирования в данной спецификации не разрешима (см. Проблему остановки ), эти инструменты используют тот факт, что люди-программисты часто допускают определенные виды простых ошибок при написании программного обеспечения.
Приборы
Инструменты для мониторинга производительности программного обеспечения во время его работы, либо специально для поиска проблем, таких как узкие места, либо для обеспечения уверенности в правильной работе, могут быть встроены в код явно (возможно, так просто, как утверждение PRINT «I AM HERE» ) или предоставлены как инструменты. Часто бывает неожиданно обнаружить, где большую часть времени занимает фрагмент кода, и это удаление предположений может привести к переписыванию кода.
Тестирование
Измерения во время тестирования могут дать оценку количества оставшихся вероятных ошибок; это становится более надежным, чем дольше тестируется и разрабатывается продукт.
Отладка
Как правило, первым шагом в поиске ошибки является ее надежное воспроизведение. Как только ошибка воспроизводится, программист может использовать отладчик или другой инструмент при воспроизведении ошибки, чтобы найти точку, в которой программа сбилась с пути.
Некоторые ошибки обнаруживаются с помощью входных данных, которые программисту может быть сложно воссоздать. Одной из причин смерти радиационной машины Therac-25 была ошибка (в частности, состояние гонки ), которая возникала только тогда, когда оператор машины очень быстро вводил план лечения; На то, чтобы это сделать, потребовались дни практики, поэтому ошибка не проявлялась ни при тестировании, ни при попытке производителя воспроизвести ее. Другие ошибки могут перестать появляться всякий раз, когда установка расширяется, чтобы помочь найти ошибку, например, запуск программы с отладчиком; их называют хайзенбагами (шутливо названными в честь принципа неопределенности Гейзенберга ).
Тест ошибок
Чтобы облегчить воспроизводимые исследования по тестированию и отладке, исследователи используют специально подобранные тесты для выявления ошибок:
Управление ошибками
Сортировка ошибок рассматривает ошибки и решает, нужно ли их исправлять и когда. Решение основывается на приоритете ошибки и таких факторах, как график проекта. Сортировка предназначена не для исследования причины ошибок, а для определения стоимости их исправления. Сортировка происходит регулярно, и в ней выявляются ошибки, открытые или повторно открытые с момента предыдущей встречи. Участниками процесса сортировки обычно являются менеджер проекта, менеджер по разработке, менеджер по тестированию, менеджер по сборке и технические эксперты.
Строгость
Приоритет
Релизы программного обеспечения
Причины, по которым издатель программного обеспечения предпочитает не исправлять или даже не исправлять конкретную ошибку, включают:
Другая категория ошибок называется состоянием гонки, которое может возникнуть, когда в программе одновременно выполняется несколько компонентов. Если компоненты взаимодействуют в порядке, отличном от задуманного разработчиком, они могут мешать друг другу и мешать программе выполнять свои задачи. Эти ошибки может быть трудно обнаружить или предвидеть, поскольку они могут не возникать при каждом выполнении программы.
Арифметика
Логика
Синтаксис
Ресурс
Многопоточность
Взаимодействие
Командная работа
Подразумеваемое
Согласно исследованию НАСА « Сложность программного обеспечения для полета », «исключительно хороший процесс разработки программного обеспечения может снизить количество дефектов до 1 дефекта на 10 000 строк кода».
Помимо ущерба, причиненного ошибками, часть их стоимости связана с усилиями, затраченными на их исправление. В 1978 году Линц и др. показал, что в среднем по проектам 17% усилий по разработке вкладывается в исправление ошибок. Исследование репозиториев GitHub в 2020 году показало, что медиана составляет 20%.
Известные ошибки
Ошибка
оглавление
Определения
Ошибка программы или программного обеспечения, основанная на общем определении слова » ошибка «
«Несоблюдение требования (EN ISO 9000: 2005)».
В частности, ошибка определяется как
«Отклонение ФАКТИЧЕСКИХ (наблюдаемых, определенных, вычисленных состояний или процессов) от ЗАДАЧИ (определенных, правильных состояний и процессов), если оно превышает предварительно определенный предел допуска [который также может быть 0]».
«Ошибка» как синоним ошибки программы
«[. ] Я обнаружил« жучок »в своем аппарате, но не в самом телефоне. Он был из рода callbellum ».
«[. ] Я нашел« жучок »в своем наборе, но не в самом телефоне. Он был из рода« callbellum »».
Типы ошибок
В программной инженерии (см. Также) различают следующие типы ошибок в программах:
Прочие условия ошибки
В некоторых проектах термин «ошибка» не используется, а скорее, например, в метабугах, в которых ошибка является элементом списка задач. В некоторых проектах вместо этого используется термин «проблемы», поскольку этот термин не ограничивается ошибками.
Экономический смысл
В том же исследовании также исследуется развитие качества программного обеспечения за период с 2002 по 2004 год. Результатом является:
Отчет Высшего аудиторского управления новых проектов (1985 г.) при федеральной администрации США показывает особенно большое количество неудач, согласно которым
Standish Group International заявила: в среднем проекты превышают
Евуси-Менах определила следующие факторы как причины отмены проекта из-за низкого качества программного обеспечения:
Предотвращение и исправление программных ошибок
Как правило, чем раньше ошибка возникает в процессе разработки и чем позже она обнаруживается, тем больше времени потребуется на ее исправление.
Во время планирования
На этапе анализа
Одна из проблем состоит в том, что правильность программы может быть доказана только с помощью должным образом формализованной спецификации. Однако создание такой спецификации может быть столь же сложным и подверженным ошибкам, как программирование самой программы.
На этапе проектирования
При программировании
При тестировании
Некоторые поставщики программного обеспечения иногда проводят этапы тестирования публично и выпускают бета-версии, чтобы непредсказуемо разнообразные условия использования разных пользователей могли быть протестированы и прокомментированы ими самими.
Оперативный
Безупречность
Классификация дефектов
Критерии, по которым можно классифицировать ошибки, включают: (с примерами):
С помощью показателей «результаты [и понимание ошибок] также должны способствовать поиску причин, стоящих за проблемами». «Классификация ошибок формирует основу для стандартизированных процедур обработки ошибок, а также поддерживает постоянное улучшение качества в смысле управления качеством ». Дополнительная информация по каждой ошибке, такая как подробное описание ошибки, затронутые программы, вовлеченные лица и т. Д., Сопровождает меры по устранению ошибок. устранение ошибок и их документирование. Для получения дополнительной информации см. Руководство BITKOM.
Последствия ошибок программы
Воспроизводимость программных ошибок
Некоторые программные ошибки чрезвычайно трудно или невозможно надежно воспроизвести. Если ранее неудачный процесс повторяется при явно неизменных условиях, существует вероятность того, что эти ошибки больше не будут выражены. Есть две возможные причины такого поведения: с одной стороны, могут быть задержки между активацией ошибки и проблемой, которая в конечном итоге возникает, например, сбой программы, который скрывает действительную причину и затрудняет ее выявление. С другой стороны, другие элементы программной системы (оборудование, операционная система, другие программы) могут влиять на поведение ошибок в рассматриваемой программе. Примером этого являются ошибки, возникающие в параллельных средах при недостаточной синхронизации (точнее: последовательности ). Из-за возникающих условий гонки процессы могут обрабатываться в последовательности, которая приводит к ошибке времени выполнения. Если одно и то же действие повторяется, возможно, что порядок процессов будет другим, и проблем не возникнет.
Что такое баги, ворнинги и исключения в программировании
Разбираемся, какие бывают типы ошибок в программировании и как с ними справляться.
Многим известно слово баг (англ. bug — жук), которым называют ошибки в программах. Однако баг — это не совсем ошибка, а скорее неожиданный результат работы. Также есть и другие термины: ворнинг, исключение, утечка.
В этой статье мы на примере C++ разберём, что же значат все эти слова и как эти проблемы влияют на эффективность программы.
Пишет о программировании, в свободное время создает игры. Мечтает открыть свою студию и выпускать ламповые RPG.
Ошибки в программировании
Словом «ошибка» (англ. error) можно описать любую проблему, но чаще всего под ним подразумевают синтаксическую ошибку — некорректно написанный код, который даже не скомпилируется:
Компилятор тут же скажет, что в коде ошибка и скорее всего не хватает запятой или точки с запятой.
Также существуют ворнинги (англ. warning — предупреждение). Они не являются ошибками, поэтому программа всё равно будет собрана. Вот пример:
Предупреждения не являются чем-то критичным, но могут иметь негативные последствия. Например, ваша программа будет использовать больше памяти, чем должна. Так как C++ нужен в том числе и для разработки высоконагруженных систем, этого допускать нельзя.
После восклицательного знака в треугольнике — количество предупреждений
Третий вид ошибок — ошибки сегментации (англ. segmentation fault, сокр. segfault, жарг. сегфолт). Они возникают, если программа пытается записать что-то в ячейку, недоступную для записи. Например:
Вот результат работы такого кода:
Баги в программах
Мы выяснили, что баг — это не совсем ошибка, а скорее неожиданное поведение программы или результат такого поведения. Баги могут быть чем-то забавным или неприятным. Например, как в играх:
Но они могут привести и к более серьёзным последствиям. Если неправильно спроектировать работу многопоточного приложения, то потоки будут постоянно опережать друг друга. Например, сообщение об ошибке из одного потока может опоздать на миллисекунду, из-за чего второй поток подумает, что никакой ошибки не было, и продолжит работу.
Если ваш код приводит в действие какое-нибудь потенциально опасное устройство, то ценой такой ошибки может быть чья-нибудь жизнь. Такое случилось с кодом для аппарата лучевой терапии Therac-25 — как минимум два человека умерло и ещё больше пострадали из-за превышения дозы радиации.
Исключения в программах
Также во время работы программы могут возникать ситуации, которые мешают корректной работе программы. Например, если вы просите пользователя ввести число, а он вводит строку.
Конвертировать введённое значение не всегда возможно, поэтому функция, которая занимается преобразованием, «выбрасывает» исключение (англ. exception). Это специальное сообщение говорит о том, что что-то идёт не так.
Если разработчик не описывает логику работы программы при вы выбрасывании исключения, то программа аварийно закрывается. Подробнее мы рассказали об этом в статье про ввод и конвертацию в C++.
Одно из самых известных исключений — переполнение стека (англ. stack overflow). В честь него даже назвали сайт, на котором программисты ищут помощь в решении своих проблем.
Компилятор C++ при этом может выдать ошибку сегментации, а не сообщение о переполнении стека:
Вот аналогичный код на языке C#:
Однако сообщение в этот раз более конкретное:
В обоих случаях программа завершается, потому что не может дальше корректно работать.
Похожая ситуация — переполнение буфера (англ. buffer overflow). Она происходит, когда записываемое значение больше выделенной области в памяти.
Обратите внимание, что мы получили предупреждение об арифметическом переполнении (англ. integer overflow):
Тем не менее программа скомпилировалась. Если же такая ситуация возникнет во время вычислений, то мы можем не получить предупреждения.
Арифметическое переполнение стало причиной одной из самых дорогих аварий, произошедших из-за ошибки в коде. В 1996 году ракета-носитель «Ариан-5» взорвалась на 40-й секунде полёта — потери оценивают в 360–500 миллионов долларов.
Как избежать всех этих ошибок
К сожалению, вручную всё это заметить и исправить не получится. Однако существуют различные инструменты и технологии, которые могут помочь.
Один из таких инструментов — отладчик. Он помогает контролировать ход работы программы, чтобы отслеживать разные показатели.
Второй, более эффективный метод — unit-тесты. Они представляют из себя набор описанных ситуаций для каждого компонента программы с указанием ожидаемого поведения.
Например, у вас есть функция sum (int a, int b), которая возвращает сумму двух чисел. Вы можете написать unit-тесты, чтобы проверять следующие ситуации:
Если какой-то из этих тестов не пройден, вы узнаете об этом и сможете всё исправить. Это намного быстрее, чем проверять всё вручную.
Заключение
Ошибок существует слишком много. При этом самые опасные тяжелее обнаружить, что только усугубляет ситуацию.
Если вы хотите научиться писать качественный код и находить в нём ошибки, вы можете записаться на наш курс по разработке на C++.