Compiler and tools tricks

Textbooks are full of good advices:

Use other aids as well. Explaining your code to someone else (even a teddy bear) is wonderfully effective. Use a debugger to get a stak trace. Use some of the commercial tools that check for memory leaks, array bounds violations, suspect code and the like. Step through your program when it has become clear that you have the wrong picture of how the code works.

— Brian W. Kernighan, Rob Pike, The practice of programming , 1999 (Chapter 5: Debugging)

Enable every optional warning; view the warnings as a risk-free, high-return investment in your program. Don't ask, "Should I enable this warning?" Instead ask, "Why shouldn't I enable it?" Turn on every warning unless you have an excellent reason not to.

— Steve Macguire, Writing solid code , 1993

Sounds familiar? But with which option? This page tries to answer that kind of question.

Constructive feedback is welcome.

Table of Contents

Numerical topics Exchange Fortran unformatted data between heterogeneous machines with SGI and Cray compilers: assign

with Compaq compilers and Intel compilers (8.0 and later): f90/ifort -convert xxx

with Sun compilers: man convert_external

Stuart Norris' "Fortran Unformatted File Utilities" may help.

The traditional format implemented by Unix compiler adds to each record a suffix and a prefix encoding the length in bytes as a signed integer. These records are usually 4 bytes long.

Compaq and Intel compilers implement a method to support lengths longer than 231 (i.e. 2 Gigabytes) while keeping the compatibility with the traditional method. This is documented in their user's manual (search for "Variable-Length Records Greater Than 2 Gigabytes" ). Long records are split in subrecords. The sign bit of the prefix indicates whether the record is continued or not. The sign bit of the suffix indicates the presence of a preceding record.

This is supported in GNU Fortran 4.2 and later. Approximate "diff" Nelson Beebe's ndiff

spiff (comp.sources.unix - volume 16)

fpdiff

D. W. Muir's t2compare Increasing the stack size Win32: fixed at link time

You can increase this by specifying the linker option /stack:n where n is the number of bytes (in decimal) you want for the stack. In Developer Studio, select Project..Settings..Link and add the option switch to the list of Project Options. You can also change the stack size of an already linked executable with the command editbin /stack:n program.exe .

Unix sh, ksh, bash: ulimit Example:

ulimit -s unlimited # no limit on stack

ulimit -a # display current settings

ulimit -aH # display maxima csh: limit and unlimit

Example:

unlimit stacksize # no limit on stack

limit # display current settings

limit -h # display maxima Finally, a command like " limit stacksize unlimited " increases the limit to a maximum value set by some kernel parameter. The kernel can be configured to change this limit. If the maxima are too small, a quick workaround for Fortran programmer is to "SAVE" (or "ALLOCATE") the offending arrays or to compile the subroutines (or whole program) with a flag that does an automatic "SAVE".

[Contents]

Code coverage tools Linux, GNU compilers: gcov (part of GCC)

(documentation: info gcc 'Gcov' and info gcc 'Invoking GCC' 'Debugging Options' )

(part of GCC) (documentation: and ) Solaris: tcov

An example:

$ cc -xa -o myprogram myprogram.c

$ ./myprogram

$ tcov myprogram.c

$ cat myprogram.tcov

An example: SGI: cvcov , cvxcov

, SGI and Compaq Unix: pixie

Compaq Unix: atom -tool pixie

AIX: tprof

Fortran: fcat nag_profile of the NAGWare f77 tools, nag_coverage95 of the NAGWare f95 tools

[Contents]

Code profiling Any platform: prof , gprof (GNU gprof is part of GNU binutils)

, (GNU gprof is part of GNU binutils) Linux: Finding system bottlenecks: vmstat is handy to display various system statistics and find out if activity is CPU, memory or i/o bound. Use netstat to monitor the network. top , ps are handy to find hogging processes. oprofile (performance-counter based), valgrind

Solaris: DTrace is the tool of choice (from Solaris 10 on). Finding system bottlenecks: prstat , mpstat . truss , strace and plockstat can come handy.

SGI and Compaq Unix: pixie

Compaq Unix: atom -tool pixie , atom -tool hiprof (online tutorial), dxprof

, (online tutorial), Compaq Unix: uprofile

SGI: perfex , ssrun , cvperf , speedshop

, , , HP: CXperf , puma

, Pallas' Vampir

lcc has several profiling options, most notably -b that produces code which counts the number of times each expression is executed. The results are analysed by the companion program bprint . [Contents]

Bourne shell Use sh -n (or ksh, bash, ...) to get a semantic check

