Defensive Programming 15 213 5 20 Bugs per 1000 lines of code InfoWorld Oct 2003 The course that gives CMU its Zip Programmers must anticipate bugs even if your code is bugbug free How Debugging April 6 2004 Check for errors at all possible opportunities detecting bugs early eases finding the root cause Maintain a clean modular structure with documented interfaces goto s global variables long jumps clever obscure macros etc considered harmful dangerous Anticipate common errors buffer overrun off by one Consider corner cases 0 1 loops empty lists Provide debugging support in your program debugging messages data structure checkers like the Heap checker from the malloc lab print function for complicated structures test case generators Add redundancy Maintain test cases for regression testing use version control systems CVS RCS BitKeeper Subversion Use all the help you can get heed compiler warnings use debuggers verifyers IDE s code generators high level tools Topics Defensive programming Know your bugs Debugging Tricks Overview of available tools 2 class23 ppt Assertions Debug Messages Explicitly state what you expect to be true in your program invariants argument ranges etc Use of cppcpp macros and conditional compilation AssertAssert macro ISO9899 ANSI C 15 213 S 04 ifdef DEBUG extern int debug level define DEBUG PRINT level format args if level debug level fprintf stderr BEBUG PRINT line d in file s n LINE FILE fprintf stderr format args else define DEBUG PRINT level format args endif include assert h Generates no tests if NODEBUG is defined define MAX ARRAY SIZE 10 void foo double a double b int n int i double a ptr a b ptr b assert n 1 n MAX ARRAY SIZE for i n i a ptr b ptr foo int a int b DEBUG PRINT 0 foo a d b d started n a b assert a ptr a n b ptr b n 3 15 213 S 04 4 Page 1 15 213 S 04 Add Redundancy Integrated Development Environment Engineering tradeoff between robustness and performance ProgramProgram editor with syntax support version control system compiler debugger buildbuild system profiler graphical user interface and integration IDE Extreme case Google Microsoft Visual IBM s Eclipse project Data structures have software maintained checksums Distributed system 10 000 machines need fail stop characteristic handle failures at higher level Kdevelop open source Simple Cases Pro convenience Con often platform dependent Count item and compare to pointer difference see assertion example No silver bullet Compute simple inexpensive invariants for example the sum of allocated and free memory objects in the heap ought to equal the heap size 5 15 213 S 04 15 213 S 04 6 Debugging History Early Debugging In 1945 G Hopper found the first bug in IBM s Harvard Mark I I an electroelectro mechanical computer Use of front pannel switches lights Other tools included Core dumps Print statements Hardware monitors Speakers 7 15 213 S 04 8 Page 2 15 213 S 04 Know your Bugs Encounter with a Bug Common bugs in CC programs Program produces unexpected result and or crashes Pointer bugs Dynamic memory allocation deallocation bugs Memory leaks missing free calls Is this behavior reproducible Does it depend on input data Does it change with compilation options g vs O2 Buffer overflow bugs First goal narrow the possible code range that could be responsible for the bug Arrays out of bound errors off by one Exception handling Variable scope problems see linking lecture Race conditions in multi threaded codes Divide Conquer Simplify the code that shows the bug In case of rare intermittent bugs try to cause the program to fail more frequently Add logging or debugging printouts to pinpoint the approximate location of the failure Other bugs not considered in this class Specification errors Performance bugs Program logic errors bad algorithms data structures etc 15 213 S 04 9 10 15 213 S 04 GDB GNU DeBugger DDD Basic functionality Graphical frontfront end to GDB with extended data visualization support http www gnu org software ddd http www gnu org software ddd Can run programs in an observable environment Uses ptrace interface to insert breakpoint single step inspect change registers and variables Does not require compilation with g but works much better if it has the symbol tables available Maintains source line numbers and can inspect source files Ability to attach to a running process Ability to watch memory locations Conditional breakpoints Some graphical user interfaces exist DDD KDbg 11 15 213 S 04 12 Page 3 15 213 S 04 Annoyingly Frequent Case Dogtags Memory corruption due to an earlier pointer or dynamic memory allocation error bug cause and effect are separated by 1000 s of instructions GDB style watch points are frequently too slow to be used in large complex programs ifdef USE DOG TAGS define DOGTAG x int x else define DOGTAG x endif Use GDB to watch the corruption happen Use conditional breakpoints break if cond Set a watchpount r a watch expr Use dog tags in your program Use a debugging version of malloc struct foobar DOGTAG dt1 int buf 20 DOGTAG dt2 If dogtags are enabled maintain a list of all allocated dogtags easier with C class objects using the constructor Initialize dogtags to a distinct value e g 0xdeadbeeef Use run time verification tools Provide function that checks the integrity of the dogtags When to call this function 15 213 S 04 13 15 213 S 04 14 Dogtags continued Dynamic Memory Allocation Checker Call check funtion near suspect codes by manually inserting calls or hack hack alert alert malloc malloc and friends are a frequent source of trouble therefore there are numerous debugging aids for this problem The typical functionality include Padding the allocated area with dogtags that are checked when any dynamic memory allocation functions are called or on demand Checking for invalid free calls multiple with bad argument ifdef AUTO WATCH DOG TAGS define if expr if CHECK WATCHED DOG TAGS expr define while expr while CHECK WATCHED DOG TAGS expr define switch expr switch CHECK WATCHED DOG TAGS expr endif AUTO WATCH DOG TAGS 15 Checking for access to freed memory regions Keeping statistics of the heap utilization Logging 15 213 S 04 16 Page 4 15 213 S 04 Boehm Weiser Conservative Garbage Collector MALLOC CHECK In recent versions of Linux libc later than 5 4 23 and GNU libc 2 x defining MALLOC CHECK causes extra checks to be enabled at the expense of lower speed Ref http www hpl hp com personal Hans Boehm gc http www hpl hp com personal Hans Boehm gc Idea forget about free calls
View Full Document