This debugging session illustrates how to use the commands and features of CodeWatch when debugging programs compiled with Open PL/I. Following the session is the source listing of the sample PL/I program. The source file for this program is also available on the CodeWatch installation media.
The sample program, primes.pl1, calculates the number of prime numbers within a given range, but it doesn't do it very well. There is a bug somewhere that causes the program to print out too many values. Observe the following output:
*** Sieve of Eratosthenes *** Input maximum prime boundary: 10 Number of primes found was 6 1 2 3 5 7 11
The program had been compiled using the -deb option to produce the necessary information for the debugger and the -l option to produce a listing file. It was then linked using Ipild. For example,
mfpli primes.pl1 -deb -l ldpli primes.o -o primes
In this sample session, comments (which are not part of the session) are the bullet items. The system prompt is $. Note that user-supplied text is in bold typewriter font. For clarity, the abbreviated form of the command is used only after the command has been previously spelled out in its entirety.
$ cwcmd primes ****************************************************************************** * CodeWatch, 08.00 * * ---------------- * * Copyright 2009 Micro Focus * ****************************************************************************** Initial evaluation environment is PRIMES:(inactive)
CodeWatch> FIND main 3: primes: procedure options (main); CodeWatch> FIND main 109: /* main procedure */
CodeWatch> PRINT 20 109 /* main procedure */ 110 111 declare n fixed binary(31); 112 113 put skip; 114 put list (' *** Sieve of Eratosthenes ***'); 115 put skip (2); 116 117 call read_input(n); 118 119 do while (n > 1); 120 call sift(n); 121 call read_input(n); 122 end; 123 124 end; 125 BOTTOM
CodeWatch> BREAK 119
CodeWatch> CONTINUE *** Sieve of Eratosthenes *** Input maximum prime boundary: 10 Break at PRIMES\119
CodeWatch> P 119: do while (n > 1); CodeWatch> EVALUATE n N = 10 {fixed binary (31)}
CodeWatch> TYPE n N fixed binary (31) automatic
CodeWatch> DSTEP [P] CodeWatch> STEP Step at PRIMES\120 120: call sift(n);
CodeWatch> S IN Step at PRIMES.SIFT\%ENTRY 77: sift: procedure (n);
CodeWatch> ARGUMENTS N = 10 {fixed binary (31)}
CodeWatch> STACK /ALL Stack contains 7 frame(s). Current execution point is PRIMES.SIFT\%ENTRY 7: Owner is "PRIMES.SIFT" In [ primes.exe ] Called from PRIMES\121 6: Owner is "PRIMES" In [ primes.exe ] Called from _lpi_main+0x71 (non-debug) 5: Owner is "_lpi_main" In [ primes.exe ] Called from _tmainCRTStartup+0x10f (non-debug) 4: Owner is "_tmainCRTStartup" In [ primes.exe ] Called from 0x750c339a 3: Owner is "0x750c339a" In [ C:\Windows\syswow64\kernel32.dll ] Called from 0x76f69ef2 2: Owner is "0x76f69ef2" In [ C:\Windows\syswow64\ntdll.dll ] Called from 0x76f69ec5 1: Owner is "0x76f69ec5"
CodeWatch> POINT 98 98: do while (k < n); CodeWatch> P 5 98: do while (k < n); 99: /* cancel all multiples */ 100: flags(k) = FALSE; 101: k = k + this_prime; 102: end;
CodeWatch> B 100 CodeWatch> C Break at PRIMES.SIFT\100
CodeWatch> TRACE STATEMENT CodeWatch> C **** PRIMES.SIFT\101 **** PRIMES.SIFT\102 **** PRIMES.SIFT\98 Break at PRIMES.SIFT\100 CodeWatch> C **** PRIMES.SIFT\101 **** PRIMES.SIFT\102 **** PRIMES.SIFT\98 Break at PRIMES.SIFT\100
CodeWatch> MACRO fig=[FIND /IGNORE] CodeWatch> fig PRINT_OUT 105: call print_out(primes,count); /* should be count - 1 */
CodeWatch> NBREAK CodeWatch> B 105 CodeWatch> NTRACE S CodeWatch> C Break at PRIMES.SIFT\105
CodeWatch> E count COUNT = 6 {fixed binary (31)}
CodeWatch> B sift\%ENTRY CodeWatch> RELOAD Command line : "primes" Reloading..ok Initial evaluation environment is PRIMES:(inactive) CodeWatch> C *** Sieve of Eratosthenes *** Input maximum prime boundary: 10 Break at PRIMES\119 CodeWatch> C Break at PRIMES.SIFT\%ENTRY
CodeWatch> S Step at PRIMES.SIFT\85 85: do I = 1 to n; CodeWatch> P 15 85: do I = 1 to n; 86: flags(I) = TRUE; 87: end; 88: 89: count = 1; 90: primes(1) = 1; 91: 92: do I = 1 to n; 93: if flags(I) = TRUE then do; 94: this_prime = I + 1; 95: count = count + 1; 96: primes(count) = this_prime; 97: k = I + this_prime; 98: do while (k < n); 99: /* cancel all multiples */
CodeWatch> B 95 /IF {count > 4} /ELSE [E count] CodeWatch> C COUNT = 1 {fixed binary (31)} COUNT = 2 {fixed binary (31)} COUNT = 3 {fixed binary (31)} COUNT = 4 {fixed binary (31)} Break at PRIMES.SIFT\95 Break at PRIMES.SIFT\105
CodeWatch> NB CodeWatch> P Break at PRIMES.SIFT\105 105: call print_out(primes,count); /* should be count - 1 */
CodeWatch> E count COUNT 6 {fixed binary (31)} CodeWatch> LET count=count-1 CodeWatch> C Number of primes found was (prime itself) 5 1 2 3 5 7 Input maximum prime boundary: 10 Break at PRIMES\119
CodeWatch> RE Command line : "primes" Reloading..ok Initial evaluation environment is PRIMES:(inactive) CodeWatch> NBREAK /ALL
CodeWatch> B 105 /SILENT [LET count=count-1;C] CodeWatch> C *** Sieve of Eratosthenes *** Input maximum prime boundary: 10 Number of primes found was (prime itself) 5 1 2 3 5 7 Input maximum prime boundary: 100 Number of primes found was 26 1 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 Input maximum prime boundary: 0 Program exited with status 0 Reloading..ok Initial evaluation environment is PRIMES:(inactive)
call print_out(primes,count);
to:
call print_out(primes,count-1);
the program will work just fine! Quit out of the debugger session.
CodeWatch> QUIT CodeWatch Quit...Bye!