home *** CD-ROM | disk | FTP | other *** search
/ ftp.robelle3000.ai 2014 / 2014.06.ftp.robelle3000.ai.tar / ftp.robelle3000.ai / papers / nmdebug.pro < prev    next >
Text File  |  1994-04-28  |  47KB  |  1,327 lines

  1. .comment    File:     NMDEBUG
  2. .comment
  3. .comment    Purpose:  The MPE/iX System Debugger Paper
  4. .comment
  5. .comment  To print this document, do the following:
  6. .comment
  7. .comment    :run printdoc.pub.robelle;info="NMDEBUG"
  8. .comment
  9. .com {ifout starts here}
  10. .comment  Choose the output device parameters for this document
  11. .if outfinal
  12. .  if outrecord
  13. .    out(las 30 c1 r+ s7).com Robelle bound version, attached
  14. .  else
  15. .    out(las 30 c1 r- s7).com Robelle bound version
  16. .  endif
  17. .elseif outhelpcomp
  18. .  out(lpt q+ w80).com helpcomp;parm=1
  19. .elseif outa4
  20. .  if outlpt
  21. .    if outrecord
  22. .      out(lpt s7 r+).com A4 paper, $Stdlist/LP/disc, attached
  23. .    else
  24. .      out(lpt s7 r-).com A4 paper, $Stdlist/LP/disc
  25. .    endif
  26. .  elseif outlaser
  27. .    if outrecord
  28. .      if outdouble
  29. .        out(las 30 s8 r+ d+).com A4 paper, LaserJet, attached, duplex
  30. .      else
  31. .        out(las 30 s8 r+).com A4 paper, LaserJet, attached
  32. .      endif
  33. .    else
  34. .      if outdouble
  35. .        out(las 30 s8 r- d+).com A4 paper, LaserJet, duplex
  36. .      else
  37. .        out(las 30 s8 r-).com A4 paper, LaserJet
  38. .      endif
  39. .    endif
  40. .  else.com No other outxxx jcws specified
  41. .    out(lpt s7 r-).com generic: A4 paper, $Stdlist/LP/disc
  42. .  endif
  43. .elseif outtext
  44. .  if outrecord
  45. .    out(lpt s0 u- r+)
  46. .  else
  47. .    out(lpt s0 u-)
  48. .  endif
  49. .else
  50. .  if outlpt
  51. .    if outrecord
  52. .      out(lpt s3 r+).com Letter, $Stdlist/LP/disc, attached
  53. .    else
  54. .      out(lpt s3 r-).com Letter, $Stdlist/LP/disc
  55. .    endif
  56. .  elseif outlaser
  57. .    if outrecord
  58. .      if outdouble
  59. .        out(las 30 s7 r+ d+).com Letter, LaserJet, attached, duplex
  60. .      else
  61. .        out(las 30 s7 r+).com Letter, LaserJet, attached
  62. .      endif
  63. .    else
  64. .      if outdouble
  65. .        out(las 30 s7 r- d+).com Letter, LaserJet, duplex
  66. .      else
  67. .        out(las 30 s7 r-).com Letter, LaserJet
  68. .      endif
  69. .    endif
  70. .  else.com No outxxx jcws specified
  71. .    out(lpt s3 r-).com Letter, generic: $Stdlist/LP/disc
  72. .  endif
  73. .endif
  74. .comment
  75. .comment  Choose the fonts for this document
  76. .if outfinal
  77. .  include final.qlibdata.green
  78. .else
  79. .  include f92286f.qlibdata.robelle
  80. .endif
  81. .comment
  82. .comment  Choose the margins for this document
  83. .comment
  84. .if outhelpcomp
  85. .  mar(r78)
  86. .elseif outa4
  87. .  mar(r62)
  88. .else
  89. .  mar(r65)
  90. .endif
  91. .comment
  92. .comment  Choose the forms for this document
  93. .comment
  94. .comment  Form 1 is for the body of the manual
  95. .comment  Form 2 is for unnumbered pages (end of section)
  96. .comment  Form 3 is for the table of contents (roman numerals)
  97. .comment
  98. .if outtext
  99. .   form(k1 [L8000] )
  100. .   form(k2 [L8000] )
  101. .   form(k3 [L8000] )
  102. .elseif outa4
  103. .   form(k1 [ T #23 S:40 // l64 / #33 "-" pn:1 "-" /]
  104. +           [ S #23 T:40 // l64 / #33 "-" pn:1 "-" /])
  105. .   form(k2 [ // l64 / #33 pr:3 /]).com Roman numerals
  106. .   form(k3 [ // l63 // ])
  107. .else
  108. .   form(k1 [ T #26 S:40 // l55 / #33 "-" pn:1 "-" /]
  109. +           [ S #26 T:40 // l55 / #33 "-" pn:1 "-" /])
  110. .   form(k2 [ // l55 / #33 pr:3 /]).com Roman numerals
  111. .   form(k3 [ // l54 // ])
  112. .endif
  113. .comment
  114. .comment  Option settings:
  115. .comment
  116. .comment   For text output we want a ragged right edge.
  117. .comment
  118. .if outtext
  119. .   opt(j4 p+ b+ r-)
  120. .else
  121. .   opt(j4 p+ b+).com     Okay to insert four blanks between words
  122. .comment                  when justifying, two spaces after period,
  123. .comment                  suppress blank lines at top of page
  124. .endif
  125. .comment
  126. .comment  Other formatting parameters:
  127. .par(f` p5 s1 u3)      .com  Automatic .skip 1.page 5.undent 3
  128. .inp(u~ b@ h\ e& t# f|).com   Underline,Blank,Hyphen,Escape,Tab,Font
  129. .if not outtext
  130. .page.count 1          .com  Start page numbering over again.
  131. .form 3
  132.  
  133. .jump 7
  134. .opt(l- r- f-)
  135. `|3The MPE/iX System Debugger|
  136.  
  137. |1By David J.@Greer|
  138.  
  139. `|1Abstract|
  140. .opt
  141.  
  142. MPE/iX comes with a powerful debugger.  For those of us who
  143. have struggled with Debug/V, there are many great features
  144. to look forward to.  But, like all new software, there is a
  145. learning curve in understanding the new MPE/iX debugger.
  146. Attempting to find the dozen or so most useful features in
  147. the three-inch stack of paper called the System Debugger
  148. Reference Manual is impossible, unless you have three spare months.
  149. In this article, I intend
  150. to summarize the features I've found most useful.
  151.  
  152.  
  153. .skip 10
  154. .opt(l- r- f-)
  155. .font 1
  156. Robelle Consulting Ltd.
  157. Unit 201, 15399-102A Ave.
  158. Surrey, B.C. Canada V3R 7K1
  159. Phone:  (604) 582-1700
  160. Fax:  (604) 582-1799
  161.  
  162. Email:  david_greer&@robelle.com
  163. .font 0
  164.  
  165.  
  166. Copyright Robelle Consulting Ltd. 1991,1994
  167.  
  168.  
  169. Permission is granted to reprint this document (but ~not~
  170. for profit), provided that copyright notice is given.
  171.  
  172.  
  173. .opt.com Stop centering
  174. .endif.com { not outtext }
  175. .com                         The next FORM is for Contents/Preface:
  176. .form 1
  177. .contents(i+3)
  178. .page.count 1
  179. .jump 1
  180. .opt(l- r- f-)
  181. `|3The MPE/iX System Debugger|
  182.  
  183. |1By David J.@Greer, Robelle Consulting Ltd.|
  184. .if outtext
  185.  
  186.  
  187. Copyright Robelle Consulting Ltd. 1991,1994
  188.  
  189.  
  190. Permission is granted to reprint this document (but ~not~
  191. for profit), provided that copyright notice is given.
  192. .endif
  193. .opt
  194.  
  195.  
  196.  
  197. .ent `Introduction
  198. MPE/iX comes with a powerful debugger.  For those of us who
  199. have struggled with Debug/V, there are many great features
  200. to look forward to.  But, like all new software, there is a
  201. learning curve in understanding the new MPE/iX debugger.
  202. Attempting to find the dozen or so most useful features in
  203. the three-inch stack of paper called the System Debugger
  204. Reference Manual is impossible, unless you have three spare months.
  205. In this article, I intend
  206. to summarize the features I've found most useful.
  207.  
  208. I am indebted to Stan Sieler of Allegro Consultants who taught
  209. me much of what is presented in this article.  To obtain the
  210. maximum benefit from this article, you should try all of the
  211. examples that are presented.  Having both a CM- and an NM-program
  212. available that calls the FWRITE intrinsic will make following the
  213. examples that much easier.
  214. If you are going to be a big user of Debug/iX, then you really
  215. have to have the reference manual.  Order part 羊-90013,
  216. System Debug Reference Manual.
  217.  
  218. .tit |1MPE/iX Debugger|
  219. .sub |1Native-Mode|
  220. `|1Native-Mode or Compatibility-Mode|
  221. .ent Native-Mode or Compatibility-Mode
  222.  
  223. HP was very kind to write not only a nice debugger for
  224. native-mode programs, but include features for
  225. debugging compatibility-mode programs too. When I first
  226. attempted to debug a CM-program, I got so confused that I
  227. returned to my classic HP 3000 where at least I knew all the
  228. command names.  The next section will show Debug/iX commands
  229. for our old favorite Debug/V commands.
  230.  
  231. .sub |1Debug/V Versus Debug/iX|
  232. `|1Debug/V Versus Debug/iX|
  233. .ent Debug/V Versus Debug/iX
  234.  
  235. Just like Debug/V, you can invoke Debug/iX by including the
  236. keyword "Debug" on the :Run Command for your program.  Debug/iX
  237. responds with its "CM" prompt:
  238.  
  239. .font 5
  240.      :run testprog;debug
  241.  
  242.      CM DEBUG Intrinsic: PROG %6.3542
  243.      cmdebug >
  244. .font 0
  245.  
  246. If you have a Pmap (or Robelle's Qmap), you can set a breakpoint
  247. just as you would in Debug/V -- using |2segment.offset|:
  248.  
  249.      #6|5cmdebug >B 0.45|
  250.  
  251. Anyone who has struggled with Pmaps knows how convenient it would
  252. be if the system debugger took advantage of the FPMAP information
  253. stored in program files.  With this information it should be
  254. possible to set a breakpoint by |1procedure name|.  Debug/iX
  255. lets you either set a symbolic breakpoint at the first logical
  256. instruction in your procedure or at the more useful entry-point:
  257.  
  258. .page 4
  259. .font 5
  260.      cmdebug >B open'input'file       |0{first instruction}|
  261.      cmdebug >B ?open'input'file      |0{? implies entry point}|
  262.      cmdebug >B open'input'file+255   |0{octal offset from first}|
  263.      cmdebug >c                       |0{Continue = Resume}|
  264. .font 0
  265.  
  266. .sub |1Breakpoints|
  267. `|1Breakpoints|
  268. .ent Breakpoints
  269.  
  270. In the last ten years, I have probably lost over a month of time
  271. from one horrible default in Debug/V.  In Debug/V, the Break
  272. Command would only break the first time it encountered the
  273. breakpoint, unless you added ":&@" to the Break Command.
  274. In Debug/iX the default is to always break.  Occasionally, you
  275. only want the breakpoint to be invoked once.  Use ",-1" after
  276. the break location to have the breakpoint removed after one
  277. occurrence:
  278.  
  279.      |5#6nmdebug >b ?open'input'file,-1 |0{break once}|
  280.  
  281. .sub |1Clearing Breakpoints|
  282. `|1Clearing Breakpoints|
  283. .ent Clearing Breakpoints
  284.  
  285. In Debug/V, the Clear Command disables breakpoints that have been set
  286. with the Break Command.  In Debug/iX, use the BD (Breakpoint Delete)
  287. Command to remove breakpoints:
  288.  
  289. .font 5
  290.      nmdebug >bd       |0{You will be asked for which one}|
  291.      nmdebug >bd &@     |0{Delete all breakpoints}|
  292. .font 0
  293.  
  294. .sub |1Return Breakpoint|
  295. `|1Setting a "Return" Breakpoint|
  296. .ent Setting a "Return" Breakpoint
  297.  
  298. One of the most useful breakpoints is the one immediately after
  299. a procedure call.  Suppose that your program calls the procedure
  300. |5extract_ready|.  You want to know the result of |5extract_ready|, so
  301. you would like a breakpoint in the calling code immediately after
  302. the call to |5extract_ready|.  You do the following:
  303.  
  304. .font 5
  305.      cmdebug >b ?extract_ready
  306.      cmdebug >c
  307.      .
  308.      .
  309.      .                        |0{break at |5extract_ready|}|
  310.      cmdebug >lev 1;b p,-1    |0{-1 means only break once}|
  311.      cmdebug >c               |0{continue execution}|
  312. .font 0
  313.  
  314. The "lev 1" goes back to the previous logical level in the
  315. calling sequence (use "tr,d" to see a complete traceback). The "b p"
  316. sets a breakpoint at the compatibility-mode program counter.
  317. The "lev 1" places the program counter at the instruction
  318. |2after| the one that called the current procedure.  The ",-1" tells
  319. Debug/iX to execute the breakpoint once and then throw it away.
  320. Note that it's safe to use this breakpoint anywhere in the
  321. |5extract_ready| procedure -- not just at the beginning.
  322.  
  323. What if we are in native-mode code (e.g., FWRITE)?  Our return
  324. breakpoint won't work, since we called FWRITE from
  325. compatibility-\mode.  To set a return breakpoint in this case,
  326. first switch into cmdebug:
  327.  
  328. .font 5
  329.      cmdebug >b ?FWRITE
  330.      cmdebug >c
  331.      .
  332.      .
  333.      .                        |0{break at NM FWRITE}|
  334.      nmdebug >cm              |0{switch into CM}|
  335.      cmdebug >lev 1;b p,-1    |0{set return breakpoint}|
  336.      cmdebug >c               |0{continue execution}|
  337. .font 0
  338.  
  339. .sub |1Abort Command|
  340. `|1Abort Command -- Getting Out of Debug|
  341. .ent Abort Command
  342.  
  343. You can terminate your program with the Abort Command.  Use this
  344. any time that Debug/iX is prompting for commands.
  345. The Debug/iX Abort Command is similar to the Debug/V E&@ Command.
  346.  
  347. .sub |1Displaying Values|
  348. `|1Displaying Values|
  349. .ent Displaying Values
  350.  
  351. When I first used Debug/iX, I became totally confused about how
  352. to display the usual DB-, Q-, and S-relative values.  It turns
  353. out to be very simple.
  354. In
  355. Debug/V the Display Command takes the register as a
  356. parameter.
  357. In Debug/iX there are separate command
  358. names for displaying values relative to each register.
  359. Here are the Debug/V and Debug/iX Display Commands:
  360.  
  361. .font 5
  362.      ~Debug/V~     ~Debug/iX~
  363.        D DB        DDB
  364.        D S         DS
  365.        D Q         DQ
  366. .font 0
  367.  
  368. The Debug/iX Display Command has a count as its second parameter (just
  369. like Debug/V), but the display attribute is different.
  370. Here is the comparison:
  371.  
  372. .font 5
  373.      ~Debug/V~      ~Debug/iX~         ~Description~
  374.      ,I           ,&# or D          Decimal
  375.      ,O           ,% or O          Octal |0{default in CM}|
  376.      ,H           ,$ or H          Hexadecimal |0{default in NM}|
  377.      ,A           ,S               Ascii/String
  378. .font 0
  379.  
  380. Instead of S, you can also use A for displaying string values.
  381. The A-option is closer to the A-option of Debug/V, but we find
  382. the S-option more useful.
  383.  
  384. By default, the S-option displays all
  385. characters you request and only displays the virtual address of
  386. the string once.  If you want to see as many characters per line
  387. as possible, with each new line starting with the virtual address
  388. of the characters displayed, use this command:
  389.  
  390.      #6|5cmdebug >dq 104,200,s,e      |0{"e" shows addresses}|
  391.  
  392. .sub |1Symbolic Machine Code|
  393. `|1Symbolic Machine Code|
  394. .ent Symbolic Machine Code
  395.  
  396. Our list above doesn't show you how to display the actual
  397. run-time machine instructions (commonly called decompiling).
  398. That's because Debug/iX has many excellent features to
  399. symbolically display code.  While you can use the DC (Display
  400. Code) Command to show symbolic code, we have found a better method
  401. -- windows.
  402.  
  403. .sub |1Symbolic Traceback|
  404. `|1Symbolic Traceback|
  405. .ent Symbolic Traceback
  406.  
  407. The Debug/V Trace Command was almost useless.  You had
  408. to manually work through the segment numbers and offsets to
  409. figure out the true procedure names.  The Debug/iX
  410. Trace Command produces a proper symbolic traceback of
  411. procedure names.
  412.  
  413. You can also use the traceback to observe switches from
  414. native-mode to compatibility-mode.  For example, if you have
  415. SM capability you can set a breakpoint in any system SL or
  416. system XL routine.  KSAM files come in two flavors:
  417. CM and NM.  If you access a
  418. CM KSAM file from a NM program, MPE/iX
  419. calls the CM FWRITE intrinsic.  You can easily prove this to
  420. yourself by setting a breakpoint in the CM FWRITE intrinsic:
  421.  
  422. .font 5
  423.      :run testprog;debug        |0{NM program to read CM KSAM file}|
  424.      nmdebug >cmdebug           |0{switch to CM}|
  425.      cmdebug >b ?FWRITE         |0{question-mark for entry point}|
  426.      cmdebug >c                 |0{continue execution}|
  427.      .
  428.      .
  429.      .                          |0{note the ",d" on the TR Command}|
  430.      cmdebug >tr,d              |0{traceback showing switches}|
  431. .font 0
  432.  
  433. .page.jump 1
  434. .sub |1WON Command|
  435.  
  436. .opt(f-l-r-)
  437. `|3Compatibility-Mode Windows|
  438. .opt
  439. .ent `Compatibility-Mode Windows
  440.  
  441.  
  442. The WON Command is the real power of Debug/iX.
  443. WON is short for Windows On.  When you turn windows on, the top
  444. portion of the screen is reserved for a symbolic display of the
  445. currently executing code, another
  446. portion displays register and/or
  447. stack values, and the bottom of the screen is used to enter
  448. commands.  This is a very powerful feature.
  449.  
  450. .sub |1CM Window Example|
  451. `|1CM Window Example|
  452. .ent CM Window Example
  453.  
  454. The following is an example compatibility-mode window.  We first
  455. set a breakpoint, continue to that breakpoint, and finally we
  456. turn windows on.
  457.  
  458. .page 6
  459. .font 5
  460.      cmdebug >b ?input'command     |0{break at the entry point}|
  461.      cmdebug >c                    |0{continue execution}|
  462.      .
  463.      .
  464.      .
  465.      cmdebug >won                  |0{turn windows on}|
  466. .font 0
  467.  
  468. .com Outlined Shape at column 7. 51 columns wide and 23 rows high.
  469. .break.page 25.com Does .INP use * ??
  470. The top three lines of the display show the register information:
  471. .skip 1
  472. .if outtext or outlpt then
  473. .   mar(r100).opt(f-)
  474. R % Regs   DB=001200  DBDST=001632  X=000002 STATUS=(mITroC CCG 007)   PIN=051
  475. SDST=001627  DL=177450     Q=023620     S=023620      CMPC=PROG 000006.006711
  476.  CIR=035004  MAPFLAG=0     MAPDST=000000
  477. FcmP %    PROG 6.6711         (?) SETUP             CSTX 7            Level 0
  478. 006707:          INPUT'COMMAND+%437       031031  2.  PCAL ?ERRX
  479. 006710:          INPUT'COMMAND+%440       032000  4.  SXIT  0
  480. 006711:     [1]> ?INPUT'COMMAND           035004  :.  ADDS  4
  481. 006712:          INPUT'COMMAND+%442       171700  ..  LRA   S-0
  482. 006713:          INPUT'COMMAND+%443       051401  S.  STOR  Q+1
  483. 006714:          INPUT'COMMAND+%444       035023  :.  ADDS  %23
  484. 006715:          INPUT'COMMAND+%445       041401  C.  LOAD  Q+1
  485. Q %  (DB  mode)                    QDST=001627                       Level 0
  486. 023610:  000000   047420   061006   000006   177600   D000002@   D00364
  487. 023620:Q>D000014@<S
  488. 023630:
  489. S %  (DB  mode)                    SDST=001627                       Level 0
  490. 023610:  000000   047420   061006   000006   177600   D000002@   D00364
  491. 023620:Q>D000014@<S
  492. Commands
  493.  
  494. %47 (%103) cmdebug >
  495. .else
  496. .   box(c+8 w50 r-0+ h22+)
  497. .   font 6.mar(l+8 r108).opt(f-)
  498. R % Regs   DB=001200  DBDST=001632  X=000002 STATUS=(mITroC CCG 007)   PIN=051    <-&|
  499. SDST=001627  DL=177450     Q=023620     S=023620      CMPC=PROG 000006.006711       &| R Window
  500.  CIR=035004  MAPFLAG=0     MAPDST=000000                                          <-&|
  501. FcmP %    PROG 6.6711         (?) SETUP             CSTX 7            Level 0     <-&|
  502. 006707:          INPUT'COMMAND+%437       031031  2.  PCAL ?ERRX                    &|
  503. 006710:          INPUT'COMMAND+%440       032000  4.  SXIT  0                       &|   CmP
  504. 006711:     [1]> ?INPUT'COMMAND           035004  :.  ADDS  4                       &|  Window
  505. 006712:          INPUT'COMMAND+%442       171700  ..  LRA   S-0                     &|
  506. 006713:          INPUT'COMMAND+%443       051401  S.  STOR  Q+1                     &|
  507. 006714:          INPUT'COMMAND+%444       035023  :.  ADDS  %23                     &|
  508. 006715:          INPUT'COMMAND+%445       041401  C.  LOAD  Q+1                   <-&|
  509. Q %  (DB  mode)                    QDST=001627                       Level 0      <-&|
  510. 023610:  000000   047420   061006   000006   177600   D000002@   D00364             &|    Q
  511. 023620:Q>D000014@<S                                                                 &|  Window
  512. 023630:                                                                           <-&|
  513. S %  (DB  mode)                    SDST=001627                       Level 0      <-&|
  514. 023610:  000000   047420   061006   000006   177600   D000002@   D00364             &|    S
  515. 023620:Q>D000014@<S                                                               <-&|  Window
  516. Commands                                                                          <-&|
  517.                                                                                     &|  Command
  518. %47 (%103) cmdebug >                                                              <-&|  Window
  519. .endif
  520. .font 0.opt.mar
  521.  
  522.  
  523. For most of us, only the DL=, Q=, S=, and X= values are interesting.
  524. If the DBDST and the SDST (the DB- and S- data segments) are
  525. different, you are in split-stack mode.
  526. Line four shows that
  527. we are currently at location 6.6711 in the
  528. program. The PROG would change if the breakpoint was inside an SL.
  529. Next we see seven instructions.  The "[1]" means breakpoint
  530. number 1.  The ">" symbol next to "?INPUT'COMMAND" shows the
  531. next instruction to be executed.  The bottom of the display shows
  532. the values around the Q- and S- registers.
  533. In our example, the Q and S registers are the same so the Q- and
  534. S-displays are identical.
  535. Finally, you are prompted for more
  536. Debug/iX commands.
  537.  
  538. .sub |1Single-Stepping|
  539. `|1Single-Stepping|
  540. .ent Single-Stepping
  541.  
  542. One other command adds a lot of power to windows:  S --
  543. single-stepping.  The S Command executes the next instruction, then
  544. returns control to Debug/iX.  After the execution, register and
  545. stack values are updated and any changed values are highlighted.
  546. Because the compatibility-mode window shows the top few words of
  547. the stack, you can often get an instant picture of what is going
  548. on.
  549. Here is the first window after executing one single-step:
  550.  
  551. .font 5.page 25
  552.      cmdebug >s              |0{single-step}|
  553.  
  554. .com Outlined Shape at column 7. 51 columns wide and 23 rows high.
  555. .break.page 23.com Does .INP use * ??
  556. .if outtext or outlpt then
  557. .   mar(r100).opt(f-)
  558. .else
  559. .   box(c+8 w50 r-0+ h22+)
  560. .   font 6.mar(l+8 r108).opt(f-)
  561. .endif
  562. R % Regs   DB=001200  DBDST=001632  X=000002 STATUS=(mITroC CCG 007)   PIN=1
  563. SDST=001632  DL=177450     Q=023620     S=023624      CMPC=PROG 000006
  564.  CIR=171700  MAPFLAG=0     MAPDST=000000
  565. cmP %    PROG 6.6712         (?) SETUP             CSTX 7            Level 0
  566. 006707:          INPUT'COMMAND+%437       031031  2.  PCAL ?ERRX
  567. 006710:          INPUT'COMMAND+%440       032000  4.  SXIT  0
  568. 006711:     [1]  ?INPUT'COMMAND           035004  :.  ADDS  4
  569. 006712:        > INPUT'COMMAND+%442       171700  ..  LRA   S-0
  570. 006713:          INPUT'COMMAND+%443       051401  S.  STOR  Q+1
  571. 006714:          INPUT'COMMAND+%444       035023  :.  ADDS  %23
  572. 006715:          INPUT'COMMAND+%445       041401  C.  LOAD  Q+1
  573. Q %  (DB  mode)                    QDST=001632                       Level 0
  574. 023610:  000000   047420   061006   000006   177600   000002   00364
  575. 023620:Q>000014   000002   006712   062007   &d
  576. 023630:
  577. S %  (DB  mode)                    SDST=001632                       Level 0
  578. 023610:  000000   047420   061006   000006   177600   000002   00364
  579. 023620:Q>000014   000002   006712   062007<S
  580. Commands
  581.  
  582. %47 (%103) cmdebug >
  583. .font 0.mar.opt
  584.  
  585.  
  586. The ">" symbol has moved forward by one instruction.  The register
  587. values have been updated and the top of stack has changed because
  588. we added four to the S-register.
  589.  
  590. .sub |1Set CRON|
  591. `|1Set CRON|
  592. .ent Set CRON
  593.  
  594. This sounds like the title of a futuristic movie, but when
  595. combined with single-stepping it can be very powerful.  Once you
  596. start using the S (Single-Step) Command, you'll find yourself
  597. typing it a lot, especially when debugging NM programs where you
  598. have a lot more instructions per source code statement.
  599. Fortunately, the Debug/iX designers already thought of this. When
  600. you Set CRON, hitting Return tells Debug/iX "execute the last
  601. command that I typed".  This is most useful when your last
  602. command was S, but it applies to |1any| command:
  603.  
  604. .font 5
  605.      cmdebug >set cron        |0{Return = last-command}|
  606.      cmdebug >s               |0{single-step}|
  607.      cmdebug >                |0{another single-step!|}
  608.      cmdebug >                |0{and one more}|
  609.      cmdebug >                |0{and so on}|
  610. .font 0
  611.  
  612. .sub |1Multiple Steps|
  613. `|1Multiple Steps|
  614. .ent Multiple Steps
  615.  
  616. While single-stepping is useful, it can be very slow.  You can
  617. step through a program faster using multiple instructions for
  618. every step.  The following example shows how to step through
  619. every seven executed instructions.
  620. Note:  you must have a space after the Step Command and
  621. before the number of instructions to execute (e.g., "S7" is
  622. invalid):
  623.  
  624. .font 5
  625.      cmdebug >set cron        |0{Return = last-command}|
  626.      cmdebug >s 7             |0{execute seven instructions|}
  627.      cmdebug >                |0{another seven!|}
  628.      cmdebug >                |0{and seven more}|
  629.      cmdebug >                |0{and so on}|
  630. .font 0
  631.  
  632.  
  633. .page.jump 1
  634. .sub |1Native-Mode Debugging|
  635.  
  636. .opt(l- r- f-)
  637. `|3Native-Mode Debugging|
  638. .opt
  639. .ent `Native-Mode Debugging
  640.  
  641.  
  642. Much of what has been discussed applies to native-mode.  There
  643. are a few minor differences:
  644. .mar(l+3)
  645. `1.#4You don't need to specify Fpmap (or any other magic
  646. parameter) on the :Link Command.  Procedure name and location
  647. information is automatically included in all NM program files.
  648. `2.#4Since the first
  649. instruction of a procedure and its entry point are the same, you
  650. never need to use a question mark.
  651. If you happen to type a question mark, Debug/iX may not print an
  652. error.  In this case, you will have set a breakpoint in a stub
  653. procedure.  Since you almost never want to do this, it's important
  654. to remember not to type the question mark before the procedure name.
  655. `3.#4In most programming languages, any separators
  656. (e.g., apostrophes) used in
  657. procedure names will now become underbars.
  658. .mar
  659.  
  660. Here is our previous breakpoint example in native-mode:
  661.  
  662.      #6|5nmdebug >b open_input_file    |0{break at procedure entry}
  663.  
  664. .sub |1Case Sensitivity|
  665. `|1Case Sensitivity|
  666. .ent Case Sensitivity
  667.  
  668. It is easy to see that portions of MPE/iX were affected by UNIX
  669. and the C programming language.  In UNIX and C, case is
  670. significant (i.e., upper-case and lower-case are not the same).
  671. When setting breakpoints in native-mode code, it
  672. is important to remember this.  Most MPE/iX routine names are in
  673. upper-case.  The most well-known exceptions are all of the IMAGE
  674. and VPLUS intrinsics which are in lower-case.  The following
  675. example results in a Debug/iX error:
  676.  
  677.      #6|5nmdebug >b fwrite          |0{not found; lower-case}|
  678.  
  679. `|1Switching Modes|
  680. .ent Switching Modes
  681. .sub |1Switching Modes|
  682.  
  683. Sometimes you want to switch between CM-debug and NM-debug. For
  684. example, the NM-FWRITE intrinsic calls the CM-FWRITE intrinsic
  685. for certain types of files (e.g., circular).  These commands
  686. would set breakpoints in both the CM- and NM-FWRITE intrinsics:
  687.  
  688. .font 5
  689.      nmdebug >b FWRITE         |0{NM-FWRITE breakpoint}|
  690.      nmdebug >cm               |0{switch into cmdebug}|
  691.      cmdebug >b ?FWRITE        |0{CM-FWRITE breakpoint}|
  692.      cmdebug >nm               |0{switch back into nmdebug}|
  693.      nmdebug >c                |0{continue execution}|
  694. .font 0
  695. .page.jump 1
  696. .sub |1Native-Mode Windows|
  697.  
  698. .opt(f-l-r-)
  699. `|3Native-Mode Windows|
  700. .opt
  701. .ent `Native-Mode Windows
  702.  
  703.  
  704. The WON (Windows On) Command is just as powerful in native-mode
  705. as in compatibility-mode.  The display is different -- instead of
  706. the old familiar DB, S, and Q registers, there is a strange group of
  707. 32 "general-purpose" registers.  The code looks a lot different
  708. too -- those famous RISC instructions instead of our old faithful
  709. Classic 3000 ones.
  710.  
  711. .sub |1NM Window Example|
  712. `|1NM Window Example|
  713. .ent NM Window Example
  714.  
  715. We will show an example native-mode window, by setting a breakpoint
  716. for the FWRITE intrinsic:
  717.  
  718. .font 5.page 15
  719.      nmdebug >b FWRITE            |0{requires SM capability}|
  720.      nmdebug >c                   |0{continue execution}}|
  721.      .
  722.      .
  723.      .
  724.      nmdebug >won                 |0{turn windows on}|
  725.  
  726. .com Outlined Shape at column 7. 51 columns wide and 18 rows high.
  727. .break.page 25.com Does .INP use * ??
  728. .if outtext or outlpt then
  729. .   mar(r100).opt(f-)
  730. GR$   ipsw=0006fe0f=jthlnxbCVmrQPDI  priv=0  pc=0000000a.004a5fc0  pin=0000007a
  731. r0  00000000 40100e20 004aee30 00000001 r4  c0000000 0000ffff 4033292a 00000000
  732. r8  00000001 00000009 00000004 4034a880 r12 00000000 00000000 00000000 00000000
  733. r16 00000000 00000000 00000000 c0000000 r20 c0000000 00000001 85240000 00000314
  734. r24 40332604 000000d0 00000001 c0202008 r28 00000001 ffffffff 4034afd8 004aee30
  735. nmP$  SYS   a.4a5fb8  NL.PUB.SYS/FSPACE+$5a4                        Level   0,0
  736. 004a5fb8:         FSPACE+$5a4            e840c000  BV       0(2)
  737. 004a5fbc:         FSPACE+$5a8            4fc33d31  LDWM     -360(0,30),3
  738. 004a5fc0:    [1]> FWRITE                 6bc23fd9  STW      2,-20(0,30)
  739. 004a5fc4:         FWRITE+$4              6fc30340  STWM     3,416(0,30)
  740. 004a5fc8:         FWRITE+$8              6bc43cc9  STW      4,-412(0,30)
  741. 004a5fcc:         FWRITE+$c              6bc53cd1  STW      5,-408(0,30)
  742. 004a5fd0:         FWRITE+$10             6bc63cd9  STW      6,-404(0,30)
  743. Commands
  744.  
  745. $7 ($1d) nmdebug >
  746. .else
  747. .   box(c+8 w50 r-0+ h17+)
  748. .   font 6.mar(l+8 r108).opt(f-)
  749. GR$   ipsw=0006fe0f=jthlnxbCVmrQPDI  priv=0  pc=0000000a.004a5fc0  pin=0000007a   <-&|
  750. r0  00000000 40100e20 004aee30 00000001 r4  c0000000 0000ffff 4033292a 00000000     &|    R
  751. r8  00000001 00000009 00000004 4034a880 r12 00000000 00000000 00000000 00000000     &|  Window
  752. r16 00000000 00000000 00000000 c0000000 r20 c0000000 00000001 85240000 00000314     &|
  753. r24 40332604 000000d0 00000001 c0202008 r28 00000001 ffffffff 4034afd8 004aee30   <-&|
  754. nmP$  SYS   a.4a5fb8  NL.PUB.SYS/FSPACE+$5a4                        Level   0,0   <-&|
  755. 004a5fb8:         FSPACE+$5a4            e840c000  BV       0(2)                    &|
  756. 004a5fbc:         FSPACE+$5a8            4fc33d31  LDWM     -360(0,30),3            &|   NmP
  757. 004a5fc0:    [1]> FWRITE                 6bc23fd9  STW      2,-20(0,30)             &|  Window
  758. 004a5fc4:         FWRITE+$4              6fc30340  STWM     3,416(0,30)             &|
  759. 004a5fc8:         FWRITE+$8              6bc43cc9  STW      4,-412(0,30)            &|
  760. 004a5fcc:         FWRITE+$c              6bc53cd1  STW      5,-408(0,30)            &|
  761. 004a5fd0:         FWRITE+$10             6bc63cd9  STW      6,-404(0,30)          <-&|
  762. Commands                                                                          <-&|  Command
  763.                                                                                     &|  Window
  764. $7 ($1d) nmdebug >                                                                <-&|
  765. .endif
  766. .font 0.mar.opt
  767.  
  768.  
  769. The first line contains general information about the process
  770. (e.g., the pin number).
  771. The pc= is the program counter (notice it's a full 64-bit address in
  772. |2space.offset| format).
  773. Lines two through four of the display show
  774. all 32 general-purpose registers.
  775. The fifth line shows where the first instruction in the window
  776. is located (in
  777. NL.\Pub.\Sys &@ FSPACE+$5a4).
  778. The native-mode instructions are shown, along with the breakpoint
  779. number "[1]" and the next instruction to be executed is marked with the
  780. ">".
  781.  
  782. There are two commands that
  783. can be a big benefit in examining the code "around" a breakpoint:
  784. PB (Program Back) and PF (Program Forward).
  785.  
  786. .sub |1Paging|
  787. `|1Paging|
  788. .ent Paging
  789.  
  790. Debug/iX windows have to display all their information in the
  791. twenty-four lines on a standard terminal screen.  By default, the
  792. size of the symbolic instruction list is seven
  793. instructions.  Especially when you are single-stepping through
  794. instructions, it is very useful to see the previous seven
  795. instructions or the next seven.  The PB (Program Back) Command displays
  796. the previous seven instructions and the PF (Program Forward) Command
  797. shows the next seven.  While seven instructions is the default,
  798. there are commands to change the size of the program window.
  799. If you have changed the size, Program Back and Program Forward adjust
  800. themselves to the new window size.
  801.  
  802. .font 5
  803.      nmdebug >pf             |0{program forward}|
  804.      nmdebug >pb             |0{program back}|
  805. .font 0
  806.  
  807. .sub |1PL Command|
  808. `|1PL Command|
  809. .ent PL Command
  810.  
  811. If you want to change the number of program instructions on the
  812. screen, use the PL Command (Program List).  The PL Command assumes
  813. that the number of lines you want is in the current base.
  814. Therefore, PL 10 means 16 instructions in NM Debug and 8 instructions
  815. in CM Debug.  To get around the problem, we always specify the
  816. number of instructions in decimal:
  817.  
  818.      #6|5nmdebug >pl       |0{show "ten" instructions}|
  819.  
  820. .page.jump 1
  821. .sub |1Procedure Parameters|
  822. .opt(f-l-r-)
  823.  
  824. `|3Native-Mode Procedure Parameters|
  825. .opt
  826. .ent Native-Mode Procedure Parameters
  827.  
  828.  
  829. .com <djg>  Longer introduction here?
  830. Long-time users of Debug/V know how to anticipate where
  831. procedure parameters will be located.  For example, if
  832. we had a procedure with this declaration:
  833.  
  834. .font 5.page 5
  835.      integer procedure convint(buf,len);  !result = Q-6
  836.         value   len;
  837.         integer len;                      !len    = Q-4
  838.         byte array buf;                   !&@buf   = Q-5
  839. .font 0
  840.  
  841. In CM-debug, we would look at the parameters as follows:
  842.  
  843. .font 5.page 5
  844.      cmdebug >dq -6           |0{result of Convint procedure}|
  845.      cmdebug >dq -4           |0{length of buffer}|
  846.      cmdebug >dq -5           |0{address of buffer}|
  847.      Q-%5     % 000104        |0{must use this value below}|
  848.      cmdebug >ddb 104/2,10,s  |0{print actual buffer contents}|
  849. .font 0
  850.  
  851. Notice that we had to divide the value at Q-5 (i.e., %104)
  852. by two, since the
  853. buffer was passed as a byte address. In native-mode, this irritation
  854. disappears (except for those using SPLash! to emulate Classic
  855. byte addressing).
  856.  
  857. .sub |1Calling Conventions|
  858. `|1Native-Mode Calling Conventions|
  859. .ent NM Calling Conventions
  860.  
  861. With the power to set breakpoints symbolically, by just knowing
  862. the name of a procedure, there is even more incentive to be able
  863. to guess the location of procedure parameters.  NM procedures are
  864. allocated registers for the first four parameters, but they are
  865. allocated left-to-right -- the opposite of CM procedures. The
  866. first parameter is assigned to Register-26, the second to
  867. Register-25, the third to Register-24, the fourth to Register-23,
  868. and any remaining parameters are stored on the NM stack.
  869. The return value is in Register-28 (and Register-29 for 64-bit
  870. values).
  871. For native-mode, you would think of the declaration for Convint as:
  872.  
  873. .font 5.page 5
  874.      integer procedure convint(buf,len); !result = R28
  875.         value   len;
  876.         integer len;                     !len    = R25
  877.         byte array buf;                  !&@buf   = R26
  878. .font 0
  879.  
  880. If you have windows on, the 32 general-purpose registers are
  881. always displayed.  The only problem area is the buffer parameter:
  882.  
  883. .font 5.page 8
  884.      nmdebug >b convint       |0{note lower-case}|
  885.      nmdebug >won             |0{windows on}|
  886.      nmdebug >c               |0{continue execution}|
  887.      .
  888.      .
  889.      .                        |0{debug breaks &@ convint}|
  890.      nmdebug >=r25            |0{display the length}|
  891.      nmdebug >dv r26,10,s     |0{display virtual uses the contents}|
  892.                               |0{of register 26 as an address}|
  893. .font 0
  894.  
  895. .sub |1Variables|
  896. `|1Variables|
  897. .ent Variables
  898.  
  899. Debug/iX contains a programming language.  We won't try and
  900. cover all of the features of this language, but variables are so
  901. powerful that they are worth knowing about.
  902. In our example with the Convint procedure,
  903. suppose that the
  904. buffer you are passing to Convint is a global variable. Setting the
  905. breakpoint at Convint gives you a convenient method to find and
  906. save the address of your buffer so that you can use it at any
  907. breakpoint.
  908.  
  909. .font 5.page 8
  910.      nmdebug >var buf_var=r26  |0{save address of buffer}|
  911.      nmdebug >dv buf_var,10,s  |0{display buffer contents}|
  912.      nmdebug >c                |0{continue execution}|
  913.      .
  914.      .
  915.      .                         |0{sometime much later ...}|
  916.      nmdebug >dv buf_var,10,s  |0{display the buffer contents}|
  917. .font 0
  918.  
  919. The final Display Virtual Command displays the contents of the buffer
  920. using the address that we saved.  When the breakpoint takes place,
  921. we may have no convenient way of finding the
  922. program variable that has the
  923. address of our buffer.  Because we have saved the
  924. address in the Debug/iX variable "buf_var",
  925. we display the buffer contents without knowing where the
  926. address is stored.
  927.  
  928. .sub |1Virtual Addresses|
  929. `|1Virtual Addresses|
  930. .ent Virtual Addresses
  931.  
  932. So far, we have assumed that all addresses are 32-bits.  In MPE/iX,
  933. addresses are actually 64-bits.  Debug/iX shows these addresses
  934. as |2space.offset|.  If you are working with mapped files, you
  935. will find that the full 64-bit address suddenly becomes important.
  936. The following example opens a file with mapped access, saves the
  937. virtual address of the file into a variable, and then displays the
  938. actual contents of the file.
  939.  
  940. .font 5.page 5
  941.      nmdebug >map "file1.suprtest" |0{open an mpe file mapped}|
  942.      nmdebug >var fileaddr = mapva("file1.suprtest")
  943.      nmdebug >=fileaddr            |0{display the virtual address}|
  944. .font 0
  945.  
  946. Debug/iX has a built-in calculator that accepts any
  947. Debug/iX expression.
  948. You invoke the calculator with an equal sign "=".  Debug/iX
  949. evaluates the calculator expression and prints the result.
  950. The calculator will display the full 64-bit address of
  951. "file1.suprtest" as
  952. |2space.offset|.
  953.  
  954. You can display the actual contents of the file:
  955.  
  956.      #6|5nmdebug >dv fileaddr,20,s    |0{first 20-bytes of file}|
  957.  
  958. .font 1
  959. Warning:  Due to a very serious bug in MPE/iX, never, never, never
  960. do this on the file Catalog.\Pub.\Sys.  If you open Catalog.\Pub.\Sys
  961. with mapped access, you will cause a system failure.
  962. .font 0
  963.  
  964. The map command displays the virtual address of a file in
  965. |2space.offset| format.  You can use the DV (Display Virtual)
  966. Command to display the file contents or you can use our
  967. method.  We prefer using a variable and mapva function, since typing
  968. in a full 64-bit address correctly is quite difficult.
  969.  
  970. .sub |1Cseq.Pub.Nuggets|
  971. `|1Cseq.Pub.Nuggets|
  972. .ent Cseq
  973.  
  974. While it is easy to predict the layout of parameters in our
  975. simple example, things can get more complicated in MPE/iX.  For
  976. example, addresses can be passed as 64-bit quantities instead of
  977. the default 32-bit values.  The best way I've found to determine
  978. parameter location is to use the Cseq (~c~alling ~seq~uence}
  979. utility in the Nuggets collection (available from Software
  980. Research Northwest 206-463-3030).  Here is the Cseq output for
  981. the FWRITE intrinsic:
  982.  
  983. .font 5.page 8.mar(r+5)
  984. Procedure FWRITE (
  985.          Parm  1:          int16   ;   |0{R26, #bits =   16}|
  986.          Parm  2: anyvar   record  ;   |0{(skip 25) R23, R24}|
  987.                                        |0{#bits = 65536}|
  988.                                        |0{Address type = LongAddr}|
  989.          Parm  3:          int16   ;   |0{SP-$0032, #bits =   16}|
  990.          Parm  4:          UInt16  )   |0{SP-$0036, #bits =   16}|
  991.       uncheckable_anyvar
  992. .font 0.mar
  993.  
  994. Note that the buffer parameter is a "LongAddr" that is passed in
  995. both R23 and R24 (the first is the space and the second is the
  996. offset). Fortunately, it is still easy to see the contents of the
  997. buffer.  If we were at a breakpoint at the start of FWRITE, we
  998. would display the buffer with:
  999.  
  1000. .font 5
  1001.      nmdebug >dv r23.r24,20,s     |0{display buffer contents}|
  1002. .font 0
  1003.  
  1004. .sub |1Integers:  16-bit versus 32-bit|
  1005. `|1Integers:  16-bit versus 32-bit|
  1006. .ent Integers
  1007.  
  1008. Cmdebug displays integers in octal as 16-bit quantities. Nmdebug
  1009. displays integers in hex as 32-bit quantities.  In our FWRITE
  1010. example, it is easy to see the value of the length parameter.
  1011.  
  1012. .font 5
  1013.      nmdebug >dv sp-32,1      |0{display the length}|
  1014.      $ 00005f00
  1015. .font 0
  1016.  
  1017. We used the DV (Display Virtual) Command to display the stack
  1018. contents.  The ",1" is not necessary - it's the default, but we
  1019. have shown it to make the following examples a little clearer.
  1020. The "dv sp-32" displays the value at sp-32 as a 32-bit quantity,
  1021. but we know that the actual value of FWRITE's length parameter is
  1022. a 16-bit quantity.  You can display two 16-bit integers using the
  1023. following:
  1024.  
  1025. .font 5
  1026.      nmdebug >dv sp-32,1,,,2  |0{display two 16-bit integers}|
  1027.      $ 0000 5f00
  1028.      nmdebug >dv sp-32,1,&#,,2 |0{display two integers in decimal}|
  1029.      &#      0  24320
  1030. .font 0
  1031.  
  1032. Display Virtual always rounds down to a virtual address that is
  1033. a multiple of four and then displays one or more 32 bit words.
  1034. .page.jump 1
  1035. .sub Miscellaneous Tips
  1036.  
  1037. .opt(f-l-r-)
  1038. `|3Miscellaneous Tips|
  1039. .opt
  1040. .ent `Miscellaneous Tips
  1041.  
  1042.  
  1043. .sub |1Return Breakpoint|
  1044. `|1Setting a "Return" Breakpoint|
  1045. .ent Setting a "Return" Breakpoint
  1046.  
  1047. We showed how to set a return breakpoint in compatibility-\mode.
  1048. You use a similar method to set a return breakpoint in native-mode
  1049. code:
  1050.  
  1051. .font 5
  1052.      nmdebug >b extract_ready
  1053.      nmdebug >c
  1054.      .
  1055.      .
  1056.      .                       |0{break at |5extract_ready|}|
  1057.      nmdebug >lev 1;b pc,-1  |0{-1 means only break once}|
  1058.      nmdebug >c              |0{continue execution}|
  1059. .font 0
  1060.  
  1061. The only difference between a CM return breakpoint, and an NM one, is
  1062. the name of the program counter.  In native-mode it's called "pc".
  1063. This sets a return breakpoint immediately after the
  1064. code that called |5extract_ready|.  Note that it's safe to use this
  1065. breakpoint anywhere in the |5extract_ready| procedure -- not just
  1066. at the beginning.
  1067.  
  1068. .sub |Debugging Batch Programs|
  1069. `|1Debugging Batch Programs|
  1070. .ent Debugging Batch Programs
  1071.  
  1072. In Debug/V, there was no practical way to debug a program running
  1073. in batch.  In Debug/iX, you can debug a batch program on the
  1074. console, although it's a bit messy to set up.  You have to do these
  1075. steps:
  1076. .mar(l+3)
  1077. `1.#4Obtain the pin number of the program you want to debug. You'll
  1078. need to use a program like Shot.\Pub.\Nuggets.
  1079. You can use the Showproc Command, if you have MPE/iX version 2.1 or
  1080. later versions.
  1081. `2.#4Go to the console and insure that there will be no output
  1082. on the console.  The easiest way to do this is to initiate a
  1083. :Restore on the console.  This assumes that your tape drive is
  1084. not configured for auto-reply.  Do not reply to the tape
  1085. request.
  1086.  
  1087. .font 5
  1088.      {On the console ...}
  1089.      :hello user.acct
  1090.      :restore
  1091. .font 0
  1092. `3.#4On another terminal,
  1093. log on with SM capability and enter debug.  For example,
  1094.  
  1095. .font 5
  1096.     :hello manager.sys
  1097.     :debug
  1098. .font 0
  1099. `4.#4Once you are inside Debug, you must set an environment
  1100. variable and force a breakpoint in the batch program. Our
  1101. example assumes that the batch program will call the FWRITE
  1102. intrinsic:
  1103.  
  1104. .font 5
  1105.      nmdebug >env job_debug true   |0{set special variable}|
  1106.      nmdebug >b FWRITE:|2pin&#|        |0{don't forget the pin&#}|
  1107. .font 0
  1108. .mar
  1109.  
  1110. You don't actually type "b FWRITE:pin&#" when setting the
  1111. breakpoint.  You substitute the actual pin&# that you obtained in
  1112. step 1 (e.g., "b FWRITE:|2103|").
  1113.  
  1114. When the batch program encounters the breakpoint, Debug/iX is
  1115. invoked and all Debug/iX input/output is done via the console. On
  1116. the console you can type any of the usual Debug/iX commands.
  1117. When you finish your debugging session, you'll need to remember to
  1118. abort the :Restore that you initiated.
  1119. You must also return to the Manager.Sys session and disable job
  1120. debugging:
  1121.  
  1122. .font 5
  1123.      cmdebug >env job_debug false
  1124. .font 0
  1125.  
  1126. .sub |1Macros|
  1127. `|1Macros|
  1128. .ent Macros
  1129.  
  1130. Debug/iX contains a small programming language that lets you create
  1131. your own macros.
  1132. Debug/iX has no command to skip over procedure calls,
  1133. although almost all
  1134. PC-based debuggers have this feature.  When single-stepping
  1135. through a program, you rarely want to single-step through external
  1136. procedures (e.g., the Print intrinsic).  Use the |2j| macro to
  1137. jump over the next native-mode BL instruction.
  1138. Macros use braces for the body of the macro (i.e., as begin/end),
  1139. so don't interpret
  1140. the braces as comments.
  1141. Here is how to
  1142. declare the macro:
  1143.  
  1144.      #6|5nmdebug >mac j {b pc+$8,-1; c}
  1145.  
  1146. Macros are declared with the Mac Command.
  1147. The first parameter to the Mac Command is the macro name (in this
  1148. case it's |2j|).  The body of the macro follows and is surrounded
  1149. with braces.
  1150. Macros can take several lines.  The |2j| macro sets a breakpoint
  1151. at the next native-mode instruction after a branch-and-link
  1152. "pc+$8".  The breakpoint is
  1153. only executed once ",-1".
  1154. Multiple commands are separated by semi-colons ";".  The last
  1155. step of the macro is to execute the Continue Command "c".
  1156. Note that the |2j| macro is only useful around branch-and-link
  1157. instructions which is
  1158. why we jump eight bytes ahead of the program
  1159. counter instead of four.
  1160. You execute the macro as if it were a built-in Debug/iX command:
  1161.  
  1162.      #6|5nmdebug >j|
  1163.  
  1164. `|1Vfilepages Macro|
  1165. .ent Vfilepages Macro
  1166.  
  1167. When doing any performance measurements with disc files, you
  1168. need to know what portion of the file is in memory.  This macro
  1169. takes advantage of many features of Debug/iX.
  1170. The macro displays the number of pages of a file that are
  1171. currently present in virtual memory.
  1172.  
  1173. .font 5.page 5
  1174.      /*  Macro:   Vfilepages
  1175.      /*
  1176.      /*  Purpose: Display the number of pages (and corresponding
  1177.      /*           sectors) of a file that are actually in memory.
  1178.      /*
  1179.      /*  Warning: Never use this macro on catalog.pub.sys.
  1180.      /*
  1181.  
  1182.      mac vfilepages (filename:str) {
  1183.         map !filename;
  1184.         w !filename " contains ";
  1185.         w vainfo(mapva(!filename),"pages_in_mem"):"D";
  1186.         w " pages in memory = ";
  1187.         w vainfo(mapva(!filename),"pages_in_mem")*:"D";
  1188.         w " sectors";
  1189.         wl;
  1190.         unmap(mapindex(!filename));
  1191.         }
  1192. .font 0
  1193.  
  1194. Lines starting with "/*" are treated as comments.  The "filename"
  1195. is a parameter to the macro and it's of string type.  To understand
  1196. the rest of the macro requires looking up the description of the
  1197. Map, Mapva, W, WL, and Unmap
  1198. Commands and an understanding of the Vainfo and Mapindex
  1199. Function.  We'll leave that up to you.  To invoke this macro, you would
  1200. do the following (note the quotes around the filename):
  1201.  
  1202. .font 5
  1203.      vfilepages "file50.suprtest"
  1204.      file50.suprtest contains 8 pages in memory = 128 sectors
  1205. .font 0
  1206.  
  1207. .font 1
  1208. Warning:  Because this macro uses the Debug/iX Map Command, do
  1209. not use it on the file catalog.pub.sys.  If you do, you will cause
  1210. a system failure.
  1211. .font 0
  1212.  
  1213. `|1DBUGINIT File|
  1214. .ent DEBUGINIT File
  1215.  
  1216. Once you start writing macros, you will want to have them
  1217. automatically loaded when you enter Debug/iX.  Debug/iX always
  1218. executes a use-file called DBUGINIT.  Debug/iX first looks
  1219. for this file in
  1220. the same group and account as the program, then it looks in the
  1221. logon group and account.  Rather than fill our DBUGINIT file with
  1222. macros, we fill it with Use Commands for different files that
  1223. contain useful macros:
  1224. You can use :file commands for the DBUGINIT file,
  1225. but you must use a fully qualified filename.  For example:
  1226.  
  1227. .font 5.mar(r+5)
  1228.      :hello david.dev,david
  1229.      :print dbuginit.macro.dev
  1230.      use splash.macro.splash
  1231.      use macros.macro.dev
  1232.      :file dbuginit.~david~.dev=debuginit.macro.dev
  1233.      :run testprog;debug     |0{Debug/iX will use debuginit.macro}|
  1234. .font 0.mar
  1235.  
  1236. .sub |1:Setdump Command|
  1237. `|1:Setdump Command|
  1238. .ent :Setdump Command
  1239.  
  1240. Classic MPE contains a :Setdump Command, but I believe most of us
  1241. ignored it because the traceback it printed was not symbolic. If
  1242. you enable :setdump in MPE/iX, you not only get an excellent
  1243. symbolic traceback, but in native-mode you are placed into
  1244. Debug/iX (certain
  1245. exceptions apply to privileged-\mode programs).
  1246.  
  1247. .sub |1MPE Commands|
  1248. `|1MPE Commands|
  1249. .ent MPE Commands
  1250.  
  1251. You can enter almost any MPE command by preceding it with a colon. This
  1252. includes UDCs and the :Run Command.  Often in the middle of a
  1253. debugging session, you need to examine your source code. An
  1254. easier way to do this is to run your editor from within Debug/iX.
  1255. One word of caution -- Debug/iX, like many HP products, fails to
  1256. see if a son process has terminated or suspended.
  1257.  
  1258. We also find it useful to invoke Cseq.\Pub.\Nuggets when we are
  1259. debugging a program.  This lets us determine the location of the
  1260. parameters for any MPE intrinsic:
  1261.  
  1262. .font 5.mar(r+3)
  1263.      nmdebug >:cseq.pub.nuggets    |0{obtain parameter addresses}|
  1264. .font 0.mar
  1265.  
  1266. .sub |1Running Qedit|
  1267. `|1Running Qedit from Debug/iX|
  1268. .ent Running Qedit from Debug/iX
  1269.  
  1270. If you invoke Qedit from Debug/iX, be sure to run it with Parm=32
  1271. (this tells Qedit not to suspend on exit). The most likely reason
  1272. to invoke Qedit from Debug/iX is to examine your source code. If
  1273. you do not /Shut your file before running your program, you will
  1274. get "Error:  Busy file" when you try to open your file inside Qedit
  1275. (inside Debug/iX).  To get around the problem, you can either
  1276. /List your source code or /Text a copy.
  1277.  
  1278. .sub |1Conclusion|
  1279. `|1Conclusion|
  1280. .ent Conclusion
  1281.  
  1282. If you are going to make heavy use of Debug/iX, I strongly recommend
  1283. getting the System Debug Reference Manual.  While it's not helpful for
  1284. learning Debug/iX, it's invaluable in looking up specific commands
  1285. and their syntax.  That part number again is 羊-90013.
  1286.  
  1287. When I first set out to write this article, I thought that it
  1288. would only take me a few paragraphs to convey what I'd learned
  1289. about Debug/iX.  If you've got this far, you realize that I
  1290. underestimated the amount of material -- not surprising given the
  1291. rich feature set of Debug/iX.
  1292. .com {toc starts here}
  1293. .if outtext
  1294. .   page
  1295. .else
  1296. .   con
  1297. .   form 3
  1298. .   tit
  1299. .   page
  1300. .   if outdouble or outfinal
  1301. .      align
  1302. .   endif
  1303. .   count 3
  1304. .   com                         The next FORM is for Contents/Preface:
  1305. .   form 2
  1306. .   jump 6
  1307. .   if not outfinal
  1308. .     jump 5
  1309. .   endif
  1310. .   opt(l- r- f-).font 3
  1311. The MPE/iX System Debugger
  1312. .   skip 4
  1313. Contents
  1314. .   opt.font 0
  1315.  
  1316.  
  1317. .   tit |1Contents|
  1318. .   con (p+ f. m14 c55 l0 r0)
  1319. .   tit
  1320. .   form 3
  1321. .   if outdouble or outfinal
  1322. .     align
  1323. .   endif
  1324. .endif    { else of if outtext }
  1325. .check(c1 f0 i1 j0 m1 o1 p1)
  1326. .com {toc ends here}
  1327.