(or ksh, bash, ...) to get a semantic check Use set -u to trap on uninitialized variables, set -x to get a trace

to trap on uninitialized variables, to get a trace Idiom to check the content of a variable

if [ "x${VAR-}" = x ]; then

Beware that echo is not portable. Use ${echo} with escaped characters. if [ "`echo -e xxx`" = xxx ]; then echo='echo -e' else echo='echo' fi

is not portable. Use with escaped characters. /bin/sh on some platforms (Solaris, AIX for instance) can be very slow. On Solaris, /bin/ksh should be preferred. [Contents]

Debuggers "Command line" debuggers Fast, powerful, usable through telnet but raw. Quickest way to get a stack trace (" where " in dbx , " backtrace " or " bt " in gdb ). Linux, GNU compilers: gdb home page with documentation setting a hardware watchpoint: watch *(int*) 0xAddressToWatch

Cygwin A post-mortem stack trace can be obtained using: awk '/^[0-9]/{print $2}' prog.exe.stackdump | addr2line -f -e prog.exe The generation of a core file can be forced using the command dumper . First use: set CYGWIN=error_start=x:\path\to\cygwin\bin\dumper.exe (possibly in cygwin.bat ). Then, upon a crash, a core file will be created. You can then use gdb to analyse the result.

Solaris, Irix, Compaq Unix, AIX: dbx (all with differences)

(all with differences) Compaq Unix: ladebug

HP: gdb (actually a modified version by HP) ( xdb is now superseded)

(actually a modified version by HP) ( is now superseded) [from Arjen Markus]

On UNIX systems that have no development environment (and therefore lack such debuggers as xdb, dbx, ...) you can still get some information from the coredump by using "adb" or "sdb". These are low-level, general-purpose debuggers with a rather terse interface. One simple recipe for "adb" is this:

> adb programfile core

$c

:q

$c will give you the stack trace, so that you at least know in what routine the program crashed, :q will end the debug session. Graphical debuggers Each Unix vendor offers its own graphical debugger ( workshop on Solaris, cvd on Irix, dde on HP, ladebug -gui (was dxladebug ) on Compaq, xldb on AIX, ...).

