Using Run-Time Checking Options With The Sun Studio Fortran Compiler

   
By Diane Meirowitz, Senior Staff Engineer, Fortran Compiler Team, December, 2006  
 
 

The Sun Studio Fortran compiler provides several command line options to enable run-time checks that can help you find bugs in your Fortran programs.

From the f95 man page:

   -C
      enables array bounds and array syntax conformance checking

   -xcheck=[init_local | stkovf]
      init_local initializes local and allocated variables to special
      garbage values that are likely to to cause an arithmetic
      exception if they are used before set

      stkovf is a SPARC-only option that can detect stack overflow at run time.

   -xassume_control=[check[,fatal]]
      checks assertions specified with the ASSUME pragma, adding "fatal" causes
      the warning to be an error

   -xcommonchk
      detects when a common block is defined THREADPRIVATE in some but not all
      modules

   -fpover
      detects floating-point overflow in formatted input

The dbx rtc feature is not covered here, but can be extremely useful. It is currently available on SPARC platforms only. See the dbx manual for details.

Array Bounds Checking


The -C option enables, among other things, array bounds checking. If an array subscript is beyond the declared bounds of the array, an error message is printed and the program aborted.

Example:

 %  
             cat test.f
      subroutine copy(a,b)
      integer a(:), b(:), i
      do i = lbound(a,1), ubound(a,1)
         a(i) = b(i)
      end do
      end subroutine

      program
      integer, parameter :: n = 20
      integer a(1:n), b(1:n-1), i  ! notice b is declared 1:n-1
      interface
         subroutine copy(a,b)
         integer a(:), b(:), i
         end subroutine
      end interface

      call copy(a,b)
      end program

 %  
             f95 -C test.f
 %  
             a.out

       ******  FORTRAN RUN-TIME SYSTEM  ******
      Subscript out of range. Location:  line 4 column 12 of 'x.f'
      Subscript number 1 has value 20 in array 'B'
      Abort
          

Optimization and -C:

The -C option can be used with any level of optimization. At higher optimization levels, checking usually has only minimal effect on performance, because the checks are optimized along with the rest of the code.

Arrays whose last dimension has size 1:

Some Fortran 77 programs declare dummy arguments with the last dimension of size 1, rather than *. In order to avoid run time errors in working programs, the compiler does not generate bounds checks for the last dimension for dummy or Cray pointee arrays whose last dimension has size 1.

Array Syntax Conformance Checking


The -C option also enables conformance checking of array syntax statements.

Example:

 %  
             cat test.f
      subroutine copy(a,b,n,m)
      integer a(n), b(m)

      a = b
      end

      program
      integer, parameter :: n = 10
      integer a(n), b(n-1)
      call copy(a,b,n,n-1)
      end

 %  
             f95 -O3 -C test.f
 %  
             a.out
       ******  FORTRAN RUN-TIME SYSTEM  ******
       An array expression does not conform : dim 1 is 9 , not 10
       Location:  line 4 column 11 of 'test.f'
       Abort
          

Garbage Initialization for Local Variables


The -xcheck=init_local option can help you detect when a local variable is used before set. When this option is used, local variables are initialized to unusual values that are likely to cause an exception when used. The initialization is currently done for:

  • local stack or automatic variables
  • allocated variables (those allocated with MALLOC or ALLOCATE)

Syntax on all SPARC platform releases and x86 platform releases after Sun Studio 11:

     %  
             f95 -stackvar -xcheck=init_local file.f 
          

Syntax on x86 platforms for Sun Studio 11 and earlier:

      %  
             f95 -stackvar -qoption f95comp -xcheck=init_local file.f 
          

Example:

 %  
             cat test.f
        subroutine init_local

        real a, b, arr(10)
        integer c, d
        logical e
        complex f
        character*4 string
        integer, pointer :: ptr(:)
        integer v(10)
        pointer(p,v)

        print *, 'real=', a, ', int=', c
        print *, 'logical=', e, ', complex=', f
        print *, 'real array=', arr
        print *, 'char*4=', string
        allocate(ptr(6))
        print *, 'allocated ptr=', ptr
        p = malloc(sizeof(integer)*10)
        print *, 'malloced cray ptr=', v
        end subroutine

        call init_local
        end

 %  
             f95 -stackvar -xcheck=init_local test.f
 %  
             a.out

        real= -NaN , int= -8388565
        logical= T , complex= (-NaN,-NaN)
        real array= -NaN -NaN -NaN -NaN -NaN -NaN -NaN -NaN -NaN -NaN
        char*4=............
        allocated ptr= -8388565 -8388565 -8388565 -8388565 -8388565 -8388565
        malloced cray ptr= -8388565 -8388565 -8388565 -8388565 -8388565 -8388565
        -8388565 -8388565 -8388565 -8388565
          

