Debugging in the IDE

One of the most frequently used tools in the traditional design-develop-debug cycle is the source-level debugger. In the IDE, this powerful tool provides an intuitive debugging environment that's completely integrated with the other workbench tools, giving you the flexibility you need to best address the problems at hand.

Have you ever had to debug several programs simultaneously? Did you have to use separate tools when the programs were written in different languages or for different processors? The IDE's source debugger provides a unified environment for multiprocess and multithreaded debugging of programs written in C, C++, Embedded C++, or Java. You can debug such programs concurrently on one or multiple remote target systems.

In order to use the full power of the Debug perspective, you must use executables compiled for debugging. These executables contain additional debug information that lets the debugger make direct associations between the source code and the binaries generated from that original source. In the IDE, you'll see different icons: a arrowhead icon for executables that weren't compiled for debugging, or a bug for those that were.

The IDE debugger uses GDB as the underlying debug engine. It translates each GUI action into a sequence of GDB commands, and then processes the output from GDB to show the current state of the program being debugged.

Note: By default, lazy binding — the process by which symbol resolution isn't done until a symbol is actually used — is turned off ( pdebug sets LD_BIND_NOW to 1). Without LD_BIND_NOW, you'll see a different backtrace for the first function call into the shared object as the runtime linker resolves the symbol. You can prevent pdebug from setting LD_BIND_NOW by specifying the -l (“el”) option. For more information about lazy binding, see the Compiling and Debugging chapter in the Neutrino Programmer's Guide.

The IDE updates the views in the Debug perspective only when the program is suspended.

Note: Editing your source after compiling causes the line numbering to be out of step because the debug information is tied directly to the source. Similarly, debugging an optimized binary can also cause unexpected jumps in the execution trace.