TLS0102-001 MPLAB X Debugging Techniques The Debugging Process Author: Rob Ostapiuk, Stu Chandler Microchip Technology
Objectives! Describe a generic process for debugging a program! Describe at a high level various techniques that may be employed in the debug process! Implement these techniques in MPLAB X "Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." Brian W. Kernighan 2014 Microchip Technology Incorporated. All Rights Reserved. Slide 2
Development Tools Data Flow Debug and Test Points Debuggable Code Instrumentation src Source Files Header Files Preprocessor Compiler Macros Compiler Flags Static Checkers Selected Libraries lib Linker Library Files Debug Executive hex Linker Options Code Instrumentation Debugger Programmer MPLAB REAL ICE ACTIVE STATUS FUNCTION RESET TM Memory View, Stack View, Profiling Inputs Input Test Data Outputs 2014 Microchip Technology Incorporated. All Rights Reserved. Slide 3
The Four Steps of the Debugging Process BUILD SUCCESSFUL Now what?
The Four Steps The Scientific Method of Debugging Testing Stabilization Localization Correction "When the software is 95% complete, there's still 25% to go." Anonymous 2014 Microchip Technology Incorporated. All Rights Reserved. Slide 5
The Debugging Process Step 1: Testing Definition Testing is the process of exercising a program by injecting a wide range of input values to uncover limitations of the program and to verify that the program behaves according to its design specifications.! Testing Toolbox! MPLAB X IDE Simulator (MPSIM)! MDB scriptable command line debugger! SCL (Simulator Command Language) Stimulus Scripts! In-Circuit Debugger (PICkit, ICD, Real ICE, etc.)! DMCI (Data Monitor and Control Interface) Plug-in! Try to break the program! Exercise all features with variety of inputs 2014 Microchip Technology Incorporated. All Rights Reserved. Slide 6
The Debugging Process Step 2: Stabilization Definition Stabilization is the attempt to control conditions such that a bug may be reproduced on demand, even when using instrumentation (trace/log).! Stabilization Toolbox! Same as testing toolbox, plus! Breakpoints and watches! Instrumented Trace and Log macros! Instrumentation with printf() and similar functions! Determine the specific input values or range of input values that reliably produce incorrect outputs make the bug easily repeatable 2014 Microchip Technology Incorporated. All Rights Reserved. Slide 7
Definition The Debugging Process Step 3: Localization Localization is the search for a bug's cause once its result has been identified and made repeatable on demand and is characterized by experimentation and data collection.! Localization Toolbox! Same as stabilization toolbox, plus! Call Stack! Default Interrupts and Traps! Collect and analyze data about bug! Construct a hypothesis describing bug's cause! Test hypothesis to narrow search for bug! Localize bug to a code segment, or variable 2014 Microchip Technology Incorporated. All Rights Reserved. Slide 8
The Debugging Process Step 4: Correction Definition Correction is the task of fixing a bug once its source has been located. Often, correction is trivial but may be more complex if the bug is due to faulty program design.! Correction Toolbox! Your programming language knowledge! Good software design practices! Some fixes are trivial and low cost! Logical errors, language misuse, etc.! Some fixes are difficult and expensive! Fundamental program design flaw, misinterpretation or omission of program specifications, etc. 2014 Microchip Technology Incorporated. All Rights Reserved. Slide 9
The Proximity Principle Cause and effect are closer than you think
The Proximity Principle and the types of proximity Definition Proximity Principle: The effect of a bug, is by some measure close to its cause, whether it be lexical, temporal, or referential.! Types of Proximity! Lexical The effect of a bug follows a short distance after its cause in the source code (compile time or runtime)! Temporal The effect of a bug follows immediately after its cause during execution of the program (run time)! Referential Two segments of code (perhaps separated by space and/or time) both reference the same item (e.g. variable) without any other references in between (run time) 2014 Microchip Technology Incorporated. All Rights Reserved. Slide 11
Lexical Proximity Example void main(int) { foo(); bar(); }! The function calls to foo() and bar() are sequentially executed and are physically near each other in the code! Lexical proximity used for finding compile time errors other types exist only at run time 2014 Microchip Technology Incorporated. All Rights Reserved. Slide 12
Temporal Proximity Example while (1) { } foo(); bar();! The first and last lines of the while loop are lexically distant (could have hundreds of lines between them)! The first line executes immediately after the last line at run time as the loop returns to the top 2014 Microchip Technology Incorporated. All Rights Reserved. Slide 13
Referential Proximity Example void main(int) { x = foo(); bar(); if (x == 1) {! The references to x on the first and last lines are separated lexically and temporally! Because there are no references to x in between, the first and last lines are referentially close 2014 Microchip Technology Incorporated. All Rights Reserved. Slide 14
Error Classification "Any sufficiently advanced bug is indistinguishable from a feature." - Rich Kulawiec
Error Classification Ranked by Ease of Automated Testing Methods Syntax and Lexical Logic (Semantic) Runtime (Execution) Latent "Computers are good at following instructions, but not at reading your mind" Donald Knuth 2014 Microchip Technology Incorporated. All Rights Reserved. Slide 16
Syntax and Lexical Errors Definition Syntax Errors are the result of legal symbols being combined in illegal ways. Lexical Errors are the result of using symbols that are not legally part of the language.! TEST BASIS: Language Specification! Syntax and Lexical errors, while different are closely related and generally come from:! Misunderstanding how to use the language properly! Typographical Errors! Show up at compile time or at link time! Program will not build with these errors 2014 Microchip Technology Incorporated. All Rights Reserved. Slide 17
Example: Syntax Error Syntax and Lexical Errors Examples int x = 5 int y = 6; int z = 0; Missing semicolon illegally combines first two lines into: int x = 5 int y = 6; z = x + y; Example: Lexical Error int x@ = 5; foo y = 42; @ is not used in ANSI C and is not allowed in identifiers foo is not a data type (unless defined with typedef) 2014 Microchip Technology Incorporated. All Rights Reserved. Slide 18
Logic / Semantic Errors Definition Logic Errors are present when a program or function runs to completion, but produces an incorrect result. These are sometimes called Intent Errors.! TEST BASIS: Original Programming Specification! Logic errors may come from:! Design Error (beyond scope of this class)! Implementation Error (didn't follow spec)! Typographical Error (e.g. used & instead of &&)! Can be very painful and costly to fix if at the design or implementation level 2014 Microchip Technology Incorporated. All Rights Reserved. Slide 19
Logic / Semantic Errors Examples! It's a simple design, what could possibly go wrong? SW1 ON OFF SW2 ON OFF THINGAMAJIG SW1 SW2 MODE OFF OFF DISABLED OFF ON PASSIVE ON OFF ACTIVE if ((sw1 = OFF) && (sw2 = OFF)) DisableThingamajig(); if (sw1 == ON) EnableThingamajig(ACTIVE); if (sw2 == ON) EnableThingamajig(PASSIVE);! Design error? [~1]! Implementation error(s)? [~1]! Typographical error(s)? [2] 2014 Microchip Technology Incorporated. All Rights Reserved. Slide 20
Runtime / Execution Errors Definition Runtime Errors are errors that only become apparent when the program is running. They occur when a programmer asks in a perfectly legal way for something impossible or illogical to be done.! TEST BASIS: High-Level Language and Machine- Level Semantics (Effect of Operations)! Difficult to catch in C due to its lack of runtime range checking - program may run a long time before error is serious enough to be detected! Caused by things like exceeding array bounds! Manifests by things like divide by zero, illegal address, etc. often caught by hardware traps 2014 Microchip Technology Incorporated. All Rights Reserved. Slide 21
Example: Runtime Error Runtime / Execution Errors Examples int *p; int x; Pointer is not initialized x = *p; Example: Runtime Error int MyArray[10]; Array bounds will be exceeded by 1 for (int i = 0; i = 10; i++) { MyArray[i] = 0; } 2014 Microchip Technology Incorporated. All Rights Reserved. Slide 22
Latent Errors Definition Latent Errors are errors that only become apparent when specific data or inputs are used.! TEST BASIS: All possible input conditions! Extremely difficult to catch in some cases! May not show up for a long time, if ever! Example: inverse = 1/(x y); will cause a divide by zero error when x = y "Testing can only prove the presence of bugs, not their absence. Edsger W. Dijkstra (Turing Award Recipient-1972) 2014 Microchip Technology Incorporated. All Rights Reserved. Slide 23
Error Classification Ranked by Ease of Localization Bug Stands Still Bug is Input Dependent Bug is Code Sensitive Bug is Environment Sensitive "To understand a program you must become both the machine and the program Alan Perlis (First Turing Award Recipient- 1966) 2014 Microchip Technology Incorporated. All Rights Reserved. Slide 24
Bug Stands Still! Independent of everything around them! Symptoms will be present regardless of:! Program inputs! Startup conditions or path taken in code! Trace or log macros used in debugging! Easy to localize! Syntax / Lexical errors always stand still! Other types may stand still too 2014 Microchip Technology Incorporated. All Rights Reserved. Slide 25
Input Dependent Bugs! Symptoms change when input changes! Difficult to localize and identify without the offending input data! Trace can be useful! Simulator or hardware debugger critical to finding error 2014 Microchip Technology Incorporated. All Rights Reserved. Slide 26
Code Sensitive Bugs! Symptoms change when code changes! Classic example when program fails in release mode but works in debug mode or when debug statements added (e.g. printf, trace, log, etc.! Sometimes called "Heisenbugs" - The closer you get to them, the harder it is to make them appear 2014 Microchip Technology Incorporated. All Rights Reserved. Slide 27
Environment Sensitive Bugs! Symptoms seem to change randomly, but are due to subtle changes in hardware environment! Example: Runs fine immediately after compiled, but fails on subsequent runs (system resets often fix problem)! Possible causes:! Uninitialized variables! Differences in state of peripheral! Mishandled interrupts 2014 Microchip Technology Incorporated. All Rights Reserved. Slide 28
Ensure Debugging Info Is Generated (Should be set by default) Project Properties In the compiler settings, ensure that Generate debugging info is checked. This will generate an.elf file (or.coff file) to allow debugging of code in MPLAB X IDE. 2014 Microchip Technology Incorporated. All Rights Reserved. Slide 29