Главная - Литература

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 [67] 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294

Пример метода, проверяющего указатели во время разработки (С++)

- Этот метод проверяет любой переданный ему указатель. Во время разработки ее можно использовать для стольких проверок, сколько вы сможете выдержать.

->voicl CheckPointer( void *pointer ) {

выполнить проверку 1 - например, что указатель не равен NULL выполнить проверку 2 - например, что какой-то его обязательный признак действителен выполнить проверку 3 - например, что область, на которую он указывает, не повреждена

выполнить проверку п-...

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

Пример метода, проверяющего указатели во время эксплуатации (С++)

- Эта процедура сразу же возвращает управление.

void CheckPointer( void *pointer ) {

никакого кода; просто возврат управления

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

8.7. Доля защитного программирования в промышленной версии

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

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



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

Удалите код, приводящий к прекращению работы программы Как я уже

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

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

Оставьте код, который позволяет аккуратно завершить работу программы Если программа содержит отладочный код, определяющий потенциально фатальные ошибки, оставьте его - это позволит элегантно завершить работу. Например, в марсоходе Pathfinder инженеры намеренно оставили часть отладочного кода. Ошибка произошла после того, как Pathfinder совершил посадку. С помощью отладочных средств, оставленных в нем, инженеры из лаборатории реактивных двигателей смогли диагностировать проблему и загрузить исправленный код. В результате Pathfinder полностью выполнил свою миссию (March, 1999).

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

Убедитесь, что оставленные сообщения об ошибках дружелюбны Если вы оставляете в программе внутренние сообщения об ошибках, проверьте, что они дружественны к пользователю. Пользователь одной из моих первых программ сообщила мне, что получила сообщение, гласившее: «У тебя неправильно выделена память для указателя, черт возьми!» К счастью для меня, у нее было чувство юмора. Общепринятым и эффективным подходом является уведомление пользователя о «внутренней ошибке» и вывод телефона и адреса электронной почты, по которым о ней можно сообщить.



8.8. Защита от защитного программирования

Избыток защитного программирования сам по себе созда-Слишком много wo-пибо-это

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

Контрольный список: защитное программирование Общие

http: cc2e.com/0S68 □ Реализована ли в методе защита от некорректных входных данных?

□ Используете ли вы утверждения для документирования допущений, включая пред- и постусловия?

□ Используются ли утверждения для документирования только тех условий, которые никогда не должны происходить?

□ Определены ли в архитектуре или высокоуровневом проекте системы технологии обработки ошибок?

□ Указано ли в архитектуре или высокоуровневом проекте системы, чему будет отдаваться предпочтение при обработке ошибок: устойчивости или корректности?

□ Построены ли баррикады для изоляции разрушительного эффекта ошибок и уменьшения объема кода, занятого в обработке ошибок?

□ Установлены ли отладочные средства таким образом, что их можно активизировать и деактивировать без особых проблем?

□ Хватает ли защитного кода: не слишком много и не слишком мало?

□ Использованы ли технологии наступательного программирования, чтобы затруднить пропуск ошибок на стадии разработки?

Исключения

□ Определен ли в проекте стандартизованный подход к обработке исключений?

□ Рассмотрены ли альтернативы использованию исключений?

□ Обрабатывается ли ошибка по возможности локально или генерируется нелокальное исключение?

□ Возможны ли исключения в конструкторах и деструкторах?

□ Генерируются ли исключения в методах на подходящих уровнях абстракции?

□ Содержит ли каждое исключение все относящиеся к нему исходные данные?

□ Свободен ли код от пустых блоков catch? (Или, если блок catch действительно допустим, задокументировано ли это?)



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 [67] 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294



0.0024