Chapter 5 Program Analysis and Debugging
This chapter presents a number of compiler features that facilitate
program analysis and debugging.
5.1 Global Program Checking (-Xlist)
The -Xlist options provide
a valuable way to analyze a source program for inconsistencies and possible
runtime problems. The analysis performed by the compiler is global,
across subprograms.
–Xlist reports errors in alignment, agreement in number and type for subprogram arguments, common block, parameter, and various other kinds of errors.
–Xlist also can be used to make detailed source
code listings and cross-reference tables.
Programs compiled with -Xlist options have their
analysis data built into the binary files automatically. This enables global
program checking over programs in libraries.
5.1.1 GPC Overview
Global program checking (GPC), invoked by the -Xlistx option, does the following:
-
Enforces type-checking rules of Fortran more
stringently than usual, especially between separately compiled routines
-
Enforces some portability restrictions needed to move programs
between different machines or operating systems
-
Detects legal constructions that nevertheless might be suboptimal
or error-prone
-
Reveals other potential bugs and obscurities
In particular, global checking reports problems such as:
-
Interface problems
-
Conflicts in number and type of dummy and actual arguments
-
Wrong types of function
values
-
Possible conflicts due to data type mismatches in common blocks
between different subprograms
Usage problems
-
Function
used as a subroutine or subroutine
used as a function
-
Declared but unused functions, subroutines, variables, and labels
-
Referenced but not declared functions,
subroutines, variables, and labels
-
Usage of unset variables
-
Unreachable statements
-
Implicit type variables
-
Inconsistency
of the named common block lengths, names, and layouts
5.1.2 How to Invoke Global Program Checking
The -Xlist option on the command line invokes the
compiler’s global program analyzer. There are a number of suboptions,
as described in the sections that follow.
Example: Compile three files for basic global program checking:
demo% f95 -Xlist any1.f any2.f any3.f
|
In the preceding example, the compiler:
5.1.2.1 Screen Output
Normally, output listings produced by -Xlistx are written to a file. To display directly to the screen, use -Xlisto to write the output file to /dev/tty.
Example: Display to terminal:
demo% f95 -Xlisto /dev/tty any1.f
|
5.1.2.2 Default Output Features
The –Xlist option provides a combination of features available for output.
With no other -Xlist options, you get the following by
default:
-
The listing file name is taken from the first input source
or object file that appears, with the extension replaced by .lst
-
A line-numbered source listing
-
Error messages (embedded in listing) for inconsistencies across
routines
-
Cross-reference table of the identifiers
-
Pagination at 66 lines per page and 79 columns per line
-
No call graph
-
No expansion of include files
5.1.2.3 File Types
The checking process recognizes all the files in the compiler command
line that end in .f, .f90, .f95, .for, .F, .F95, or .o.
The .o files supply the process with information regarding
only global names, such as subroutine and function names.
5.1.3 Some Examples of -Xlist and Global
Program Checking
Here is a listing of the Repeat.f source code used
in the following examples:
demo% cat Repeat.f
PROGRAM repeat
pn1 = 27.005
CALL subr1 ( pn1 )
CALL newf ( pn1 )
PRINT *, pn1
END
SUBROUTINE subr1 ( x )
IF ( x .GT. 1.0 ) THEN
CALL subr2 ( x * 0.5 )
END IF
END
SUBROUTINE newf( ix )
INTEGER PRNOK
IF (ix .eq. 0) THEN
ix = -1
ENDIF
PRINT *, prnok ( ix )
END
INTEGER FUNCTION prnok ( x )
prnok = INT ( x ) + .05
END
SUBROUTINE unreach_sub()
CALL sleep(1)
END
SUBROUTINE subr2 (x)
CALL subr1(x+x)
END
|
Example: Use -XlistX to show errors, warnings, and
cross-reference
demo% f95 -XlistX Repeat.f
demo% cat Repeat.lst
Repeat.f Mon Mar 18 18:08:27 2002 page 1
FILE "Repeat.f"
program repeat
4 CALL newf ( pn1 )
^
**** ERR #418: argument "pn1" is real, but dummy argument is integer
See: "Repeat.f" line #14
5 PRINT *, pn1
^
**** ERR #570: variable "pn1" referenced as real but set as integer in
line #4
subroutine newf
19 PRINT *, prnok ( ix )
^
**** ERR #418: argument "ix" is integer, but dummy argument is real
See: "Repeat.f" line #22
function prnok
23 prnok = INT ( x ) + .05
^
**** WAR #1024: suspicious assignment a value of type "real*4" to a
variable of type "integer*4"
subroutine unreach_sub
26 SUBROUTINE unreach_sub()
^
**** WAR #338: subroutine "unreach_sub" never called from program
subroutine subr2
31 CALL subr1(x+x)
^
**** WAR #348: recursive call for "subr1". See dynamic calls:
"Repeat.f" line #10
"Repeat.f" line #3
Cross Reference Mon Mar 18 18:08:27 2002 page 2
C R O S S R E F E R E N C E T A B L E
Source file: Repeat.f
Legend:
D Definition/Declaration
U Simple use
M Modified occurrence
A Actual argument
C Subroutine/Function call
I Initialization: DATA or extended declaration
E Occurrence in EQUIVALENCE
N Occurrence in NAMELIST
L Use Module
Cross Reference Mon Mar 18 15:40:57 2002 page 3
P R O G R A M F O R M
Program
-------
repeat <repeat> D 1:D
Cross Reference Mon Mar 18 15:40:57 2002 page 4
Functions and Subroutines
-------------------------
INT intrinsic
<prnok> C 23:C
newf <repeat> C 4:C
<newf> D 14:D
prnok int*4 <newf> DC 15:D 19:C
<prnok> DM 22:D 23:M
sleep <unreach_sub> C 27:C
subr1 <repeat> C 3:C
<subr1> D 8:D
<subr2> C 31:C
subr2 <subr1> C 10:C
<subr2> D 30:D
unreach_sub <unreach_sub> D 26:D
Cross Reference Mon Mar 18 15:40:57 2002 page 5
Variables and Arrays
--------------------
ix int*4 dummy
<newf> DUMA 14:D 16:U 17:M 19:A
pn1 real*4 <repeat> UMA 2:M 3:A 4:A 5:U
x real*4 dummy
<subr1> DU 8:D 9:U 10:U
<subr2> DU 30:D 31:U 31:U
<prnok> DA 22:D 23:A
------------------------------------------------------------------
STATISTIC Mon Mar 18 15:40:57 2002 page 6
Date: Mon Mar 18 15:40:57 2002
Options: -XlistX
Files: 2 (Sources: 1; libraries: 1)
Lines: 33 (Sources: 33; Library subprograms:1)
Routines: 6 (MAIN: 1; Subroutines: 4; Functions: 1)
Messages: 6 (Errors: 3; Warnings: 3)
|
5.1.4 Suboptions for Global Checking Across Routines
The basic global
cross-checking option is -Xlist with no suboption. It is
a combination of suboptions, each of which could have been specified separately.
The following sections describe options for producing the listing, errors,
and cross-reference table. Multiple suboptions may appear on the command line.
5.1.4.1 Suboption Syntax
Add suboptions according to the following rules:
-
Append the suboption to -Xlist.
-
Put no space between the -Xlist and the
suboption.
-
Use only one suboption per -Xlist.
5.1.4.2 -Xlist and its Suboptions
Combine suboptions according to the following rules:
-
The most general option is -Xlist (listing,
errors, cross-reference table).
-
Specific features can be combined using -Xlistc, -XlistE, -XlistL, or -XlistX.
-
Other suboptions specify further details.
Example: Each of these two command lines performs the same task:
demo% f95 -Xlistc -Xlist any.f
|
The following table shows the reports generated by these basic -Xlist suboptions alone:
Table 5–1
Basic Xlist Suboptions
|
Generated Report
|
Option
|
|
Errors, listing, cross-reference
|
–Xlist
|
|
Errors only
|
–XlistE
|
|
Errors and source listing only
|
–XlistL
|
|
Errors and cross-reference table only
|
–XlistX
|
|
Errors and call graph only
|
–Xlistc
|
The following table shows all -Xlist suboptions.
Table 5–2 Complete List of
-Xlist Suboptions
|
Option
|
Action
|
|
–Xlist (no suboption)
|
Shows errors, listing, and cross-reference table
|
|
–Xlistc
|
Shows call graphs and errors
Used alone, -Xlistc does not show a listing or cross-reference.
It produces the call graph in a tree form, using printable characters. If
some subroutines are not called from MAIN, more than one
graph is shown. Each BLOCKDATA is printed separately with
no connection to MAIN.
The default is not to show the call graph.
|
|
–XlistE
|
Shows errors
Used alone, -XlistE shows only cross-routine errors
and does not show a listing or a cross-reference.
|
|
–Xlisterr[nnn]
|
Suppresses error nnn in the verification
report
Use -Xlisterr to suppress a numbered error message
from the listing or cross-reference.
For example: -Xlisterr338 suppresses error message
338. To suppress additional specific errors, use this option repeatedly. If nnn is not specified, all error messages are suppressed.
|
|
–Xlistf
|
Produces output faster
Use -Xlistf to produce source file listings and a
cross-checking report and to check sources without full compilation.
|
|
–Xlisth
|
Shows errors from cross-checking stop compilation
With -Xlisth, compilation stops if errors are detected
while cross-checking the program. In this case, the report is redirected to stdout instead of the *.lst file.
|
|
–XlistI
|
Lists and cross-checks include files
If -XlistI is the only suboption used, include files
are shown or scanned along with the standard -Xlist output
(line numbered listing, error messages, and a cross-reference table).
Listing—If the listing is not suppressed,
then the include files are listed in place. Files are listed
as often as they are included. The files are: Source files, #include files, INCLUDE files
Cross-Reference Table—If the cross reference
table is not suppressed, the following files are all scanned while the cross
reference table is generated: Source files, #include files, INCLUDE files
The default is not to show include files.
|
|
–XlistL
|
Shows the listing and errors
Use -XlistL to produce only a listing and a list
of cross routine errors. This suboption by itself does not show a cross reference
table. The default is to show the listing and cross reference table
|
|
–Xlistln
|
Sets page breaks
Use -Xlistl to set the page length to something other
than the default page size. For example, -Xlistl45 sets
the page length to 45 lines. The default is 66.
With n=0 (-Xlistl0) this
option shows listings and cross-references with no page breaks for easier
on-screen viewing.
|
|
-XlistMP
|
(SPARC) Check consistency of OpenMP
directives
Use -XlistMP to report on any inconsistencies in
the OpenMP directives specified in the source code file. See also the OpenMP
API User’s Guide for details.
|
|
–Xlisto name
|
Specify the -Xlist output report file
Use -Xlisto to specify the generated report output
file. (A space between o and name is
required.) With -Xlisto name, the output is to name and
not to file.lst.
To display directly to the screen, use the option: -Xlisto
/dev/tty
|
|
–Xlists
|
Suppresses unreferenced symbols from cross-reference
Use -Xlists to suppress from the cross reference
table any identifiers defined in the include files but
not referenced in the source files.
This suboption has no effect if the suboption -XlistI is
used.
The default is not to show the occurrences in #include or INCLUDE files.
|
|
–Xlistvn
|
Sets checking “strictness” level
n is 1,2, 3,
or 4. The default is 2 (–Xlistv2):
-
–Xlistv1
Shows the cross-checked
information of all names in summary form only, with no line numbers. This
is the lowest level of checking strictness—syntax errors only.
-
–Xlistv2
Shows cross-checked
information with summaries and line numbers. This is the default level of
checking strictness and includes argument inconsistency errors and variable
usage errors.
-
–Xlistv3
Shows cross-checking
with summaries, line numbers, and common block maps. This is a high level
of checking strictness and includes errors caused by incorrect usage of data
types in common blocks in different subprograms.
-
–Xlistv4
Shows cross-checking
with summaries, line numbers, common block maps, and equivalence block maps. This is the
strictest level of checking with maximum error detection.
|
|
–Xlistw[nnn]
|
Sets the width of output lines
Use -Xlistw to set the width of the output line.
For example, -Xlistw132 sets the page width to 132 columns.
The default is 79.
|
|
–Xlistwar[nnn]
|
Suppresses warning nnn in the report
Use -Xlistwar to suppress a specific warning message
from the output reports. If nnn is not specified,
then all warning messages are suppressed from printing. For example, -Xlistwar338 suppresses warning message number 338. To suppress more than one,
but not all warnings, use this option repeatedly.
|
|
–XlistX
|
Shows just the cross-reference table and errors
-XlistX produces a cross reference table and cross
routine error list but no source listing.
|
5.2 Special Compiler Options
Some compiler options are useful for debugging. They check subscripts,
spot undeclared variables, show stages of the compile-link sequence, display
versions of software, and so on.
The Solaris linker has additional debugging aids. See ld(1),
or run the command ld –Dhelp at
a shell prompt to see the online documentation.
5.2.1 Subscript Bounds (–C)
If you compile with -C, the compiler adds checks at runtime for
out-of-bounds references on each array subscript,
and array conformance. This action helps catch some situations that cause segmentation
faults.
Example: Index out of range:
demo% cat range.f
REAL a(10,10)
k = 11
a(k,2) = 1.0
END
demo% f95 -o range range.f
demo% range
****** FORTRAN RUN-TIME SYSTEM ******
Subscript out of range. Location: line 3 column 9 of ’range.f’
Subscript number 1 has value 11 in array ’A’
Abort
demo%
|
5.2.2 Undeclared Variable Types (–u)
The -u option checks for any undeclared variables.
The -u option causes all variables to be initially
identified as undeclared, so that all variables that are not explicitly
declared by type statements, or by an IMPLICIT statement,
are flagged with an error. The -u flag is useful for discovering
mistyped variables. If -u is set, all variables are treated
as undeclared until explicitly declared. Use of an undeclared variable is
accompanied by an error message.
5.2.3 Compiler Version Checking (–V)
The –V option causes the name and version ID of each phase of
the compiler to be displayed. This option can be useful in tracking the origin
of ambiguous error messages and in reporting compiler failures, and to verify
the level of installed compiler patches.
demo% f95 -V wh.f
f95: Sun Fortran 95 7.0 DEV 2002/01/30
f90comp: Sun Fortran 95 7.0 DEV 2002/01/30
f90comp: 9 SOURCE LINES
f90comp: 0 ERRORS, 0 WARNINGS, 0 OTHER MESSAGES, 0 ANSI
ld: Solaris Link Editors: 5.8-1.272
|
5.3 Debugging With dbx
Sun Studio provides a tightly integrated development environment
for debugging applications written in Fortran, C, and C++.
The dbx program provides event management, process
control, and data inspection. You can watch what is happening
during program execution, and perform the following tasks:
-
Fix one routine, then continue executing without recompiling the
others
-
Set watchpoints to stop or trace if a specified item changes
-
Collect data for performance tuning
-
Monitor variables, structures, and arrays
-
Set breakpoints (set places to halt in the program) at lines
or in functions
-
Show values—once halted, show or modify variables, arrays,
structures
-
Step through a program, one source or assembly line at a time
-
Trace program flow—show sequence of calls taken
-
Invoke procedures in the program being debugged
-
Step over or into function calls; step up and out of a function
call
-
Run, stop, and continue execution at the next line or at some
other line
-
Save and then replay all or part of a debugging run
-
Examine the call stack, or move up and down the call stack
-
Program scripts in the embedded Korn shell
-
Follow programs as they fork(2) and exec(2)
To debug optimized programs, use the dbx fix command
to recompile the routines you want to debug:
-
Compile the program with the appropriate -On optimization level.
-
Start the execution under dbx.
-
Use fix -g any.f without optimization on the routine you want to debug.
-
Use continue with that routine compiled.
Some optimizations will be inhibited by the presence of -g on
the compilation command. See the dbx documentation for
details.
For details, see the Sun Studio Debugging a Program With dbx manual, and the dbx(1) man pages.