🐞Виды ошибок. Методы отладки

Прежде всего определимся с некоторыми понятиями, связанными с отладкой программного обеспечения.

Откуда берутся ошибки в ПО?

Почему бывает так, что программы работают неправильно? Все очень просто – они создаются и используются людьми. Если пользователь допустит ошибку, то это может привести к проблеме в работе программы – она используется неправильно, значит, может повести себя не так, как ожидалось.

Ошибка (error) – это действие человека, которое порождает неправильный результат.

Однако программы разрабатываются и создаются людьми, которые также могут допускать (и допускают) ошибки. Это значит, что недостатки есть и в самом программном обеспечении. Они называются дефектами или багами (оба обозначения равносильны). Здесь важно помнить, что программное обеспечение – нечто большее, чем просто код.

Дефект, Баг (Defect, Bug) – недостаток компонента или системы, который может привести к отказу определенной функциональности (невозможности выполнить требуемую функцию, например, неверный оператор или определение данных).

Дефект, обнаруженный во время исполнения программы, может вызвать отказ отдельного компонента или всей системы.

При исполнении кода программы дефекты, заложенные еще во время его написания, могут проявиться: программа может не делать того, что должна или наоборот делать то, чего не должна – происходит сбой.

Сбой (failure) – несоответствие фактического результата (actual result) работы компонента или системы ожидаемому результату (expected result).

Программная ошибка — это расхождение между программой и ее спецификацией, причем тогда и только тогда, когда спецификация существует и она правильна.

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

Локализация — это определение оператора/операторов программы, выполнение которого вызвало нарушение вычислительного процесса

Для исправления ошибки необходимо определить ее причину, т.е. установить оператор или фрагмент, содержащие ошибку. Причины ошибок могут быть как очевидны, так и очень глубоко скрыты.

Сбой в работе программы может являться индикатором наличия в ней дефекта.

Баг существует при одновременном выполнении 3-х условий:

  • Известен ожидаемый результат

  • Известен фактический результат

  • Фактический результат существенно отличается от ожидаемого результата

Важно понимать, что не все баги становятся причиной сбоев – некоторые из них могут никак себя не проявлять и оставаться незамеченными (или проявляться только при очень специфических обстоятельствах).

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

Всего существует несколько источников дефектов и, соответственно, сбоев:

  • Ошибки в спецификации, дизайне или реализации программной системы;

  • Ошибки использования системы;

  • Неблагоприятные условия окружающей среды;

  • Умышленное причинение вреда;

  • Потенциальные последствия предыдущих ошибок, условий или умышленных действий;

Дефекты могут возникать на разных уровнях, и от того, будут ли они исправлены и когда, будет напрямую зависеть качество системы.

Как определить дефект?

Вот список того, как можно понять что перед нами какой-то недостаток:

  1. Программа не делает чего-то, что она должна делать согласно техническим требованиям.

  2. Программа делает что-то, чего она не должна делать согласно техническим требованиям.

  3. Программа делает что-то, о чем в требованиях не упоминалось (?).

  4. Программа не делает чего-то, о чем не говорится в требованиях, однако подразумевается, что она должна делать это.

  5. Программа трудна для понимания, неудобна в использовании.

Классификации ошибок

Также нижнюю часть окна редактора кода компилятор выводит сообщения об ошибках. Первая ошибка – это первая от начала текста программы синтаксическая ошибка, обнаруженная компилятором. Наличие в тексте даже одной синтаксической ошибки приводит к возникновению второй, фатальной ошибки (Fatal Error) – невозможности генерации исполняемой программы.

Возможнные причины возникновения ошибок

  • Неверное определение исходных данных

  • Логические ошибки

  • Накопление погрешностей результатов вычислений(ошибки накопления погрешностей)

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

Логические ошибки имеют разную природу и могут следовать из ошибок, допущенных при проектировании, например, при выборе методов, разработке алгоритмов или определении структуры классов, а могут быть непосредственно внесены при кодировании модуля.

Ошибки кодирования:

  • Ошибки некорректного использования переменных, например, неудачный выбор типов данных, использование переменных до их инициализации, использование индексов, выходящих за границы определения массивов, нарушения соответствия типов данных при использовании явного или неявного переопределения типа данных, расположенных в памяти при использовании нетипизированных переменных, открытых массивов, объединений, динамической памяти, адресной арифметики;

  • Ошибки вычислений, например, некорректное использование неарифметических переменных, некорректная работа с целочисленными переменными, некорректное преобразование типов данных в процессе вычислений;

  • Ошибки взаимодействия модулей, т.е. межмодульного интерфейса, например, нарушение типов и последовательности при передаче параметров, несоблюдение единства единиц измерения формальных и фактических параметров, нарушение области действия локальных и глобальных переменных

  • Неправильная реализация логики программы при кодировании;

  • Игнорирование особенностей или ограничений конкретного языка программирования.

Пример ошибки кодирования. В языке C++ требуется указывать точку с запитой в конце после каждого законченного выражения. Если не поставить точку с запитой, то произойдёт синтаксическая ошибка и компилятор об этом сообщит.

...
std::cout << "Hello World" << std::endl // <-- ERROR
...
...
std::cout << "Hello World" << std::endl; // <-- Hello World

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

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

Сложность отладки может возрастать вследствие влияния следующих факторов:

  • Опосредованное проявление ошибок;

  • Возможность взаимного влияния ошибок;

  • Возможность получения внешне одинаковых проявлений разных ошибок;

  • Отсутствие повторяемости проявлений некоторых ошибок от запуска к запуску (стохастические ошибки);

  • Возможности устранения внешних проявлений ошибок в исследуемой ситуации при внесении некоторых изменений в программу, например, при включении в программу диагностических фрагментов может аннулироваться или измениться внешнее проявление ошибок;

  • Написания отдельных частей программы разными программистами.

Методы отладки программ можно классифицировать следующим образом:

  • метод ручного тестирования;

  • метод индукции;

  • метод дедукции;

  • метод обратного прослеживания.

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

Метод индукции основан на тщательном анализе симптомов ошибки, которые могут проявляться как неверные результаты вычислений или как сообщение об ошибке. Если компьютер просто «зависает», то фрагмент проявления ошибки вычисляют исходя из последних полученных результатов и действий пользователя. Полученную таким образом информацию можно изучить, просматривая соответствующий фрагмент программы. В результате выдвигаются гипотезы об ошибках, которые затем проверяются. Если гипотеза верна, то детализируют информацию об ошибке, иначе — выдвигают другую гипотезу. Собирая данные об ошибке, необходимо зафиксировать все, что известно об ее проявлениях, причем принимают во внимание, как ситуации, в которых фрагмент с ошибкой выполняется нормально, так и ситуации, в которых ошибка проявляется. Если в результате изучения данных никаких гипотез не появляется, то необходима дополнительная информация об ошибке.

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

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

Подробнее о различных ошибках здесь.

Last updated