Debugging a Simulation

The OMNeT⁠+⁠+ IDE integrates with the CDT (C/C⁠+⁠+ Development Tooling) of Eclipse which also includes debugging support. The CDT debugger UI relies on gdb for doing the actual work.

Starting a Debug Session

Launching a simulation in debug mode is very similar to running it (see previous sections), only you have to select the Debug toolbar icon or menu item instead on Run. The same launch configurations are used for debugging that for running, that is, if you open the Debug Configurations... dialog, you will see the same launch configurations as in the Run dialog. The launcher is automatically using the debug build of the model (i.e. the executable that has a _dbg suffix.) The dialog will have extra tab pages where you can configure the debugger and other details.

Note

If you have problems with starting the debug session, check whether:
  • your executable is built with debug information,
  • you can run the same executable without problem (using the same launch configuration, but with adding a _dbg suffix to the executable name), and
  • the debugger type is set properly on the Debugger tab of the Launch dialog.

Warning

Batch (and parallel) execution is not possible in this launch type, so you may specify only a single run number.

Using the Debugger

The CDT debugger provides functionality that can be expected from a good C/C⁠+⁠+ debugger: run control (run, suspend, step into, step over, return from function, drop to stack frame); breakpoints (also conditional and counting breakpoints); watchpoints (a.k.a. expression breakpoints, breakpoints that stop the execution whenever the value of a given expression changes); watching and inspecting variables; and access to machine-level details such as disassembly, registers and memory.

Source code is shown in the editor area; additional information and controls are displayed in various Views: Debug, Breakpoints, Expressions, Variables, Registers, Memory, etc.

CDT's conversation with gdb can also be viewed, in the appropriate pages of the Console View. (Click the Display Selected Console icon, and choose gdb or gdb traces from the menu.)

Tip

One little tip that we found useful: if you have a pointer in the program that actually points to an array (of objects, etc), you can have it displayed as an array, too. In Variables, right-click the variable and choose Display As Array... from the menu. You will be prompted for a start index and the number of elements to display.

More information on the debugger is available in the CDT documentation, which is part of the IDE's Help system. See C/C⁠+⁠+ Development User Guide, chapter Running and debugging projects.

Pretty Printers

Many programs contain data structures whose contents is difficult to comprehend by looking at "raw" variables in the program. One example is the std::map<T> class, which is essentially a dictionary but implemented with a binary tree, so it is practically impossible to figure out with a C⁠+⁠+ debugger what data a concrete map instance contains.

The solution gdb offers to this problem is pretty printers. Pretty printers are Python classes that gdb invokes to transform some actual data structure to something that is easier for humans to understand. The *.py files that provide and register these pretty printers are usually loaded via gdb's startup script, .gdbinit (or some .gdbinit.py script, because gdb allows startup scripts to be written in Python, too).

The OMNeT⁠+⁠+ IDE comes with pretty printers for container classes in the standard C⁠+⁠+ library (std::map<T>, std::vector<T>, etc.) and also for certain OMNeT⁠+⁠+ data types, for example simtime_t. These scripts are located under misc/gdb/ in the OMNeT⁠+⁠+ root directory. The IDE also supports project-specific pretty printers: if the debugged project's root folder contains a .gdbinit.py file, it will be loaded by gdb. (The project's .gdbinit.py can then load further Python scripts, e.g. from an etc/gdb/ folder of the project.)

Pretty printer loading works in the following way. The IDE invokes gdb with misc/gdb/gdbinit.py as startup script (for new launch configurations, the GDB command file field on the Debugger tab is set to ${opp_root}/misc/gdb/gdbinit.py). This script loads the pretty printers under misc/gdb, and also the project-specific pretty printers.

Tip

If you want to write your own pretty printers, refer to the gdb documentation. It is available online e.g. here: http://sourceware.org/gdb/current/onlinedocs/gdb/

Some pretty-printers may occasionally interfere with the debugged program (especially if the program's state is already corrupted by earlier errors), so at times it may be may be useful to temporarily turn off pretty printers. To prevent pretty printers from being loaded for a session, clear the GDB command file setting in the launch configuration. To disable them for a currently active debug session, switch to the gdb page in the Console, and enter the following gdb command:

disable pretty-printer global

Or, to only disable OMNeT⁠+⁠+-specific pretty printers (but leave the standard C⁠+⁠+ library printers on):

disable pretty-printer global omnetpp;.*