Download presentation
Presentation is loading. Please wait.
1
debugging, bug finding and bug avoidance Part 4
Alan Dix
2
outline part 1 – general issues and heuristics
part 2 – the system as it is understand and document part 3 – locating and fixing bugs part 4 – bug engineering design to expose, avoid and recover including fail-fast programming
3
debugging – part 4 bug engineering
simplicity fail-fast programming factoring limiting effects of error
4
simplicity simple code is correct code
5
simplicity avoid Tower of Babel dead code unnecessary optimisations
long chains of method calls deep subclass trees dead code once was needed / may be needed someday! unnecessary optimisations instead profile then optimise where needed
6
simplicity DO choose simple data structures choose simple algorithms
arrays / other pre-supplied data static vs. dynamic allocated (esp. in C/C++) choose simple algorithms linear searches etc. implement key paths first design class structure for generality implement methods necessary for early use/test + incremental delivery, no dead code
7
fail fast coding if it is going to fail fail sooner rather than later
during testing rather than use ‘cos then you can fix it
8
fail fast coding general principles
constant checking data integrity, logical integrity log, throw exception (or crash!) avoid special cases the worst case will eventually happen reused code is heavily tested code
9
fail fast coding internal consistency
C/C++ assert char *c = getname(); assert( c!=NULL ); validation methods and exceptions obj.doSomethingComplicated(); obj.check(); class A { public void check() throws CheckException { }
10
fail fast coding cross checking
test method list.fastSortMethod(); if ( ! list.isSorted() ) ... parallel execution temp = list.clone(); temp.slowButSimpleSortMethod(); if ( ! list.equals(temp) ) ...
11
fail fast coding magic values
special arbitrary value - just to check many file formats first few bytes special identify format can add to your own data file formats, version markers C/C++ around dynamic structures (for buffer overrun bugs etc.) GIF89a ..... ... binary.. ... data ...
12
fail fast coding real time systems
Byzantine cases branch testing not sufficient evaluate and discard best case = worst case fast enough during testing always fast enough
13
submarine cable tracker
user interface memory 68xxx control processor Texas DSP sensor array 20ms interrupt loop shared memory A-to-D
14
fail fast coding internal reuse
same code used in several places method, function, iteration or copy more uses of same code more likely to find bugs copying may introduce differences
15
fail fast coding table driven code
form of reuse replace long-hand code original long-hand code if ( 3 < x && x <= 7 ) return “hello”; if ( 19 < x && x <= 23 ) return “world”; ... return “default”;
16
fail fast coding table driven code
long-hand code -> table + loop table in file or code min max val 3 7 hello world ... for ( i=0; i<t.len; i++) { if ( t[i].min < x && x <= t[i].max ) return t[i].val; } return “default”; if ( 3 < x && x <= 7 ) return “hello”; if ( 19 < x && x <= 23 ) return “world”; ... return “default”;
17
fail fast coding generated code
if ( 3 < x && x <= 7 ) return “hello”; if ( 19 < x && x <= 23 ) return “world”; min max val 3 7 hello world ... code compile generator program for ( i=0; i<t.len; i++) { print(“if ( “+ t[i].min +” < x”); print(“ && x <= “+ t[i].max +” )\n”); print(“\t return \“”+ t[i].val +”\”;\n”); }
18
factoring communication component 1 component 2 monitor component 2
replay offline record
19
factoring in code introduce intermediate data structures
res = complexCalculation(); introduce intermediate data structures intermediate_val = complexPart1(); // check and/or print intermediate_val res = complexPart2(intermediate_val); exposes hidden state
20
factoring through files
program 1 complex program part 1 part2 object.write() object object object object.read() program 2
21
factoring through protocols
network client server instrument client and/or server log or use proxy client server proxy
22
limiting effects of error
“file format error - aborting” when one subsystem goes wrong protect the rest of the system best efforts to recover during testing – allows further tests when deployed – allows continued use do log/warn of problem!
23
limiting effects of error safety net
check bounds etc., sanitise values beware non-termination, memory hogs component main program checks
24
limiting effects of error sandbox
component other components e.g. applet entirely quarantine component prevent unauthorized actions
25
limiting effects of error guardian
monitor critical interfaces on failure - reset or intervene guardian outputs inputs
26
limiting effects of error in code
pre-post checks outputs of subcomponents inputs to methods wrapper/proxy classes VM/OS support memory protection Unix/WinNT/MacOsX Java classloader/security manager
27
limiting effects of error self-healing data
parameters null default value data files calculate/default missing values ignore unexpected values sentinels for easy parsing old format new format conversions data operations check and tidy-up data structures attribute/property lists for extensibility (beware also)
28
limiting effects of error workarounds
avoid bad values document, wrap with protective code alternative code for bad cases restart frequently especially for memory leaks recover after error backup/recovery points, adjust environment more memory, time, etc.
29
if you think it will be perfect
last word if you think it will be perfect things will fail accept you aren’t and things may work
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.