Шаг 43.
Некоторые причины, осложняющие поиск ошибок

    На этом шаге мы укажем некоторые причины, осложняющие поиск ошибок.

   

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

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

       

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

       

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

       

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

       

  5. Некоторые ошибки не проявляются сами по себе, а лишь приводят к возникновению других ошибок (так называемые наведенные ошибки), которые и наблюдает программист.

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

       

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

       

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

       

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

       

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

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

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

       

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

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

       

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

    Отладка программы - это прежде всего эксперимент, а не наблюдение за поведением программы. Различие между этими двумя понятиями удачно и точно охарактеризовал знаменитый русский физиолог И.П.Павлов, отметивший, что наблюдение собирает то, что ему предлагает природа, опыт же берет у природы то, что хочет. И, как всякий эксперимент, отладку нужно уметь проводить. Очень важно при этом делать правильные выводы на основании данных, полученных из эксперимента. То, насколько при этом можно ошибиться, наглядно демонстрирует следующая шутливая история [1].

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

    А "окончив" отладку, вспомните, что когда известного датского скульптора Торвальдсена спросили мнение об одной из его скульптур, он ответил: "Я не вижу в ней недостатков, из чего заключаю, что у меня хромает воображение".

   


(1) Боровин Г.К., Комаров М.М., Ярошевский В.С. Ошибки-ловушки при программировании на Фортране. - М.: Наука, 1987.

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




Предыдущий шаг Содержание Следующий шаг