You can debug XL Fortran programs with any dbx-compatible symbolic debugger. For background information on dbx, see the AIX General Concepts and Procedures book. For information on dbx subcommands, see the AIX Commands Reference.
The following example represents a typical XL Fortran problem that you may be able to resolve through dbx. Although it demonstrates only a small subset of dbx features, and uses memory-allocation techniques made obsolete by Fortran 90/Fortran 95 allocatable arrays, it can serve as an introduction if you have not used this debugger before.
The following program tries to allocate an array at run time by using the AIX system subroutine malloc. When you use the following command to compile the program, and then run the program, the program produces a core dump:
xlf95 -qddim testprog.f -o testprog
At this point, you may be wondering whether the C malloc routine is working correctly, or whether this is the right way to allocate an array in a main program when the dimensions are not known until run time.
program main pointer(p, array(nvar,nrec)) real*8 array nvar = 2 nrec = 3 p = malloc(nvar*nrec*8) call test_sub(array, nvar, nrec) end subroutine test_sub(array, nvar, nrec) dimension array(nvar, nrec) array(1,1) = 1. array(2,1) = 2. array(1,2) = 3. array(2,2) = 4. array(1,3) = 5. array(2,3) = 6. write(*, 100) array(1,1), array(2,1), array(1,2), 1 array(2,2), array(1,3), array(2,3) 100 format(//t2,f4.1/t2,f4.1/t2,f4.1/t2,f4.1/ 1 t2,f4.1/t2,f4.1) return end
You might go through the debugging process as follows:
-> xlf -qddim -g testprog.f -o testprog ** main === End of Compilation 1 === ** test_sub === End of Compilation 2 === 1501-510 Compilation successful for file testprog.f. |
-> testprog Segmentation fault(coredump) -> |
-> dbx testprog core dbx version 3.1 for AIX. Type 'help' for help. reading symbolic information ... [using memory image in core] segmentation violation in test_sub at line 21 in file "testprog.f" 21 array(1,1) = 1. (dbx) |
(dbx) where test_sub(array = (...), nvar = warning: Unable to access address 0x200aee94 from core -1, nrec = warning: Unable to access address 0x200aee98 from core -1), line 21 in "testprog.f" main(), line 12 in "testprog.f" (dbx) |
main calls test_sub at line 12. The warning indicates that a problem occurs while evaluating the arguments for this call.
(dbx) print array(1,1) reference through nil pointer (dbx) |
This suggests that array does not have a value assigned. To verify that possibility, try to look at the address of an element in the array:
(dbx) p &array(1,1) (nil) (dbx) |
It seems that XL Fortran has not allocated the space for the array. To verify that it has not, print the value of the pointer that points to the array:
(dbx) print p warning: Unable to access address 0x200aee90 from core 0xffffffff |
(dbx) stop in main [1] stop in main (dbx) run [1] stopped in main at line 7 in file "testprog.f" 7 nvar = 2 (dbx) trace p [3] trace p (dbx) cont initially (at line 8 in "testprog.f"): p = nil segmentation violation in test_sub at line 21 in file "testprog.f" 21 array(1,1) = 1. (dbx) p p nil (dbx) |
Because p is never set to a valid value, something must be wrong with the line that allocates space for the array:
9 p = malloc(nvar*nrec*8) |
When you read that section, you find that calls to C functions require arguments to be passed by value rather than by reference. To fix the problem in this sample program, replace the line:
p = malloc(nvar*nrec*8)
with the line:
p = malloc(%val(nvar*nrec*8))
-> xlf95 -qddim -g solution.f -o solution ** main === End of Compilation 1 === ** test_sub === End of Compilation 2 === 1501-510 Compilation successful for file solution.f. -> solution 1.0 2.0 3.0 4.0 5.0 6.0 |
-> dbx solution dbx version 3.1 for AIX. Type 'help' for help. Core file program (testprog) does not match current program (core ignored) reading symbolic information ... (dbx) trace p [1] trace p (dbx) run initially (at line 7 in "solution.f"): p = nil after line 9 in "solution.f": p = 0x200af100 1.0 2.0 3.0 4.0 5.0 6.0 execution completed (dbx) |
To check whether the values of p and array are appropriate, turn off the trace:
(dbx) status [1] trace p (dbx) delete all (dbx) status (dbx) |
Then set new break points and run through the program again. Notice that the address of array(1,1) is the same as the contents of p(0x200af100), as expected:
(dbx) stop at 9 [11] stop at "solution.f":9 (dbx) run [11] stopped in main at line 9 in file "solution.f" 9 p = malloc(%val(nvar*nrec*8)) (dbx) p p nil (dbx) next stopped in main at line 12 in file "solution.f" 12 call test_sub(array, nvar, nrec) (dbx) p p 0x200af100 <------------- (dbx) (dbx) step /* Notice we use step to step into subroutine test_sub */ stopped in test_sub at line 21 in file "solution.f" 21 array(1,1) = 1. (dbx) p &array(1,1) 0x200af100 <--------------- (dbx) next stopped in test_sub at line 22 in file "solution.f" 22 array(2,1) = 2. (dbx) p array(1,1) 1.0 (dbx) |