If, while debugging, you encounter a local variable with an unusual value such as the above, there is a good chance that the variable has not been initialized.

IMPORTANT NOTE: Do not rely on the particular initial values that the compiler currently uses, as they are subject to change.

Stack Overflow Checking


The -xcheck=stkovf is currently available only on SPARC. It can be very useful for OpenMP programs, where the stack can be smaller than usual.

Example:

 %  
             cat test.f
        program
        call overflow
        end

        subroutine overflow
        integer, parameter :: n = 16000
        integer*8 :: a(n), b(n), c(n), d(n)
        a = b
        c = d
        print *,a(1:10),c(1:10)
        end

 %  
             f95 -stackvar -xcheck=stkovf test.f
 %  
             limit stacksize 100     # to force a very small stack
 %  
             a.out
   Segmentation Fault

 %  
             dbx a.out
   dbx>  
             run
   t@1 (l@1) signal SEGV (no mapping at the fault address) in __stack_grow_probing_impl at 0x1347c
   0x0001347c: __stack_grow_probing_impl+0x0004:   ldsb     [%o0], %g0
          

The segmentation fault alerts you that stack overflow may have taken place. To check, run dbx; if the executable terminates in the above function, stack overlow has occurred.

ASSUME Pragmas


The -xassume_control=check option causes the compiler to check the value of ASSUME pragmas, and generate a message when the value is not true. ASSUME pragmas are described in detail in the Fortran User's Guide. When they are not being used for run time checking, ASSUME pragmas can also improve optimization.

Example:

        subroutine check (a,b,c)
        integer a, b, c, d

c$pragma assume (a > 0, 1.0)   ! 1.0 means 100% certainty, which enables checking
c$pragma assume (b > 0, 1.0)

        print *, a, b, c

        d = 0
c$pragma begin assume (__tripcount().lt.1000, 1.0)
        do i = 1, c
           d = d + 1
        end do
c$pragma end assume

        print *, d
        end

        call check(1, -1, 1000)
        end

With -xassume_control=check when an assume error is detected a message is printed and execution continues:

      %  
             f95 -xO3 -xassume_control=check test.f
      %  
             a.out
      Assume check failure at assume.f:5
      Assume check failure at assume.f:10
       1 -1 1000
       1000
          

With -xassume_control=check,fatal when an assume error is detected a message is printed and the program is terminated:

      %  
             f95 -xO3 -xassume_control=check,fatal test.f
      %  
             a.out
      Assume check failure at assume.f:5
          

NOTE: only ASSUME pragmas with probabilities of 1.0 are checked at run time, and any level of optimization may be used.

THREADPRIVATE Common Checking


The -xcommonchk option adds run time checking to detect when a common block is defined THREADPRIVATE in some but not all program units. This option should be used for debugging only since it can degrade performance. The following is an example of its use.

   common.f:
        program
        real a(100)
        common /mycommon/ a
        call abc()
        end program

   abc.f:
        subroutine abc()
        real a(100)
        common /mycommon/ a
!$omp   threadprivate (/mycommon/)
        a = 0
        end subroutine

 %  
             f95 -O3 -xopenmp -xcommonchk common.f abc.f
 %  
             setenv OMP_NUM_THREADS 2
 %  
             a.out

      ERROR (libmtsk): at abc.f:3. Inconsistent declaration of threadprivate
       mycommon_ : Not declared as threadprivate at line 4 of common.f 
          

Floating Point Overflow Checking


The -fpover option enables a program to handle floating-point overflow in formatted input.

   test.f:
      integer status
      real r

      read (*, *, iostat=status) r
      if (status.eq.1031) then
         print *, 'Floating point overflow on input', r
      end if
      end

   input:
      1e+100

The -ftrap=%none flag is required with -fpover.

 %  
             f95 -fpover -ftrap=%none test.f
 %  
             a.out <input
Floating point overflow on input Inf
          

If the READ statement does not contain an IOSTAT= argument, a Fortran run time error is emitted when floating point overflow is detected in a formatted input value.

   test.f:
      integer status
      real r

      read (*, *) r
      print *, r

      end

 %  
             f95 -fpover -ftrap=%none test.f
 %  
             a.out <input

    ******  FORTRAN RUN-TIME SYSTEM  ******
    Error 1031:  floating-point overflow on input
    Unit:  *
    File:  standard input
    Abort
          
 
Rate and Review
Tell us what you think of the content of this page.
Excellent   Good   Fair   Poor  
Comments:
Your email address (no reply is possible without an address):
Sun Privacy Policy

Note: We are not able to respond to all submitted comments.
Left Curve
System Administrator
Right Curve
Left Curve
Developer and ISVs
Right Curve
Left Curve
Related Products
Right Curve
solaris-online-forum-banner