Sample debugging session
We’ve used a Synergy program called badship.dbl in our sample debugging session. Badship.dbl creates a report of bad shipments with the specified starting and ending dates. The user can also specify the customer’s ID number and the output device that should be used to report the results.
We know that the badship.dbl program has three problems:
- When a customer’s ID number is specified, badship.dbl doesn’t find anything, even if it should.
- The starting date for the search doesn’t work correctly.
- The “No bad records…” message is not sent to the screen even if no bad records exist.
First, we’ll compile, link, and run the program with the debug option. (Note that these commands do not apply to OpenVMS systems. See Building and Running Synergy Applications for the correct compile, link, and run commands for OpenVMS.)
$ dbl -d badship $ dblink -d badship $ dbr -d badship *** DEBUG 8.3.1 *** Break at 121 in BADSHIP (badship.dbl) *121: xcall flags(7004020, 1)
Now that we’re in the debugger, we’ll use the HELP command to list all available debugger commands.
DBG> help Help is available on: BREAK - Set a program breakpoint CANCEL - Cancel program breakpoints and watchpoints DEPOSIT - Modify variables DELETE - Delete program breakpoints EXAMINE - Examine variables GO - Continue program execution LIST - List source lines OPENELB - Open the specified ELB or shared image SAVE - Save the current debugger context SCREEN - Do screen manipulation SEARCH - Search source SET - Set debug options SHOW - Display debug options and program state information STEP - Step to the next Synergy DBL instruction TRACE - Display current traceback VIEW - View Synergy DBL source around the debug entry WATCH - Set a watchpoint WINDBG - Invoke the Toolkit window debugger Cmd_Inp - Command recall and editing @ - Process an indirect command file ! - Execute a shell command
We’ll view the source lines that surround the debug entry and then set the default mode for the STEP command, set the debugger to break whenever the program traps an error, and examine all debugger parameters.
DBG> view 117: ,a2 118: rep ,a5 119: 120: proc 121> xcall flags(7004020, 1) 122: open(TT_CH, i, "tt:") 123: display(TT_CH, $scr_clr(SCREEN), "Create bad shiplist.",10,13) 124: do 125: begin DBG> set step into DBG> set trap on DBG> show The debugger wasn't entered in an error state. No breakpoints are set. Default step mode is "INTO" %DBR-I-ATLINE, at line 120 in routine MAIN$BADSHIP (badship.dbl) A trapped DBL error will cause a break. DBL stack size 4096 bytes; now using 32; maximum used 0. No DBL channels opened. DBGSRC not set
Now we’ll list 140 lines beginning at line 120 so we can determine possible problem spots.
DBG> list 120 140 120: proc 121> xcall flags(7004020, 1) 122: open(TT_CH, i, "tt:") 123: display(TT_CH, $scr_clr(SCREEN),"Create bad ship list.",10,13) 124: do 125: begin 126: display(TT_CH, $scr_pos(2,0),"For a specific customer? ") 127: reads(TT_CH, ans) 128: end 129: until ((ans.eq."y").or.(ans.eq."n")) 130: if ((ans.eq."Y").or.(ans.eq."y")) 131: begin 132: display(TT_CH, $scr_pos(3,0),"Enter Customer ID: ") 133: reads(TT_CH, cust_id) 134: cmp_id(1,4) = cust_id 135: do 136: begin 137: display(TT_CH, $scr_pos(4,0),"Want a total history?") 138: reads(TT_CH, history) 139: end 140: until ((history.eq."y").or.(history.eq."n")) 141: end 142: if ((history.eq."Y").or.(history.eq."y")) then 143: begin 144: predate = 19760101 145: postdate = 30000000 146: end 147: else 148: begin 149: do 150: begin 151: first, display(TT_CH, $scr_pos(5,0), "Start: (MM/DD/YYYY)") 152: reads(TT_CH, entdate) 153: end 154: until (%rsize.eq.10) 155: dday=entday 156: dmon=entmonth 157: dyr=dyr 158: predate=date 159: do 160: begin 161: display(TT_CH, $scr_pos(6,0), "End: (MM/DD/YYYY)") 162: reads(TT_CH, entdate) 163: end 164: until (%rsize.eq.10) 165: dday=entday 166: dmon=entmonth 167: dyr=entyear 168: postdate=date 169: end 170: 171: do 172: begin 173: display(TT_CH, $scr_pos(7,0), 174: & "Print the report to the (S)creen or (F)ile? ") 175: reads(TT_CH, out_flg) 176: end 177: until ((out_flg.eq."s").or.(out_flg.eq."f")) 178: if ((out_flg.eq."F").or.(out_flg.eq."f")) 179: begin 180: do 181: begin 182: display(TT_CH, $scr_pos(8,0), 183: & "Should output be sent to the printer? (Y/N)") 184: reads(TT_CH, printer_flg) 185: end 186: until ((printer_flg.eq."y").or.(printer_flg.eq."n")) 187: end 188: if (printer_flg.eq."n") 189: begin 190: display(TT_CH, $scr_pos(9,0), 191: & "Output will be placed in file: ", BADFILE,10,13) 192: end 193: display(TT_CH, "Press Enter to continue or ^D to exit",10,13) 194: reads(TT_CH, incode) [eof=exit] 195: if (incode.eq.' ') 196: incode = "BAD" 197: open(CLNT_CH, i:i, "sclnt") 198: open(FACT_CH, i:i, "sfact") 199: open(FOLD_CH, i:i, "sfhdr") 200: open(OUT_CH, o, BADFILE) 201: if ((out_flg.eq."S").or.(out_flg.eq."s")) then 202: begin 203: date=predate 204: display(TT_CH, "BAD Ship list for ",dmon,"/",dday," ",dyr) 205: date=postdate 206: display(TT_CH, " - ",dmon,"/",dday,"/",dyr) 207: forms(TT_CH, 2) 208: end 209: else 210: begin 211: date=predate 212: display(OUT_CH,"BAD Ship list for ",dmon,"/",dday,"/",dyr) 213: date=postdate 214: display(OUT_CH, " - ",dmon,"/",dday,"/",dyr) 215: forms(OUT_CH, 2) 216: end 217: isam_pre=predate 218: read(FACT_CH, cmfact, isam_pre, KRF=2) [err=next] 219: next, while (cadate.ge.predate) .and. (cadate.le.postdate) do 220: begin 221: if ((caactc.eq.incode(1,%trim(incode))).and.(ans.eq."n")) 222: begin 223: chcomp = cacomp 224: chclnt = caclnt 225: chfldr = cafldr 226: read(FOLD_CH, cmfhdr, chkey) [err=skip] 227: if (chftyp.ne."WISH" .and. chclos.eq.0) 228: call dumpit 229: end 230: if ((caactc.eq.incode(1,%trim(incode))).and. 231: & (ans.eq."y").and.(cmp_id.eq.caclnt)) 232: begin 233: chcomp = cacomp 234: chclnt = caclnt 235: chfldr = cafldr 236: read(FOLD_CH, cmfhdr, chkey) [err=skip] 237: if (chftyp.ne."WISH" .and. chclos.eq.0) ;Is it open? 238: call dumpit 239: end 240: skip, 241: reads(FACT_CH, cmfact) [eof=done] 242: end 243: done, if (.not.find_flg) 244: begin 245: if (out_flg.eq."S") then 246: writes(TT_CH, "No bad records were located in query.") 247: else 248: writes(OUT_CH, "No bad records were located in query.") 249: end 250: close CLNT_CH 251: close FACT_CH 252: close TT_CH 253: close OUT_CH 254: if ((printer_flg.eq."Y").or.(printer_flg.eq."y")) 255: begin 256: lpque(BADFILE, LPNUM:"conan") 257: xcall delet(OUT_CH, BADFILE) 258: end 259: exit, stop
From the listing, we can see that cmp_id in line 134 is loaded with cust_id. Since cmp_id is used for the search, we’ll want to see if it is loaded correctly in line 134. The second problem in the program involves the starting date. From the listing, we can see that predate is loaded at line 158. The third problem involves the “No bad records…” message, which is located around line 243.
DBG> trace %DBR-I-ATLINE, at line 120 in routine MAIN$BADSHIP (badship.dbl)
We’ll use the HELP command to see what our BREAK options are.
DBG> help break Set program breakpoints: BREAK rtn - Set a break at the entry to routine <rtn> BREAK ln - Set a break at line <ln> in the current routine BREAK rtn ln - Set a break at line <ln> in routine <rtn> BREAK lbl [/LABEL] - Set a break at <lbl> in the current routine BREAK . - Set a break at the current line and routine Multiple breaks may be specified, separated by commas, with the "current routine" the last <rtn> encountered. DBG> break 132 DBG> show breaks MAIN$BADSHIP: 132 DBG> go Generate bad shipment list. Generate for a specific customer? y Break at 132 in BADSHIP (badship.dbl) 132> display(TT_CH, $scr_pos(3,0), "Enter Customer ID: ") DBG> step Enter Customer ID: Step to 133 in BADSHIP (badship.dbl) 133> reads(TT_CH, cust_id) DBG> step over 3040 Step to 134 in BADSHIP (badship.dbl) 134> cmp_id(1,4) = cust_id DBG> examine cust_id 3040 DBG> examine cmp_id 000000 DBG> step Step to 3 in BADSHIP (badship.dbl) 137> display(TT_CH, $scr_pos(4,0),"Want a total history?") DBG> examine cmp_id 304000
Here we learn that cmp_id isn’t loaded correctly: cmp_id(1,4)=cust_id should be changed to cmp_id(3,6)=cust_id.
Now we’ll jump to the next possible problem area.
DBG> go 150 Want a total history? n Break at 151 in BADSHIP (badship.dbl) 151> first, display(TT_CH, $scr_pos(5,0), "Start: (MM/DD/YYYY) ")
We’ll do a TRACE command to see where the last command was executed.
DBG> trace %DBR-I-ATLINE, at line 147 in routine MAIN$BADSHIP DBG> step Start: (MM/DD/YYYY) Step to 152 in BADSHIP (badship.dbl) 152> reads(TT_CH, entdate) DBG> step 5 05/22/1986 step to 154 in BADSHIP (badship.dbl) 154> until (%rsize.eq.10) DBG> view 150: begin 151: first, display(TT_CH, $scr_pos(5,0), "Start: (MM/DD/YYYY) ") 152: reads(TT_CH, entdate) 153: end 154> until (%rsize.eq.10) 155: dday=entday 156: dmon=entmonth 157: dyr=dyr 158: predate=date DBG> step Step to 155 in BADSHIP (badship.dbl) 155> dday=entday DBG> step Step to 156 in BADSHIP (badship.dbl) 156> dmon=entmonth DBG> examine dday 22 DBG> step Step to 157 in BADSHIP (badship.dbl) 157> dyr=dyr DBG> examine dmon 05 DBG> step Step to 158 in BADSHIP (badship.dbl) 158> predate=date DBG> examine dyr
Dyr should have contained 1986, not a blank. Instead of dyr=dyr, line 157 should be dyr=entyear.
DBG> step Step to 161 in BADSHIP (badship.dbl) 161> display(TT_CH, $scr_pos(6,0), "End: (MM/DD/YYYY) ") DBG> examine predate 522
This predate value of 522 verifies the above problem. Predate should have contained 19860522.
DBG> go 244 End: (MM/DD/YYYY) 01/01/1992 Print the report to the (S)creen or (F)ile? s Press Enter to continue or ^D to exit BAD Ship list for 5/22/ - 01/01/1992 DBL error trapped at 218 in BADSHIP (badship.dbl), jumping to line 219 218> read(FACT_CH, cmfact, isam_pre, KRF=2) [err=next]
The error we expected was trapped.
DBG> go 244 DBL error trapped at 241 in BADSHIP (badship.dbl), jumping to line 243
Again, the expected error was trapped.
241> reads(FACT_CH, cmfact) [eof=done] DBG> go 244 break at 245 in BADSHIP (badship.dbl) *245: if (out_flg.eq."S") then DBG> view 241: reads(FACT_CH, cmfact) [eof=done] 242: end 243: done, if (.not.find_flg) 244: begin 245: if (out_flg.eq."S") then 246: writes(TT_CH, "No bad records were located in query.") 247: else 248: writes(OUT_CH, "No bad records were located in query.") 249: end DBG> examine out_flg
The IF statement checks for uppercase “S” above, but because out_flg is lowercase “s,” it never allows output to be sent to the console. To check this theory, we’ll put uppercase “S” into out_flg.
DBG> deposit out_flg = 'S' DBG> examine out_flg S DBG> step Step to 246 in BADSHIP (badship.dbl) 246> writes(TT_CH "No bad records were located in query.")
This fixed the problem, which means that the IF statement in line 245 should be changed to check for a lowercase “s.”
DBG> step No bad records were located in query. Step to 250 in BADSHIP (badship.dbl) 250> close CLNT_CH DBG> st
Notice that you can abbreviate the STEP command.
Step to 251 in BADSHIP (badship.dbl) 251> close FACT_CH DBG> s Step to 252 in BADSHIP (badship.dbl) 252> close TT_CH DBG> go %DBR-S-STPMSG, STOP %DBR-I-ATLINE, at line 259 in routine BADSHIP (badship.dbl) $