Debugging is the stage of software development, at which programmers detect, localize and eliminate errors.
There are two mutually complementary debugging technologies.
Using debuggers - programs that include a user interface for step-by-step program execution: operator-by-operator, function-by-function, with stops on some lines of source code or when a certain condition is reached.
The output of the current state of the program using statements located at the critical points of the program - on the screen, printer, loudspeaker or in a file. The output of debugging information to a file is called logging.
A typical development cycle, over the lifetime of the program, is repetitive and looks like this:
Programming - the introduction of new functionality into the program, correction of existing errors.
Testing (manual or automated, programmer, tester or user, in black box mode or modular) - detecting the fact of error.
Reproduction of the error - finding out the conditions under which the error happens. This may not be an easy task when programming parallel processes, and with some unusual bugs.
Debugging - finding the cause of the error.
The ability of the programmer to debug is probably the most important factor in detecting the source of the problem, but the debugging complexity depends heavily on the programming language and tools used, in particular, the debuggers.
The debugger is a software tool that allows the programmer to monitor the execution of the program under study, stop and restart it, run at a slow pace, change the values in memory, and even, in some cases, return back in time.
Other useful tools in the hands of programmers may be:
Profilers. They allow one to determine how much time is spent on a piece of code. Analysis of coverage makes it possible to identify non-executable sections of the code.
API loggers allows one to track the interaction of the program and Windows API by writing Windows messages to the log.
Disassemblers - with this you can view the assembler code of the executable file
Sniffers helps to track the traffic generated by the program
The use of high-level programming languages usually simplifies debugging if such languages contain, for example, exception handling facilities that assists in finding the source of the problem. In low-level languages, errors can lead to inconspicuous problems, for example: memory corruption. Then it can be quite difficult to determine what was the original cause of the error. In these cases, complex tricks and means of debugging may be required.