1.21. Producing a Debug Build

Problem

You want to build a version of your project that will be easy to debug.

Solution

In general, to produce a debug build, you must;

  • Disable optimizations

  • Disable expansion of inline function

  • Enable generation of debugging information

Table 1-20 presents the compiler and linker options to disable optimization and inlining; Table 1-21 presents the compiler and linker options to enable debugging information.

Table 1-20. Disabling optimization and inlining from the command line

Toolset

Optimization

Inlining

GCC

-O0

-fno-inline [12]

Visual C++Intel (Windows)

-Od

-Ob0

Intel (Linux)

-O0

-Ob0

-opt off

-inline off

Comeau (Unix)

-O0

--no_inlining

Comeau (Windows)

Same as backend, but using a slash (/) instead of a dash (-)

Borland

-Od

-vi-

Digital Mars

-o+none -S

-C

[12] It’s not necessary to specify this option unless -O3 has also been specified.

Table 1-21. Command-line options for enabling debug information

Toolset

Compiler options

Linker options

Comeau (Unix) GCCIntel (Linux)Metrowerks

-g

-g

Visual C++Intel (Windows)

See Table 1-22.

See Table 1-22.

Comeau (Windows)

Same as backend, but using a slash (/) instead of a dash (-).

Same as backend compiler option, but using a slash (/) instead of a dash (-).

Borland

-v

-v

Digital Mars

-g

-co

Table 1-22. Enabling debugging information with Visual C++ or Intel for Windows

Compiler options

Linker options

IDE options[13]

Description

-Z7

-debug

C7 Compatible

Debug info is stored in .obj and .exe files.

-Zi [-Fd<pdb-file-for-obj>]

-debug[-pdb:<pdb-file-for-exe>]

Program Database

Debug info is stored in .pdb files; use the bracketed options to specify the .pdb files.

-ZI [-Fd<pdb-file-for-obj>]

-debug [-pdb:<pdb-file-for-exe>]

Program Database for Edit & Continue

Debug info is stored in .pdb files; use the bracketed options to specify the .pdb files. Your program can be recompiled during a debugging session.

[13] To access these options, go to Configuration Properties C/C++ General Debug Information Format.

Boost.Build provides a simple mechanism for producing a debug build: simply add <variant>debug to your target’s requirements or use the command-line option variant=debug, which can be abbreviated simply as debug.

Some IDEs also provide a simple way to produce a debug build. For instance, when you create a new project with Visual C++, the IDE generates debug and release build configurations automatically. To request a debug build, simply select Configuration Manager... from the Build menu and select Debug as the active configuration. You can also select Debug from the drop-down list of configurations on the standard toolbar. The next time you build your project, it will produce a debug build.

Similarly, when you create a new project with CodeWarrior using one of Metrowerks’s project templates, called stationery, the IDE generates debug and release targets automatically. The name of the debug target may vary, but it should always contain the word “debug”. To request a debug build, select Set Default Target from the Project menu, and then select the menu item corresponding to the debug target. You can also select the debug target from the drop-down list of targets on your project’s window.

C++Builder does not support multiple build configurations for a single project, but it does provide an easy way produce a debug build. To request a debug build, go to Project Options Compiler and press Full debug. This will disable optimization and inlining and enable debugging information.

If you are using an IDE that doesn’t provide preset debug and release configurations, such as Dev-C++, or if you need more control over your project’s settings, refer to Tables 1-23 through 1-25.

Table 1-23. Disabling optimization from your IDE

IDE

Configuration

Visual C++

From your project’s property pages, go to Configuration Properties C/C++ Optimization and set Optimization to Disabled. Use the default settings for the other properties on this page.

CodeWarrior

From the Target Settings Window, go to Code Generation Global Optimizations and select Off.

C++Builder

From Project Options, go to Compiler and select None under Code optimization.

Dev-C++

From Project Options, go to Compiler Optimization and set Perform a number of minor optimizations to No; next, go to Compiler Optimization Further optimizations and set Optimize, Optimize more, and Best Optimization to No.

Table 1-24. Disabling inlining from your IDE

IDE

Configuration

Visual C++

From your project’s property pages, go to Configuration Properties C/C++ Optimization and set Inline Function Expansion to Default.

CodeWarrior

From the Target Settings Window, go to Language Settings C/C++ Language and set Inline Depth to Don’t Inline.

C++Builder

From Project Options, go to Compiler and check Disable inline expansions under Debugging.

Dev-C++

See the entry for GCC in Table 1-20 and refer to Recipe 1.20.

Table 1-25. Enabling debug information from your IDE

IDE

Configuration

Visual C++

See Table 1-22.

CodeWarrior

From the Target Settings Window, go to Language Settings Linker PPC Mac OS X Linker and check Generate SYM File and Full Path in SYM Files.

C++Builder

From Project Options, go to Compiler and check Debug Information and Line Number Information.

Dev-C++

See the entry for GCC in Table 1-21 and refer to Recipe 1.20.

Discussion

All toolsets provide an option to generate information in object files and executables that allows debuggers to report useful information as a program is executed step by step. This information generally includes the sources file names and line numbers corresponding to particular object or machine code instructions, as well as information about C++ objects occupying particular memory locations, including their names and types.

Most toolsets store debugging information directly in object files and executables, but some, also provide options for generating debugging information in separate database files. For example, with Visual C++, the -Z7 compiler option specifies that debug information should be placed in object files and executables, while the -Zi and -ZI options specify that debugging information should be stored in program database files with the extension .pdb. The -ZI option enables a feature called Edit and Continue, which allows IDE users to modify and recompile their code without terminating a debugging session. Similarly, CodeWarrior for Mac OS X by default generates debugging information in .SYM files.

Most toolsets can generate debugging information even when optimizations and inlining are enabled, although in some cases debugging information may be incompatible with particular optimizations. When optimizations are enabled, however, the compiler has the freedom to improve efficiency by reordering statements or completely reorganizing sections of code, as long as the observable behavior remains the same. This makes debugging difficult, since there may no longer be a close correspondence between locations in the source code and locations in the object or machine code. The same is true for inlining: when the compiler expands a function inline, the object code corresponding to the function body is generated within the body of the calling function. When this code is executed, no stack frame is created for the expanded function; among other things, this means that the debugger will not be able to display the values of the function arguments and local variables. Typically, debuggers do not even attempt to report the source code locations corresponding to the bodies of functions expanded inline.

Because of these considerations, the usual practice is to disable optimizations and inlining when producing a debug build.

See Also

Recipe 1.22

Get C++ Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.