My preference goes to the Data Display Debugger (ddd) which provides an uniform interface across unix platform, encapsulates the system debugger ( gdb , dbx , ladebug , ...) and works well (Dr Dobb's article). Availability and setup of DDD No installation needed (!), just call the executable.

Use ddd --gdb or ddd --dbx following the platform. Debuggers for parallel applications think of using debugging options (bounds checking, etc)

Etnus' totalview Installation:

setenv TVROOT xxx

setenv PATH "${PATH}:${TVROOT}/bin"

setenv MANPATH "${MANPATH}:${TVROOT}/man" Example for Irix:

[f77, f90] -64 -g <prog-name>.f -L${TVROOT}/lib -ldbfork_n64 -lmpi -o <application-name>

[f77, f90] -n32 -g <prog-name>.f -L"${TVROOT}"/lib -ldbfork_n32 -lmpi -o <application-name>

mpirun -np <nprocs> totalview <application-name> Vendor site

Irix: cvd

Compaq: dmpirun -dbx <nprocs> <program name and arguments> (or -ladebug or ... c.f. " man dmpirun ")

(or or ... c.f. " ") IBM: pdbx , xpdbx Trace debugger [linux] ltrace : trace dynamic library calls

: trace dynamic library calls [linux] strace ( -f : follow and continue tracing any child processes forked)

( : follow and continue tracing any child processes forked) [solaris] truss ( -f : follow and continue tracing any child processes forked)

( : follow and continue tracing any child processes forked) [irix] par

[compaq] atom -tool ptrace Various debugger tricks Equivalence between Solaris dbx and gdb .

and . Solaris dbx : dbx has got some built-in memory debugging capabilities.

: dbx has got some built-in memory debugging capabilities. Getting a stack live: [Solaris] /usr/proc/bin/pstack <PID> attach the process and get a stack trace [glibc >= 2.1] catchsegv

[Solaris 8] pstack core gives a stack trace.

gives a stack trace. [HP_UX] When stepping into some shared libraries in an attached process, start the executable with pxdb -s on <exe>

Apache Debugging Guide

Debugging Mozilla on Linux FAQ [Contents]

Compaq (Digital) Debug flags [all compilers] -trapuv Forces all uninitialized stack variables to be initialized with 0xfff58005fff58005. When this value is used as a floating-point variable, it is treated as a floating-point NaN and causes a floating-point trap. When it is used as a pointer, an address or segmentation violation usually occurs. With Fortran, think of using -automatic . [Fortran] -automatic Places local variables on the run-time stack. [Fortran] -C check for subscripts out of range at runtime [Fortran] -check <xxx> Add some checks. Check (!) it out in the manual pages ( man f77 , man f90 ).

advice: -check format -check output_conversion -check overflow [-check underflow] [Fortran] -syntax_only Specifies that the source file will be checked only for correct syntax. No code is generated, no object file is produced, and some error checking done by the optimizer is bypassed (for example, checking for uninitialized variables). This option lets you do a quick syntax check of your source file. The default is -nosyntax_only. [Fortran] -u or -warn declarations Makes the default type of a variable undefined (IMPLICIT NONE), which causes the compiler to issue a warning for any undeclared symbols. [Fortran] -warn <xxx> Enable some warnings. Check it out in the manual pages. ( man f77 , man f90 ).

advice: -warn argument_checking [cc] -w Activate warnings. [cc] -warnprotos Causes the compiler to produce warning messages when a function is called that is not declared with a full prototype. This checking is more strict than required by ANSI C. [cc] -check Performs compile-time code checking. With this flag, the compiler checks for code that exhibits non portable behavior, represents a possible unintended code sequence, or possibly affects operation of the program because of a quiet change in the ANSI C Standard. Some of these checks have traditionally been associated with the lint utility. This flag is available for -newc and -migrate only. [cc] -portable Enables the issuance of diagnostics that warn about any non portable usages encountered. This flag is not available when you use the -oldc flag. [cc] -std Enforces the ANSI C standard, but allows some common programming practices disallowed by the standard. [cc] -varargs Prints warnings for all lines that may require the varargs.h macros. [cc, cxx] -readonly_strings Causes all string literals to be read-only. [cc, cxx] -Hf Halt processing after compiling and template instantiating (if applies) Tracing flags -Wl,'-ySYMBOL' Print the name of each linked file in which SYMBOL appears. Runtime checking Atom toolset and its "Third Degree" tool (c.f. man atom , man third , man dxheap )

Example:

cc -O0 -g a.c

atom ./a.out -tool third

setenv LD_LIBRARY_PATH `pwd`

./a.out.third

cat a.out.3log [Contents]

Linux/glibc Documentation info gcc 'libc'

Debugging with Glibc

FAQ Runtime checking environment variables MALLOC_CHECK_ and MALLOC_PERTURB_ (c.f. documentation, e.g. man malloc ). Typically, set MALLOC_CHECK_ to 2 and, if available, MALLOC_PERTURB_ to a pertubation byte such as B .

and (c.f. documentation, e.g. ). Typically, set to and, if available, to a pertubation byte such as . tools Floating point trapping Build with gcc -c trapfpe.c and link with trapfpe.o or build with gcc -shared -o trapfpe.so trapfpe.c and set LD_PRELOAD to this library. Adapted from: info g77 'Trouble' 'Missing Features' 'Floating-point Exception Handling' . Starting with glibc 2.2, the following C99-style (but glibc specific) code is preferred. #define _GNU_SOURCE 1 #include <fenv.h> static void __attribute__ ((constructor)) trapfpe(void) { /* Enable some exceptions. At startup all exceptions are masked. */ feenableexcept(FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW); } Previous versions of glibc require some platform dependent code (x86 specific). [Contents]

GNU compilers Documentation Look for the "info" pages. Under emacs on a Linux box: "C-h i". Interesting "debug" nodes: info gcc 'Invoking GCC' 'Warning Options'

info gcc 'Invoking GCC' 'Debugging Options'

info g77 'Invoking G77' 'Warning Options'

info g77 'Invoking G77' 'Debugging Options' Debug flags -fsyntax-only Check the code for syntax errors, but do not do anything beyond that. -ggdb Produce debugging information for use by GDB. This means to use the most expressive format available, including GDB extensions if at all possible. -g3 , -ggdb3 Level 3 includes extra information, such as all the macro definitions present in the program. Some debuggers support macro expansion when you use -g3 . -fmessage-length=0 Messages on one line, i.e. not split. Useful with some editors' "jump on error" mode. [gcc] -Wall -W -Wstrict-prototypes -Wwrite-strings -pedantic -O (add -Wold-style-definition with gcc 3.4 and later)

[g++] -Wall -W -Wwrite-strings -pedantic -O activate all the standard warnings. [gcc, g++] -Wunused-macros warn about macros defined in the main file that are unused. [g++] -Weffc++ warn about guidelines Scott Meyers' " Effective C++ " books. Noisy but useful. Use with -fmessage-length=0 and grep -v as a filter. [g++] -Wold-style-cast warn about C-style casts. [g77] -Wall -W -Wsurprising -pedantic -O activate all the standard warnings. [g77] -Wimplicit Warn whenever a variable, array, or function is implicitly declared. [g77 (>= 2.95)] -fbounds-check run-time checks for array subscripts and substring. [all compilers (>= 2.95)] -fstrict-aliasing Allows the compiler to assume the strictest aliasing rules applicable to the language being compiled.

It may help to find buggy code. In principle, code produced by f2c should be safe for such optimization. Implied by -O2 since gcc 3.x. "lint" with gcc (by James Hu) - somewhat out-of-date: glint() { gcc -ansi -pedantic -pedantic-errors -O \ -Wall -W -Wtraditional -Wpointer-arith -Wbad-function-cast \ -Wcast-qual -Wcast-align -Wwrite-strings -Wconversion \ -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations \ -S -o - "$@" > /dev/null; } Joseph Myers' favourite warnings as of gcc 3.4. Tracing flags Some useful flags to find out what's going on. Many others are available. -v Print (on standard error output) the commands executed to run the stages of compilation. -H Print the name of each header file used, in addition to other normal activities. [gcc] -E -dM -xc /dev/null shows which symbols are defined. Use -xc++ for C++. [GNU ld] -Wl,-M Print a link map to the standard output. [GNU ld] -Wl,--cref Output a cross reference table. [GNU ld] -Wl,'-y SYMBOL' Print the name of each linked file in which SYMBOL appears. libstd++ debug mode According the documentation, to use the libstdc++ debug mode, compile your application with the compiler flag -D_GLIBCXX_DEBUG . Floating point implementation GCC (at least up to the 3.4 release), does not offer "referential transparency" on Intel x86 that uses floating point extended registers. It can lead to puzzling results as explained by Brad Lucier who showed as well how the compiler could be fixed. The x87 architecture which has only 8 80-bit FPU registers is particularly sensitive to uncontrollable register spills to 64 bits in memory that cause double roundings. Furthermore, variables allocated on the stack may be optimized away in register, changing the precision and producing different results depending on the level of optimization of the program. Some possible actions are detailed below. Note that the x86-64 architecture in 64 bit mode uses the SSE floating point device and not the x87 stack and is therefore immune to this problem. Note that even if gcc was producing code that spills double extended register on stack without rounding, the results will still occasionally be different than on a architecture without extended arithmetic and that due to double rounding. Compiling with -ffloat-store forces user declated floating point variables to be stored in memory and therefore be rounded as 32- or 64-bit floating point. The overhead is serious but it is helpful to diagnose the problem. Unfortunately, temporaries are still allocated to registers and this can still cause uncontrollable rounding.

forces user declated floating point variables to be stored in memory and therefore be rounded as 32- or 64-bit floating point. The overhead is serious but it is helpful to diagnose the problem. Unfortunately, temporaries are still allocated to registers and this can still cause uncontrollable rounding. It may be possible to modify the code to make it less sensitive to extended registers side effects. Especially, avoid equality tests on floating point variables. Occasionally, using " long double " explicitly, for instance on some reduction operations (sum, dot product, ...) may help.

" explicitly, for instance on some reduction operations (sum, dot product, ...) may help. The x87 control word can be modified by the application (examples) to round the 80-bit registers to double precision. Note that the exponent range is still extended format 15-bit and that only FADD, FSUB, FMUL, FDIV, and FSQRT instructions are affected.

Beware that the run-time libraries may not be properly protected and, consequently, it is advisable to restore the precision mode after a critical section. Moreover, gcc may perform some optimizations such as constant folding that do not honor the precision mode. A solution will be to use C99 " #pragma STDC FENV_ACCESS ON " when it is supported. Meanwhile, careful testing is required.

Beware that the run-time libraries may not be properly protected and, consequently, it is advisable to restore the precision mode after a critical section. Moreover, gcc may perform some optimizations such as constant folding that do not honor the precision mode. A solution will be to use C99 " " when it is supported. Meanwhile, careful testing is required. On x86, one may use the SSE/SSE2 instructions if available instead of x87 ones. Use gcc's -mfpmath=sse (refer to documentation for details). [Contents]

HP Debug flags [all compilers] +FP flags Specify how the runtime environment for trapping floating-point operations should be initialized at program startup. The default is that all traps are disabled. See ld(1) for specific values for flags.

You can try: +FP VZOuiD [f90] +fp_exceptions [f77] +T Enable floating-point exceptions and cause the running program to issue a procedure traceback for runtime errors. Can be mixed with +FP [f90] +check=all Enable compile-time range checking of array subscripts. [f90] +langlvl={90|default} Issue warnings for all extensions to the Fortran 90 standard (+langlvl=90). The default, +langlvl=default, allows extensions. [f90] +implicit_none Cause the types of identifiers to be implicitly undefined. [cc] -A<mode> Specify the compilation standard to be used by the compiler. [cc] +w<n> Specify the level of the warning messages. [aCC] -Aa ISO C++ conformance [aCC] +w Warn about all questionable constructs. [aCC] +p Disallows all anachronistic constructs. [all compilers] +Onoinitcheck The optimizer does not initialize uninitialized variables, but issues warning messages when it discovers them. [cc] +ESlit Place string literals and const-qualified data into read-only memory. [cc, aCC] -z Do not bind anything to address zero. This option allows run-time detection of null pointers. Tracing flags -Wc,-list,progress get the complete list of include files. -Wl,-y SYMBOL Print the name of each linked file in which SYMBOL appears. Runtime checking wdb 2.0 and later (HP-supported version of gdb) offers some memory debugging capability. [Contents]

IBM xlc and xlf debug flags -qflttrap Generate instructions to trap floating-point exceptions

(try: -qflttrap=inv:ov:zero:en ) -qfloat=nans Detects (at run time) operations that involve signaling NaN values (SNaN) -qflag=<sev1>:<sev2> Specifies severity level of diagnostics to be reported in listing, <sev1>, and on screen, <sev2>. Severity levels include: I Informational messages. L Language-level messages. W Warning messages. E Error messages. S Severe error messages. U Unrecoverable error messages. -qinitauto=<hh> Initialize automatic storage to <hh>. <hh> is a hexadecimal value. This generates extra code and should only be used for error determination.

Try: [xlc] -qinitauto=FF , [xlf] -qinitauto=FFF00000 -qlanglvl=<langlvl> Specify language level to be used during compilation. ([xlc] <langlvl> can be ansi, saal2, saa, extended, or classic) xlc debug flags -qextchk (AIX specific) Perform external name type-checking and function call checking. -qheapdebug (AIX specific) Enables debug versions of memory management functions -qlinedebug Generates abbreviated line number and source file name information for the debugger. -qro Put string literals in read only area. -qroconst Put constant values in read only area. -qsyntaxonly Causes the compiler to perform syntax checking without generating an object file. -qcheck=<option> Generate code to check for run-time checks. nullptr Runtime checking of addresses contained in pointer variables used to reference storage. bounds Runtime checking of addresses when subscripting within an object of known size. divzero Runtime checking of integer division. A trap will occur if an attempt is made to divide by zero. all Switches on all the above suboptions. -qinfo=all Produce additional lint-like messages. Turns on all diagnostic messages for all groups. xlf debug flags Note: xxlf allows one to put together the options through a GUI. -C or -qcheck Performs run-time checking of array bounds and character substring expressions. -qextchk (AIX specific) Performs procedure interface checking as well as detection of mismatched common blocks.

Done at link time. -qnosave Sets the storage class of local variables to AUTOMATIC. -u or -qundef Specifies undefined (no) implicit data typing. [Contents]

NAGWare Availability and documentation official web site

To make the compile mode of GNU Emacs compatible with f95, append the text below to your .emacs . ;; GNU Emacs 20.x (but not XEmacs) has broken the compilation regexps. ;; So add one for NAGWare f95 (require 'compile) (setq compilation-error-regexp-alist (append compilation-error-regexp-alist '(("^[A-Za-z ]+[:] \\([^.]+[.][a-zA-Z0-9]+\\), line \\([0-9]+\\)[:]" 1 2)))) Debug flags "Mandatory" options NAGWare f95 offers several flags that must be used unreservedly during development time. -C (and -C=all ) Compile code with most runtime checks enabled (including check of array bounds and check of procedure references). Version 5.0 of the compiler introduces "-C=undefined" that detects uninitialised variables. See documentation for limitation.

