Software Engineering for Students A Programming Approach
Software Engineering for Students A Programming Approach Software Engineering for Students A Programming Approach
17.2 Fault detection by software 241 In general, it seems that compile-time checking is better than run-time checking. However, run-time checking has the last word. It is vital because not everything can be checked at compile time. SELF-TEST QUESTION 17.2 Add to the list above checks that can only be done at run-time and therefore, by implication, cannot be done at compile-time. Incidentally, it is common practice to switch on all sorts of automatic checking for the duration of program testing, but then to switch off the checking when development is complete – because of concern about performance overheads. For example, some C++ compilers allow the programmer to switch on array subscript checking (during debugging and testing), but also allow the checking to be removed (when the program is put into productive use). C.A.R Hoare, the eminent computer scientist, has compared this approach to that of testing a ship with the lifeboats on board but then discarding them when the ship starts to carry passengers. We have looked at automatic checking for general types of fault. Another way of detecting faults is to write additional software to carry out checks at strategic times during the execution of a program. Such software is sometimes called an audit module, because of the analogy with accounting practices. In an organization that handles money, auditing is carried out at different times in order to detect any fraud. An example of a simple audit module is a method to check that a square root has been correctly calculated. Because all it has to do is to multiply the answer by itself, such a module is very fast. This example illustrates that the process of checking for faults by software need not be costly – either in programming effort or in run-time performance. SELF-TEST QUESTION 17.3 Devise an audit module that checks whether an array has been sorted correctly. Another term used to describe software that attempts to detect faults is defensive programming. It is normal to check (validate) data when it enters a computer system – for example, numbers are commonly scrupulously checked to see that they only contain digits. But within software it is unusual to carry out checks on data because it is normally assumed that the software works correctly. In defensive programming the programmer inserts checks at strategic places throughout the program to provide detection of design errors. A natural place to do this is to check the parameters are valid at the entry to a method and then again when a method has completed its work. This approach has been formalized in the idea of assertions, explained below.
242 Chapter 17 ■ Software robustness 17.3 ● Fault detection by hardware We have already seen how software checks can reveal faults. Hardware also can be vital in detecting consequences of such software errors as: ■ division by zero, more generally arithmetic overflow ■ an array subscript outside the range of the array ■ a program which tries to access a region of memory that it is denied access to, e.g. the operating system. Of course hardware also detects hardware faults, which the hardware often passes on to the software for action. These include: ■ memory parity checks ■ device time-outs ■ communication line faults. Memory protection systems One major technique for detecting faults in software is to use hardware protection mechanisms that separate one software component from another. (Protection mechanisms have a different and important role in connection with data security and privacy, which we are not considering here.) A good protection mechanism can make an important contribution to the detection and localization of bugs. A violation detected by the memory protection mechanism means that a program has gone berserk – usually because of a design flaw. To introduce the topic we will use the analogy of a large office block where many people work. Along with many other provisions for safety, there will usually be a number of fire walls and fire doors. What exactly is their purpose? People were once allowed to smoke in offices and public buildings. If someone in one office dropped a cigarette into a waste paper basket and caused a fire, the fire walls helped to save those in other offices. In other words, the walls limited the spread of damage. In computing terms, does it matter how much the software is damaged by a fault? – after all it is merely code in a memory that can easily be re-loaded. The answer is “yes” for two reasons. First, the damage caused by a software fault might damage vital information held in files, damage other programs running in the system or crash the complete system. Second, the better the spread of damage is limited, the easier it will be to attempt some repair and recovery. Later, when the cause of the fire is being investigated, the walls help to pinpoint its source (and identify the culprit). In software terminology, the walls help find the cause of the fault – the bug. One of the problems in designing buildings is the question of where to place the firewalls. How many of them should there be, and where should they be placed? In software language, this is called the issue of granularity. The greater the number of walls, the more any damage will be limited and the easier it will be to find the cause. But walls are expensive and they also constrain normal movement within the building.
- Page 213 and 214: 190 Chapter 14 ■ The basics Ada d
- Page 215 and 216: 192 Chapter 14 ■ The basics The w
- Page 217 and 218: 194 Chapter 14 ■ The basics In a
- Page 219 and 220: 196 Chapter 14 ■ The basics > str
- Page 221 and 222: 198 Chapter 14 ■ The basics Answe
- Page 223 and 224: CHAPTER 15 Object-oriented programm
- Page 225 and 226: 202 Chapter 15 ■ Object-oriented
- Page 227 and 228: 204 Chapter 15 ■ Object-oriented
- Page 229 and 230: 206 Chapter 15 ■ Object-oriented
- Page 231 and 232: 208 Chapter 15 ■ Object-oriented
- Page 233 and 234: 210 Chapter 15 ■ Object-oriented
- Page 235 and 236: 212 Chapter 15 ■ Object-oriented
- Page 237 and 238: 214 Chapter 15 ■ Object-oriented
- Page 239 and 240: 216 Chapter 15 ■ Object-oriented
- Page 241 and 242: 218 Chapter 15 ■ Object-oriented
- Page 243 and 244: 220 Chapter 15 ■ Object-oriented
- Page 245 and 246: 222 Chapter 16 ■ Programming in t
- Page 247 and 248: 224 Chapter 16 ■ Programming in t
- Page 249 and 250: 226 Chapter 16 ■ Programming in t
- Page 251 and 252: 228 Chapter 16 ■ Programming in t
- Page 253 and 254: 230 Chapter 16 ■ Programming in t
- Page 255 and 256: 232 Chapter 16 ■ Programming in t
- Page 257 and 258: 234 Chapter 16 ■ Programming in t
- Page 259 and 260: 236 Chapter 16 ■ Programming in t
- Page 261 and 262: 238 Chapter 17 ■ Software robustn
- Page 263: 240 Chapter 17 ■ Software robustn
- Page 267 and 268: 244 Chapter 17 ■ Software robustn
- Page 269 and 270: 246 Chapter 17 ■ Software robustn
- Page 271 and 272: 248 Chapter 17 ■ Software robustn
- Page 273 and 274: 250 Chapter 17 ■ Software robustn
- Page 275 and 276: 252 Chapter 17 ■ Software robustn
- Page 277 and 278: 254 Chapter 17 ■ Software robustn
- Page 279 and 280: 256 Chapter 17 ■ Software robustn
- Page 281 and 282: 258 Chapter 17 ■ Software robustn
- Page 283 and 284: 260 Chapter 18 ■ Scripting GNU/Li
- Page 285 and 286: 262 Chapter 18 ■ Scripting In sum
- Page 288: PART D VERIFICATION
- Page 291 and 292: 268 Chapter 19 ■ Testing We begin
- Page 293 and 294: 270 Chapter 19 ■ Testing within a
- Page 295 and 296: 272 Chapter 19 ■ Testing Test num
- Page 297 and 298: 274 Chapter 19 ■ Testing if (a >=
- Page 299 and 300: 276 Chapter 19 ■ Testing 3. apply
- Page 301 and 302: 278 Chapter 19 ■ Testing made con
- Page 303 and 304: 280 Chapter 19 ■ Testing 19.3 Dev
- Page 305 and 306: 282 Chapter 19 ■ Testing 19.2 The
- Page 307 and 308: 284 Chapter 20 ■ Groups The term
- Page 309 and 310: 286 Chapter 20 ■ Groups Of course
- Page 311 and 312: 288 Chapter 20 ■ Groups • Exerc
17.2 Fault detection by software 241<br />
In general, it seems that compile-time checking is better than run-time checking.<br />
However, run-time checking has the last word. It is vital because not everything can<br />
be checked at compile time.<br />
SELF-TEST QUESTION<br />
17.2 Add to the list above checks that can only be done at run-time and<br />
there<strong>for</strong>e, by implication, cannot be done at compile-time.<br />
Incidentally, it is common practice to switch on all sorts of automatic checking <strong>for</strong><br />
the duration of program testing, but then to switch off the checking when development<br />
is complete – because of concern about per<strong>for</strong>mance overheads. For example,<br />
some C++ compilers allow the programmer to switch on array subscript checking (during<br />
debugging and testing), but also allow the checking to be removed (when the program<br />
is put into productive use). C.A.R Hoare, the eminent computer scientist, has<br />
compared this approach to that of testing a ship with the lifeboats on board but then<br />
discarding them when the ship starts to carry passengers.<br />
We have looked at automatic checking <strong>for</strong> general types of fault. Another way of<br />
detecting faults is to write additional software to carry out checks at strategic times<br />
during the execution of a program. Such software is sometimes called an audit module,<br />
because of the analogy with accounting practices. In an organization that handles<br />
money, auditing is carried out at different times in order to detect any fraud. An<br />
example of a simple audit module is a method to check that a square root has been<br />
correctly calculated. Because all it has to do is to multiply the answer by itself, such a<br />
module is very fast. This example illustrates that the process of checking <strong>for</strong> faults by<br />
software need not be costly – either in programming ef<strong>for</strong>t or in run-time per<strong>for</strong>mance.<br />
SELF-TEST QUESTION<br />
17.3 Devise an audit module that checks whether an array has been sorted<br />
correctly.<br />
Another term used to describe software that attempts to detect faults is defensive programming.<br />
It is normal to check (validate) data when it enters a computer system – <strong>for</strong><br />
example, numbers are commonly scrupulously checked to see that they only contain<br />
digits. But within software it is unusual to carry out checks on data because it is normally<br />
assumed that the software works correctly. In defensive programming the programmer<br />
inserts checks at strategic places throughout the program to provide detection<br />
of design errors. A natural place to do this is to check the parameters are valid at the<br />
entry to a method and then again when a method has completed its work. This<br />
approach has been <strong>for</strong>malized in the idea of assertions, explained below.