Compiler Options for Debugging
There are various debugging options that can be specified when compiling to create a program that contains additional information about the source code. This allows debugging software to provide this information and give context as the program is analysed.
Prerequisite knowledge
To start using debugging options you should first be familiar with how to install and run your program and how to set compiler flags when compiling.
Symbolic debugging
When an application crashes or stalls, you can use a debugger to help locate the cause and enable further investigation. Enabling support for symbolic debugging generates and stores source-level debugging and symbol information in the executable. This enables a debugger to reference variables by name and show where in the source code the problem is.
Table 1. Symbolic debugging flags
Flag | Description |
---|---|
-g | Generates symbolic debugging information. |
Add the -g
flag to both the compile and link steps.
Some compilers disable optimisations with debugging, or permit debugging with optimised code at the expense of reliable debugging information as a result of optimisations. With all three families of compilers, GNU, Cray and AMD AOCC, the optimisation level can be specified by adding -O<n>
.
GNU Compilers
The GNU compilers have the following debugging and diagnostic options:
Table 2. GNU compiler debugging options
Flag | Description |
---|---|
-g1 | Produces minimal information, enough for making backtraces in parts of the program that you don’t plan to debug. This includes descriptions of functions and external variables, and line number tables, but no information about local variables. |
-g2 | (default) Corresponds to -g . |
-g3 | Includes extra information, such as all the macro definitions present in the program. |
Cray compilers
The Cray C/C++ compilers are based on LLVM Clang compilers and have the following debugging and diagnostic options:
Table 3. Cray C/C++ compiler debugging options
Flag | Description |
---|---|
-g | Generates symbolic debugging information. Debugging levels are the same as for GNU compilers (-g1 to -g3 ). |
-ggdb (or -gdbx -glldb -gsce ) | Tune debugging information for different debuggers (the default is gdb ). |
-fdiagnostics-print-source-range-info | Print machine parsable information about source ranges. This option makes Clang print information about source ranges in a machine-parsable format after the file/line/column number information. The information is a simple sequence of brace-enclosed ranges, where each range lists the start and end line/column locations. For example, it will provide not just line numbers but the full range of where an error is located: Clang output with diagnostic flag enabled exprs.c:47:15:{47:8-47:14}{47:17-47:24}: error: invalid operands to binary expression ('int *' and '_Complex float') P = (P-42) + Gamma*4; ~~~~~~ ^ ~~~~~~~ |
-fsanitize-address-use-after-return=(never|runtime|always)
| Fast memory error detector. It consists of a compiler instrumentation module and a run-time library. The tool can detect the following types of bugs:
|
-fsave-loopmark | Provides a loopmark file containing detailed compiler messages of how code has been optimised. |
The Cray Fortran compiler is not based on LLVM Flang and has a different set of options.
Table 4. Cray Fortran compiler debugging options
Flag | Description |
---|---|
-G0 | Full debugging information with most optimisations disabled. |
-G1 | Most debugging information is available with partial optimization. Some optimizations make tracebacks and limited breakpoints available in the debugger. Some scalar optimizations and all loop nest restructuring is disabled, but the source code will be visible and most symbols will be available. This allows block-by-block debugging, with the exception of innermost loops. The executable will be faster than with -g or -G0 . |
-G2 | Partial debugging information. Most optimizations, tracebacks and very limited breakpoints are available in the debugger. The source code will be visible and some symbols will be available. This level allows post-mortem debugging, but local information such as the value of a loop index variable is not necessarily reliable at this level because such information often is carried in registers in optimized code. The executable will be faster and smaller than with -G1 . |
-rd | Decompiles (translates) the intermediate representation of the compiler into listings that resemble the format of the source code. You can use these files to examine the restructuring and optimization changes made by the compiler, which can lead to insights about changes you can make to your Fortran source to improve its performance. |
AMD AOCC compilers
The AMD AOCC C/C++ compilers are based on LLVM Clang compilers and so have the same options as the Cray compilers.
Optimisation levels
The optimisation process often trades performance for accuracy, or can introduce an optimisation bug. In some cases this is not significant to the results, however in others the difference can be substantial. One way to isolate numerical differences is to disable or reduce the optimisation level until the results are correct.
Table 5. Optimisation level options
Flag | Description |
---|---|
-O0 | Disables all optimisations. |
-O1 | Enables a conservative level of optimisation. |
-O2 | Enables moderate optimisations including vectorisation. |
-O3 | Enables aggressive optimisations. |
-Ofast | Enables aggressive optimisations which violate requirements of C standard for floating-point semantics. Not recommended Test and verify results before using. |
For projects with multiple files, optimisation can be reduced selectively to help isolate the problem.
Floating point consistency
Some codes might be very sensitive to specific types of floating point optimisation. For instance, compilers might decide to exchange division with multiplication when used with higher optimisation levels and this type of optimisation will usually have an impact on the final numerical result of the code. Fortunately, floating point optimisations can be selectively controlled by using specific compiler options.
GNU compilers
The GNU compilers support a range of options that control the accuracy of floating point operations.
Table 6. GNU compiler floating point precision options
Flag | Description |
---|---|
-ffloat-store | Disables storing floating point data in registers where excess precision deviates from IEEE floating point data. |
-frounding-math | Disables transformations and optimisations for floating point .rounding |
-fsignaling-nans | Disables some optimisations when signalling NaNs. |
-ffast-math | Enables optimisations that break IEEE floating point. |
Cray compilers
The Cray compilers support controlling floating point optimisations with the following options:
Table 7. Cray C/C++ Clang compiler floating point precision options
Flag | Description |
---|---|
-frounding-math | Disables transformations and optimisations for floating point rounding. |
-fsignaling-maths | Disables some optimisations when signalling math exceptions. |
-ffast-math | Enables optimisations that break IEEE floating point. |
Cray Fortran is not based on LLVM and has different options.
Table 8. Cray Fortran compiler floating point precision options
Flag | Description |
---|---|
-h fp0 | Gives minimum freedom to optimise floating point operations, with stricter conformance to the IEEE standard. |
-h fp[1-4] | Allows progressively more freedom to optimise floating point operations, but with less conformance to the IEEE standard. |
The -h fp2
option is the default.
AMD AOCC compilers
The AMD AOCC C/C++ compilers are based on LLVM Clang compilers and so have the same options as the Cray compilers.
Compiler warnings
Compiler warnings can help to identify dubious code at compile time. Use the -Wall
option to allow the generation of warnings with most compilers.
Runtime checks
Most compilers support checking for various error conditions at run time, such as out-of-bounds array access.
Runtime checks can degrade performance so use these options only for debugging.
GNU compiler
The GNU C/C++ compilers gcc
and g++
support the following runtime checks:
Table 9. GNU C/C++ compiler runtime check options
Flag | Description |
---|---|
-fstack-check | Generates code to check for stack overflow. |
-fcheck-new | Checks the pointer returned by new is non-null. |
-fstack-protector-all | Checks for buffer overflows. |
The GNU Fortran compiler (gfortran
) supports a wide range of runtime checks with the -fcheck=<keyword>
option. Multiple keywords from the following table can be used together provided they are comma delimited.
Table 10. GNU Fortran compiler runtime check options
Keyword | Description |
---|---|
array-temps | Warns when a temporary array is created for an actual argument. |
bounds | Checks array subscripts against minimum and maximum values. |
do | Checks for modification of loop iteration variables. |
mem | Checks memory allocations. |
pointer | Enables checks for pointer and allocatable variables. |
recursion | Checks for recursion in routines which are not marked recursive. |
Older GNU Fortran compilers supported -fbounds-check
and -fcheck-array-temporaries
, though these are now deprecated.
Cray compiler
The Cray C/C+ compiler supports several different sanitisers:
Table 11. Cray C/C++ compiler runtime check options are enabled with -fsanitize=<flag>
Flag | Description |
---|---|
address | AddressSanitizer, a memory error detector. |
thread | ThreadSanitizer, a data race detector useful for debugging openmp. |
memory | MemorySanitizer, a detector of uninitialised reads, which requires instrumentation of all the code. |
undefined | UndefinedBehaviourSanitizer, fast undefined behaviour checker. |
dataflow | DataFlowSanitizer, general data flow analysis. |
safe-stack | Protection against stack-based memory corruption errors. |
The Cray Fortran compiler runtime checks can be enabled with the -R
option. High optimisation levels can impact the degree to which checks are made.
Table 12. Cray Fortran compiler runtime check options
Flag | Description |
---|---|
-Rb | Checks array bounds. |
-Rc | Checks array conformance in array expressions. |
-Rd | Enables directive checking. |
-Rp | Checks association and allocation status for pointer arrays, allocatable arrays and assumed-shape arrays. |
-Rs | Checks character substring bounds. |
-Rbcdps | Enables all runtime checks. |
AMD AOCC compilers
The AMD AOCC C/C++ compilers are based on LLVM Clang compilers and so have the same options as the Cray compilers.
Related pages