Do not think twice: hard code -C in your Makefile. -nan Initialise floating point variables to IEEE Signalling NaN. This includes local variables and INTENT(OUT) dummy arguments. This may be useful for finding uninitialised floating point variables while keeping the overhead low. Works only when -ieee=<mode> is set to "stop" (the default). Other useful flags -ieee=<mode> Set the mode of IEEE arithmetic operation according to mode, which must be one of full , nonstd or stop .

The default mode, -ieee=stop , is recommended for most situations. -info Request output of information messages. -M Produce module information files (.mod files) only.

In effect, it can be used to check syntax with minimal compilation.

-M -nomod allows a syntax check without any file produced. -u Specify that IMPLICIT NONE is in effect by default, unless overridden by explicit IMPLICIT statements. Runtime checking f95 offers run-time checking through the option -C (even when an array's last dimension is declared as * - look at the man page), can trap uninitialised floating point variables with -nan and perform uninitialised variables detection ( -C=undefined ).

Additionnaly, depending on the platform, you can: use tools.

On Linux x86, valgrind is the tool of choice. On Sun, available memory debuggers work.

On Linux x86, valgrind is the tool of choice. On Sun, available memory debuggers work. pass any relevant option to the C back-end by using -Wc,<option> -Wl,<option> . [Contents]

Portland Group compilers Availability and documentation compilers: pgf77 , pgf90 , pghpf , pgcc , pgCC

, , , , vendor home page Debug flags -g Includes debugging information in the object module. -Ktrap=option[,option]... Controls the behavior of the IA-32 processor when IA-32 floating-point exceptions occurs. -Ktrap=fp is equivalent to -Ktrap=inv,divz,ovf . -Mpgflag Selects options for code generation [no]bounds specifies whether array bounds checking is enabled or disabled. chkfpstk check for internal consistency of the x86 FP stack in the prologue of a function and after returning from a function or subroutine call. chkptr check for NULL pointers (pgf90 and pghpf only). chkstk check the stack for available space upon entry to and before the start of a parallel region. Useful when many private variables are declared. [no]dclchk determines whether all program variables must be declared (pgf77, pgf90, and pghpf only). [no]depchk checks for potential data dependences. info print informational messages regarding optimization and code generation to standard output as compilation proceeds. [no]iomutex determines whether critical sections are generated around Fortran I/O calls (pgf77, pgf90, and pghpf only). [no]save determines whether the compiler assumes that all local variables are subject to the SAVE statement (pgf77, pgf90, and pghpf only). standard causes the compiler to flag source code that does not conform to the ANSI standard (pgf77, pgf90, and pghpf only). [no]unixlogical determines whether logical .TRUE. and .FALSE. are determined by non-zero (TRUE) and zero (FALSE) values for unixlogical . With nounixlogical , the default, -1 values are TRUE and 0 values are FALSE (pgf77, pgf90, and pghpf only).

SGI Debug flags [all compilers] -DEBUG:subscript_check (or -C , Fortran only) check for subscripts out of range at runtime [all compilers] -DEBUG:trap_uninitialized (or -trapuv ) Force all un-initialized stack, automatic and dynamically allocated variables to be initialized with 0xFFFA5A5A. When this value is used as a floating point variable, it is treated as a floating point NaN and it will cause a floating point trap. When it is used as a pointer, an address or segmentation violation will most likely to occur.

Note: be aware that the program will trap on IEEE invalid exception. This exception can be produced by something else than an uninitialized variable, for instance sqrt(-1.) . [all compilers] -DEBUG:div_check=3 check all integer divides for zero divisors or overflow at run time. [all compilers except f90] -use_readonly_const -G0 -rdata_shared Puts string literals and file-level (static, common, or external) const qualified initialized variables into a .rodata section to separate these objects from data likely to be modified. This is the default. However, if you want constants to not be writable, then in addition to specifying -use_readonly_const , you must also specify -G0 -rdata_shared , because by default, the linker makes .rodata and gp-relative sections writable. [all compilers] -Wl,'-f <fill>' Sets the fill pattern for holes between sections within an output segment. The argument fill must be a four-byte hexadecimal constant.

In practice 0xFFFFFFFF will allow the detection of uninitialized static variables, essentially useful with Fortran. [all compilers] -ansi strict ansi [all compilers] -fullwarn full warnings [all compilers] -Hf (was -fe ) check syntax only (stop afer "front end") Type " man DEBUG_group " for more information. Floating point trapping First of all, any program compiled will -trapuv will trap on invalid. If your program is linked with -lfpe , then this flag forces floating-point errors to trap following the value of TRAP_FPE . Look at " man handle_sigfpes " for more information. You can use these aliases (for your .cshrc ) (adapted from Peter Shenkin): # floating point trap on SGI. Must be linked with -lfpe. # c.f. man handle_sigfpes. alias fpdebug setenv TRAP_FPE \ "UNDERFL=DEFAULT\;OVERFL=TRACE\(1\)\,ABORT\;DIVZERO=TRACE\(1\)\,ABORT\;INVALID=TRACE\(1\)\,ABORT" alias fpundebug 'unsetenv TRAP_FPE' # trap by default fpdebug If I say " fpdebug " at the shell level, then run a program linked with -lfpe , IEEE floating-point exceptions will be trapped ; if I haven't said " fpdebug ", or have later said " fpundebug ", the program will execute normally. Tracing flags -Wl,'-ySYMBOL' Print the name of each linked file in which SYMBOL appears. [Contents]

Sun Debug flags [all compilers] -xs Allow debugging by dbx without .o files. [all compilers] -ftrap=common Trap on invalid, division by zero, and overflow.

To be effective this option must be used when compiling the main program. [all compilers] -fnonstd -ftrap=common + disable gradual underflow. [all compilers] -xcheck=stkovf (>= 7.0) Checks for overflow at start of a function. [Fortran] -stackvar Allocate local variables on the stack. Useful to help catching uninitialized variables. [Fortran] -ansi Identify many non ANSI extensions. [Fortran] -C Check array references for out of range subscripts. [Fortran] -XlistE Do global program checking.

Try: -XlistE -Xlisto /dev/tty [Fortran] -fpover=yes Detect floating-point overflow in formatted input. [C] -fd Reports K&R function declarations and definitions. [C] -X[a|c|s|t] Specifies the degree of conformance to the ANSI/ISO C standard. [C] -xe Performs only syntax and semantic checking on the source file, but does not produce any object or executable file. [C] -xstrconst Inserts string literals into the read-only data section of the text segment instead of the default data segment. [C++] +w Prints extra warnings where necessary. [C++] +w2 Prints even more warnings. [C++] -features=conststrings Inserts string literals into the read-only memory. Tracing flags -H Print the name of each header file used. Runtime checking Some tools can help to detect uninitialized variables, memory corruptions and leaks (with Sun Fortran, think of -stackvar ). [Contents]

Windows and Linux Fortran compilers Debug flags Polyhedron survey comparing Fortran compilers on Windows and Linux. See options used in the Diagnostics capabilities sections.

sections. Herman D. (Skip) Knoble's survey focused on run-time diagnostic/debug capability of Win32 Fortran compilers.

A list of resources

Typical debug options: Compaq Visual Fortran /check:all /fpe:0 /traceback /warn:argument_checking /automatic Lahey (From User's Guide on Windows) For debugging, we recommend the following switch settings:

-chk (a,e,s,u,x) -chkglobal -g -pca -stchk -trace -w -info

(Note: Specifying -chkglobal or -chk (x) must be used for compilation of all files of the program, or incorrect results may occur.) [Contents]

x86 specifics Floating point trapping The examples below show how to trap the exceptions Invalid, Divide by zero and Overflow on the x87 and SSE floating point units. Floating point trapping on x87 and SSE FPU Systems Example for x87 Example for SSE Windows APIs Use _controlfp or _control87 . #include <float.h> unsigned int cw; /* could use _controlfp */ cw = _control87(0,0) & MCW_EM; cw &= ~(_EM_INVALID|_EM_ZERODIVIDE|_EM_OVERFLOW); _control87(cw,MCW_EM); With Visual Studio 2005, _controlfp and _control87 affect the control words for both the x87 and the SSE FPU. Linux/glibc 2.2 and later Use feenableexcept . #define _GNU_SOURCE 1 #include <fenv.h> feenableexcept(FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW); Use feenableexcept , which sets both the x87 and the SSE control words from glibc 2.3.3 onwards for x86_32. Linux/glibc 2.1 and older #include <fpu_control.h> fpu_control_t cw; _FPU_GETCW(cw); cw &= ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM); _FPU_SETCW(cw); These APIs do not affect the SSE FPU. FreeBSD FreeBSD post March 2005 implements feenableexcept . For older versions, follow the example below. #include <floatingpoint.h> fp_except_t cw; cw = fpgetmask(); fpsetmask(cw & ~(FP_X_INV | FP_X_DZ | FP_X_OFL)); Unknown Compilers supporting xmmintrin.h These APIs do not affect the x87 FPU. #include <xmmintrin.h> _MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK() & ~(_MM_MASK_INVALID| _MM_MASK_DIV_ZERO| _MM_MASK_OVERFLOW) ); gcc compatible assembler

(e.g. Cygwin) unsigned int cw; __asm__ __volatile__ ("fnstcw %0" : "=m" (cw)); cw &= ~(0x01 | 0x04 | 0x08); __asm__ __volatile__ ("fldcw %0" : : "m" (cw)); unsigned int cw; __asm__ __volatile__ ("stmxcsr %0" : "=m" (cw)); cw &= ~((0x01|0x04|0x08) << 7); __asm__ __volatile__ ("ldmxcsr %0" : : "m" (cw)); Floating point precision mode Under Linux/glibc, the x87 floating point processing unit operates by default under double extended precision. Under Win32 and FreeBSD, the default is set to double precision mode. This can lead to observed differences for some algorithms. Setting the precision mode and restoring it around a specific section is the most reliable way to fix the problem as illustrated below. References: gcc floating point behaviour

Douglas Priest's paper in the Sun's Numerical Computation Guide

S. W. Whiteley's paper #if defined(_WIN32) # include <float.h> # ifdef SINGLE # define _CW_PREC PC_24 # else # define _CW_PREC PC_53 # endif # define x86_SetPrecision \ unsigned int _oldcw_pc; \ _oldcw_pc = _control87(0,0) & MCW_PC; \ _control87(_CW_PREC,MCW_PC) # define x86_RestorePrecision \ _control87(_oldcw_pc,MCW_PC) #elif defined(i386) && defined(__FreeBSD__) # include <floatingpoint.h> # ifdef SINGLE # define _CW_PREC PC_PS # else # define _CW_PREC PC_PD # endif # define x86_SetPrecision \ fp_prec_t _oldcw_pc; \ _oldcw_pc = fpgetprec(); \ fpsetprec(_CW_PREC) \ # define x86_RestorePrecision \ fpsetprec(_oldcw_pc) #elif defined(i386) && defined(__GNUC__) # ifdef SINGLE # define _CW_PREC _FPU_SINGLE # else # define _CW_PREC _FPU_DOUBLE # endif # if defined(linux) # include <fpu_control.h> # else # define _FPU_EXTENDED 0x300 # define _FPU_DOUBLE 0x200 # define _FPU_SINGLE 0x0 # define _FPU_GETCW(cw) __asm__ __volatile__("fnstcw %0" : "=m" (*&cw)) # define _FPU_SETCW(cw) __asm__ __volatile__("fldcw %0" : : "m" (*&cw)) # define fpu_control_t unsigned int # endif # define x86_SetPrecision \ fpu_control_t _oldcw_pc; \ { fpu_control_t _cw; \ _FPU_GETCW(_cw); \ _oldcw_pc = _cw & _FPU_EXTENDED; \ _cw = (_cw & ~_FPU_EXTENDED) | _CW_PREC; \ _FPU_SETCW(_cw); \ } # define x86_RestorePrecision \ { fpu_control_t _cw; \ _FPU_GETCW(_cw); \ _cw = (_cw & ~_FPU_EXTENDED) | _oldcw_pc; \ _FPU_SETCW(_cw); \ } #else # define x86_SetPrecision # define x86_RestorePrecision #endif /* UNTESTED, see "ieee_flags" for an alternative */ #if defined(i386) && defined(__sun) && \ (defined(__SUNPRO_C) || defined(__SUNPRO_CC)) # include <fenv.h> # ifdef SINGLE # define _CW_PREC FE_FLTPREC # else # define _CW_PREC FE_DBLPREC # endif # define x86_SetPrecision \ int _oldcw_pc; \ _oldcw_pc = fegetprec(); \ fesetprec(_CW_PREC) \ # define x86_RestorePrecision \ fesetprec(_oldcw_pc) #endif

Compilers on super-computers NEC SX Refer to the CNRS/IDRIS documentation (in French). Cray debug flags [f90] -e ni i Generates a run-time error when an uninitialized local real or integer variable is used in a floating-point operation or array subscript

Also see the -f option on segldr(1) [ f90 -Wl"-f indef" ] and the -D preset= option on cld(1). n Generates messages to note all nonstandard Fortran usage, based on the Fortran 95 standard [f90] -Wl"-f indef" set undefined value in static variables (i.e. "COMMON") [f90] -m 0 Message types enabled: Error, warning, caution, note, and comment [f90] -R runchk run-time checks. Look at the documentation.

Ex: -Rab : arguments (type and number) and bound checking [f90] -t num (UNICOS Systems Only) The -t num option specifies the number of bits to be truncated on floating-point operations. For num , enter an integer in the range 0 num 47. The default is 0.

Useful for stability test. [Contents]

Acknowledgments Malcolm Cohen, Mario Deilmann, James Giles, Herman D. Knoble, Jean-Yves L'Excellent, Arjen Markus, Michel Olagnon, Gareth Shaw [Contents]

$Id: CompilerTricks.html,v 1.260 2008/01/28 13:51:50 adesitter Exp $ | Valid XHTML and CSS

by Arnaud Desitter.

© Arnaud Desitter, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008

This page can be redistributed as long as the copyright mention is preserved.