350 likes | 361 Views
Learn how to measure and improve defect potential and removal efficiency to reduce maintenance costs, shorten development schedules, and enhance software quality.
E N D
Microprocessors, AdvancedProfessional Debugging II February 3, 2012Jack Ganssle
Two Important Measures Defect potential= number of bugs found in development + those found within 90 days of delivery Defect removal efficiency = percent removed in development
Measuring Defects “When these measures were introduced into large corporations such as IBM and ITT, in less than four years the volumes of delivered defects had declined by more than 50%; maintenance costs were reduced by more than 40%; development schedules were shortened by more than 15%. There are no other measurements that can yield such positive benefits in such a short time span.” - Capers Jones Percent of bugs shipped
// Find the positive solution of a quadratic // equation. float solve_pos(float a, float b, float c) { float32_t result; result = (-b + sqrt(b*b - 4*a*c))/(2*a); return result; }
// Find the positive solution of a quadratic // equation. float solve_pos(float32_t a, b, c) { float32_t result; result = (-b + sqrt(b*b - 4*a*c))/(2*a); return result; }
// Find the positive solution of a quadratic // equation. float solve_pos(float32_t a, b, c) { float32_t result; assert (a!=0); assert ((b*b-4*a*c) >= 0); result = (-b + sqrt(b*b - 4*a*c))/(2*a); assert (isnormal(result)); return result; }
What’s wrong with assert()? An assertion is true for one point in time Assertions can have side effects assert(y > 0 && x = MAX) assert(pop(x) == 0)
#define precondition(a) ((void)(a), assert(a)) #define postcondition(a)((void)(a), assert(a)) //lint -emacro(730,require) Better Than Assert() precondition(n>=0); precondition(m=n); warning 666 - expression with side effects precondition(g(m)); warning 666 - expression with side effects
// Find the positive solution of a quadratic // equation. float solve_pos(float32_t a, b, c) { float32_result; precondition (a!=0); precondition ((b*b-4*a*c) >= 0); result = (-b + sqrt(b*b - 4*a*c))/(2*a); postcondition (isnormal(result)); return result; }
// Push a number on a stack void push(int data) { *count = data; ++count; }
// Push a number on a stack void push(int data) { precondition (count != NULL); *count = data; ++count; postcondition (*(count-1) == data); postcondition (count <= BUFFER_END); }
What to Check Fail fast! Don’t check for correct inputs from error-prone devices… like people. Do check for “impossible” conditions No side effects: “=“ is not allowed Do check for “obvious” situations
Faster Debugging Cost to Fix Bug Number
$500m… or 3 Preconditions? This: Or this: Require horizontal bias < 215
Production Code? A philosophical issue. NASA’s mantra: “test what you fly, fly what you test.” Resource issues may mean assertions should be removed.
malloc() - the Curse of Embedded Systems • Problems: • Heap fragmentation! • May be slow • No one knows how to compute heap size
malloc() - the Curse of Embedded Systems • Solutions: • Use static allocation • Always, always check malloc()’s return value • And the argument passed to it! • Use multiple heaps: • http://members.chello.nl/h.robbers/ • http://www.fourmilab.ch/bget/
malloc() - the Curse of Embedded Systems • mem - a malloc() diagnostic tool: • Detects extra free()s • Detects point over- and under-runs • Finds out of memory conditions • Plus… it will find memory leaks. • http://www8.cs.umu.se/~isak/snippets/
Measure Idle Time while(1) { set_bit(): unset_bit(); handle_other_stuff; }
uC/OS-II Idle Task Hook /************************************************* IDLE TASK HOOK **************************************************/ void OSTaskIdleHook (void) { outportb(test_port, 1); // Assert pin outportb(test_port, 0); // … but just for a moment } On a 33 MHz 186 this adds just 480 nsec of overhead.
A $15 VOM == $10k Performance Analyzer 8.6% duty cycle Change 29.2K resistor to: R=(duty cycle/100) * (Max volts) * 2kΩ
Measuring Task Activity /******************************** ASK SWITCH HOOK ********************************/ void OSTaskSwHook (void) { outportb(test_port, OSTCBCur->OSTCBId); } R-2R Ladder
Seeding Memory • Always program unused flash to logical states: • SWI on ARM CPUs • Illegal instruction on 68k CPUs • INT3 on x86 CPUs • Any software interrupt