Compiler switches for debugging

To allow you to single-step through a program with a debugger, you have to provide information to allow the debugger to associate machine code with source code. At the very least, this means switching off all optimizations, since in an attempt to optimize code the C++ compiler will rearrange code. Optimizations are switched off by default (so the using the /Od switch is redundant), but clearly, to be able to debug a process and single-step through C++ code you need to remove all the /O optimization switches.

Since the C++ Standard Library uses the C Runtime, you will need to compile your code to use the latter's debug builds. The switch you use depends on whether you are building a process or Dynamic Link Library (DLL), and whether you will statically link the C runtime or access it through a DLL. If you are compiling a process, you use /MDd to get the debug version of the C runtime in a DLL, and if you use /MTd you will get the debug version of the static linked C runtime. If you are writing a dynamic linked library, you have to use /LDd in addition to one of the C runtime switches (/MTd is the default). These switches will define a pre-processor symbol called _DEBUG.

A debugger will need to know debugger symbolic information--the names and types of variables and the names of functions and line numbers associated with code. The accepted way to do this is through a file called a program database, with an extension of pdb. You use one of the /Z switches to generate a pdb file: the /Zi or /ZI switch will create two files, one with a name starting with VC (for example VC140.pdb) that contains the debugging information for all of the obj files, and a file with the name of the project that contains debugging for the process. If you compile without linking (/c) then only the first file is created. The Visual C++ project wizard will use /Od /MDd /ZI by default for debug builds. The /ZI switch means that a program database is created in a format that allows the Visual C++ debugger to perform Edit and Continue, that is, you can change some code and continue to single-step through the code without recompiling. When you compile for a release build, the wizard will use the /O2 /MD /Zi switches, which means that the code is optimized for speed but a program database (without Edit and Continue support) will still be created. The code does not need the program database to run (in fact, you should not distribute it with your code), but it is useful if you have a crash report and need to run the release build code under the debugger.

These /Z compiler switches assume the linker is run with the /debug switch (and if the compiler invokes the linker it will pass this switch). The linker will create the project program database from the debug information in the VC program database file.

This raises the question of why a release build file will need a program database. If you run a program under the debugger and look at the call stack, you will often see a long list of stack frames in operating system files. These usually have fairly meaningless names made up of the DLL name and some numbers and characters. It is possible to install the symbols (the pdb files) for Windows or, if they are not installed, instruct the Visual C++ debugger to download the symbols for a library being used from a computer on the network called a symbol server. These symbols are not the source code for the library, but they do give you the names of the functions and the types of the parameters, which gives you additional information about the state of the call stack at the point where you are single stepping.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset