Если вы пишете код на C, Objective-C или C ++, вы можете использовать CLang Static Analyzer, чтобы критиковать ваш источник, фактически не запуская его.
Доступны некоторые инструменты отладки памяти: ValGrind, Guard Malloc в Mac OS X, Electric Fence в * NIX.
Некоторые среды разработки предоставляют возможность использовать распределитель памяти для отладки, который выполняет такие вещи, как заполнение вновь выделенных страниц и недавно освобожденных страниц мусором, обнаружение освобождения нераспределенных указателей и запись некоторых данных до и после каждого блока кучи, причем отладчик является вызывается, если известный шаблон этих данных когда-либо меняется.
Какой-то парень из Slashdot сказал, что он получил большую выгоду от пошагового создания новой строки исходного кода в отладчике. «Вот и все», сказал он. Я не всегда следую его совету, но когда он у меня был, он мне очень помог. Даже если у вас нет тестового примера, который стимулирует необычный путь кода, вы можете вертеть переменную в своем отладчике, чтобы взять такие пути, скажем, выделив некоторую память, а затем с помощью отладчика установить новый указатель на NULL вместо адрес памяти, затем пошаговое выполнение обработчика ошибок выделения.
Используйте утверждения - макрос assert () в C, C ++ и Objective-C. Если ваш язык не предоставляет функцию assert, напишите ее самостоятельно.
Используйте утверждения свободно, а затем оставьте их в своем коде. Я вызываю assert () "Тест, который продолжает тестирование". Я использую их чаще всего для проверки предварительных условий в точке входа большинства моих функций. Это одна из частей «Программирование по контракту», которая встроена в язык программирования Eiffel. Другая часть - это постусловия, то есть использование assert () в точках возврата функции, но я обнаружил, что я не получаю от этого столько же пробега, сколько предварительные условия.
Вы также можете использовать assert для проверки инвариантов класса. Хотя ни один класс строго не должен иметь инварианта вообще, у наиболее разумно разработанных классов они есть. Инвариант класса - это некое условие, которое всегда истинно, кроме как внутри функций-членов, которые могут временно переводить ваш объект в противоречивое состояние. Такие функции всегда должны восстанавливать согласованность, прежде чем вернуться.
Таким образом, каждая функция-член может проверять инвариант при входе и выходе, а класс может определять функцию с именем CheckInvariant, которую любой другой код может вызывать в любое время.
Используйте инструмент покрытия кода, чтобы проверить, какие строки вашего источника на самом деле тестируются, а затем спроектируйте тесты, которые стимулируют непроверенные строки. Например, вы можете проверить обработчики нехватки памяти, запустив ваше приложение внутри виртуальной машины, которая настроена с небольшим количеством физической памяти, и без файла подкачки или очень маленького.
(По какой-то причине я никогда не был в курсе, хотя BeOS мог работать без файла подкачки, он был крайне нестабильным. Доминик Джампаоло, который писал файловую систему BFS, убеждал меня никогда не запускать BeOS без подкачки. понимаю, почему это должно иметь значение, но это должен быть какой-то артефакт реализации.)
Вам также следует проверить реакцию своего кода на ошибки ввода-вывода. Попробуйте сохранить все свои файлы в общем сетевом ресурсе, а затем отсоедините сетевой кабель, когда приложение загружено. Аналогичным образом отсоедините кабель - или выключите беспроводную связь - если вы общаетесь по сети.
Одна вещь, которую я нахожу особенно раздражающей, это сайты, которые не имеют надежного кода Javascript. Страницы Facebook загружают десятки маленьких файлов Javascript, но если какой-либо из них не удается загрузить, вся страница разрывается. Просто должен быть какой-то способ либо обеспечить некоторую отказоустойчивость, скажем, путем повторной загрузки, либо предоставить какой-то разумный запасной вариант, когда некоторые из ваших сценариев не загружались.
Попробуйте убить ваше приложение с помощью отладчика или с помощью команды "kill -9" в * NIX, пока оно находится в середине написания большого, важного файла. Если ваше приложение хорошо спроектировано, весь файл будет записан или не будет записан вообще, или, может быть, если он будет записан только частично, то, что записывается, не будет повреждено, а сохраненные данные будут полностью использованы приложение после перечитывания файла.
базы данных всегда имеют отказоустойчивый дисковый ввод-вывод, но вряд ли какое-либо другое приложение имеет. Хотя журнализированные файловые системы предотвращают повреждение файловой системы в случае сбоя питания или сбоев, они вообще ничего не делают для предотвращения повреждения или потери данных конечного пользователя. За это отвечают пользовательские приложения, но вряд ли кто-либо, кроме баз данных, реализует отказоустойчивость.