A debugger is a
computer program that is used to test and
debug other programs (the "target" program). The code to be examined might alternatively be running on an
instruction set simulator (ISS), a technique that allows great power in its ability to halt when specific conditions are encountered but which will typically be somewhat slower than executing the code directly on the appropriate processor. Some debuggers offer two modes of operation - full or partial simulation to limit this impact.
When the program "crashes" or reaches a preset condition, the debugger typically shows the position in the original code if it is a source-level debugger or symbolic debugger, commonly now seen in
integrated development environments. If it is a low-level debugger or a machine-language debugger it shows the line in the
disassembly (unless it also has online access to the original source code and can display the appropriate section of code from the assembly or compilation).(A "
crash" happens when the program cannot continue because of a
programming bug. For example, perhaps the program tried to use an instruction not available on the current version of the
CPU or attempted access to unavailable or
protected memory.)
Typically, debuggers also offer more sophisticated functions such as running a program step by step (single-stepping or
program animation), stopping (breaking) (pausing the program to examine the current state) at some event or specified instruction by means of a
breakpoint, and tracking the values of some variables. Some debuggers have the ability to modify the state of the program while it is running, rather than merely to observe it. It may also be possible to continue execution at a different location in the program.
The importance of a good debugger cannot be overstated. Indeed, the existence and quality of such a tool for a given language and platform can often be the deciding factor in its use, even if another language/platform is better-suited to the task.[
citation needed] However, software can (and often does) behave differently running under a debugger than normally, due to the inevitable changes the presence of a debugger will make to a
software program's internal
timing. As a result, even with a good debugging tool, it is often very difficult to track down runtime problems in complex multi-threaded or
distributed systems.
The same functionality which makes a debugger useful for eliminating bugs allows it to be used as a
software cracking tool to evade
copy protection,
digital rights management, and other software protection features.
Most current mainstream debugging engines, such as
gdb and
dbx provide console-based command line interfaces.
Debugger front-ends are popular extensions to debugger engines that provide
IDE integration,
program animation, and visualization features. Some early
mainframe debuggers such as
Oliver and
SIMON provided this same functionality for the
IBM System/360 as long ago as the
1970s.