Documente Academic
Documente Profesional
Documente Cultură
Introduction
An interactive debugging system provides programmers with facilities that aid in the testing and debugging of programs.
Approaches to debugging
Print statements Printing to log files Sprinkling the code with assertions Using post-mortem dumps Having programs that provide function call stacks on termination Profiling Heap checking System call tracing tools Interactive source-level debugging Reverse execution ...
This principle says that the debugger must intrude on the debuggee in a minimal way. The debugger must be truthful so the programmer always trusts it. The debugger should provide the program context information during debugging. Program context information.
Truthful debugging
The programmer may define a breakpoint which causes execution to be suspended when a specified point in the program is reached.
After execution is suspended, other debugging commands can be used to analyze the progress of the program and to diagnose errors detected.
Tracing can be used to track the flow the execution logic and data modifications.
Step into Step over Run to cursor Run until return ...
Trackback can show the path by which the current statement was reached (a list of all the functions called in order). This kind of information should be displayed symbolically, and should be related to the source program.
call stack
watch registers
It must be possible to display the program being debugged. The user should be able to control the level at which this display occurs.
If the compiler has so distorted the final instruction stream through optimizations, the programmer cannot easily map this back onto the original source code
switching to a mode where the actual source code is interpreted may remove a major source of confusion for the programmer.
Fix-and-run
The goal of this approach is to minimize the turnaround time between creating a fix to test and the ability to actually test the system with the modification in place.
10
Many application systems involve the use of several different programming language. A debugging system must be sensitive to the specific language being debugged so that procedural, arithmetic, and conditional logic can be coded in the syntax of that language.
11
12
This can be provided for by simply writing some illegal instruction into the code stream for the debuggee.
A notification system, also called an interrupt or a trap, that will notify the operating system (and thereby the debugger) that an important event has occurred with respect to the running process. The ability to read and write directly out of and into the hardware registers when the interrupt occurs.
13
14
Breakpoint support
Breakpoints are usually implemented as a special instruction that causes a trap to the operation system, which then can notify a special program that has registered itself as a debugger. On architectures with varying length instructions, it is normal for the trap---or breakpoint---instruction to be the length of the shortest possible instruction.
This makes it much simpler for the debugger to guarantee breakpoints are placed on instruction boundaries. Breakpoint instruction of Intel x86 is a one-byte instruction INT 3.
15
Single-step support
Single-step means that the processor is instructed to execute a single machine instruction when it is next processing instructions for the debuggee. Most processors provide a mode bit that controls single-step operation.
16
Fault-detection support
When some faults of the debuggee are detected
by the processor, such as divide by zero and memory access violations, by OS, such as I/O failure, or by some higher level software systems, such as stack corruption or array bounds check violations,
the OS notifies the debugger that its debuggee has received a fault before the debuggee actually is allowed control again.
17
Watchpoint support
Watchpoints are notifications presented to the debugger when specified portions of the debuggees address space are modified.
OS debugging support
To control a debuggee process, a debugger needs a mechanism to notify the OS about the executable program it wishes to control.
Once this is done, the debugger needs to modify that debuggees code in order to modify the instruction stream with the breakpoint instructions; And then, the debugger needs to tell the OS to run the debuggee but notify the debugger if any sort of exceptions occur before the debuggee itself get notified or terminated. Once the debuggee stops, the debugger needs to be able to gather information from the debuggees register set and data memory.
19
it relates directly to executable machine instructions, the points in the address space where actual hardware
breakpoint instructions get written.
it stores the original instruction. the original instruction is restored if the breakpoint is to
be removed.
20
10
logical File foo.c: line 9 File foo.c: line 9 File foo.c: line 9 File foo.c: line 5
physical
0x458F0
Original instruction
0x400F0
Logical-to-physical: set, modify, or delete breakpoints Physical-to-logical: whenever a hardware breakpoint event occurs
request symbol table agent to map given file name and line number information into physical address. create logical breakpoint object containing this information. create physical breakpoint object, or increment reference count if this object already exists physical breakpoint agent must put breakpoint instruction and save original instruction at that location
22
11
Conditional breakpoint
A conditional breakpoint may or may not stop the debuggee when the breakpoint fires depending on the value of an associated condition.
23
For statement step over, an internal breakpoint is set on the functions return address to allow the function and all its descendents at full speed.
Step into is a statement step that goes into any descendent functions found during the current operations.
24
12
float compute(int a,int b) { float c = b; for(int i = 0; i < a; i++) c = c * b; return c; } main() { int a,b; float c; printf(Enter a, b:\n); scanf(%d %d,&a,&b); c = compute(a,b); printf(result: %f\n,c); }
Last step ended here. From here do a step into or a step over.
Drawback: very slow. (1000 times slower than full-speed run to a breakpoint)
Set a temporary breakpoint at the address of the beginning of the next source statement.
How to handle branching instruction? if (expression) { ... } else { ... } either machine single-step instruction, or decode the branch target and set a temporary breakpoint at that address 26
13
Step over
The algorithm for step over is like that of step into but it notes a call instruction during instruction decode as special, and once the called function has been entered, a breakpoint is inserted at the return address of this function by looking at the current stack frame.
27
Stack trace
When a fault or breakpoint occurs, the user needs a stack track to know how did the program get here? A stack trace is a list of the procedure activation records currently on the call stack.
frame 2 frame 1 frame 0 STACK
call P2 call P1
call stack
28
14
Stack trace
Once the debugger knows
the boundaries of a activation record and the procedure-calling conventions,
The debugger can also retrieve the values of the local variables.
29
activation record 2 locals registers saved by P2 P1 return address arguments from P1 to P2 activation record 1 locals registers saved by P1 P0 return address arguments from P0 to P1 activation record 0 locals registers saved by P0
P1 calls P2
P0 calls P1
15
31
16