This is an installment in a series covering the different components of a typical development environment. You may want to read Part 1, Part 2, Part 3, Part 4, and Part 5 before reading this one, although it’s not strictly necessary.
Today we’ll be covering one of the tools used to analyze a running program. Unlike the Static Code Analyzer, which was covered in the previous installment, these tools help you see what is going on when the program is functioning, which aids comprehension of unwanted behaviors and rooting them out of our software. Without further ado, Today’s topic:
This piece of software is most used to correct a particular type of misbehavior: computations which produce the wrong result.
Just like when a child is learning to talk, or when one encounters and tries to use new words, phrases, and double entendres, sometimes we write some code which we thinks means something and it turns out it doesn’t. In software development, this is called a bug.
There are two particular types of bugs which are committed with more frequency at different stages of knowledge of a particular toolchain:
- Misunderstanding of the constructs we are using
- Misunderstanding of the process we are expressing
The first happen most often when learning a new tool, be it a programming language or some code written by another person, while the second happens when encountering a problem and not wrapping our head around the solution we mean to give it.
Unlike many of the tools we saw earlier, the debugger needs not know a thing about the programming language, because it works at the level of object code – in case you’ve not read about the compilers, that’s what a compiler usually produces. For more details, read Part 3.
Nevertheless, knowing about a particular programming language is of great help to a debugger and the debugging process, because the Compiler can include “debugging information” on the executables to be used with the tool. This includes copies of the lines of code that produce a particular behavior, allowing you to “watch” the behavior of your original variables and lines of code with great flexibility.
Without this kind of information, debugging is really painful and falls into the realm of reverse engineering.
- gdb; it supports over a half dozen programming languages, all supported also by the gcc.
- LLDB; a part of the LLVM toolchain, it supports C, C++, Objective-C and Swift.
- jdb; a debugger built for Java bytecode binaries. It’s likely to work with binaries targeting the JVM, even if written in another language
- pdb; a debugger built for python bytecode binaries.
Besides the debuggers, many development environments include debugger front-ends. In particular, the text editors emacs and vim have debugger frontends available.
This is all for Today; Tomorrow, we’ll cover the Profilers.