home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / MISC / TGARTS.ZIP / DVTECH.ZIP / EXCEPT13.TEC < prev    next >
Text File  |  1994-03-03  |  20KB  |  348 lines

  1. ID:13 QEMM-386:  Exception #13 Explained
  2. Quarterdeck Technical Note #142                       Filename: EXCEPT13.TEC
  3. by Michael Bolton                                   CompuServe: EXCEPT.TEC
  4. Last revised:  3/02/92                                Category: QEMM
  5.  
  6. Subject: A detailed explanation of what QEMM-386's Exception #12 and Exception
  7.          #13 messages mean, why they are reported, and some of the steps that
  8.          can be taken to identify their causes.  See also EX13FLOW.TEC for
  9.          troubleshooting suggestions.
  10.  
  11.  
  12. Q. What is an Exception #13?  What is an Exception #12?
  13. Q. What does the QEMM Exception message mean?  How can it help me?
  14.  
  15. Users of QEMM-386 may sometimes encounter a report that an attempt has been
  16. made to execute an invalid instruction.  It is almost certain that QEMM-386,
  17. in and of itself, is not the cause of Exception #13 problems, though
  18. QEMM-386's memory managment may come into conflict with other hardware and
  19. software on your system.
  20.  
  21. Quarterdeck Technical Note #232, Exception #13 Advanced Troubleshooting
  22. (EX13FLOW.TEC) is designed to resolve conflicts in which QEMM-386 may be
  23. involved.  This technical note is its companion; here we explain in detail
  24. what a processor exception is, how you can interpret the information provided
  25. by the exception report, and what you can do to remedy the situation in the
  26. unhappy event that the techniques in EX13FLOW.TEC don't provide relief from
  27. the problem.
  28.  
  29. To answer the questions above, it's worthwhile to examine the Exception #13
  30. report bit by bit.
  31.  
  32. "The processor has notified QEMM that an attempt has been made to execute an
  33. invalid instruction..."
  34.  
  35. Exceptions are the processor's response to unusual, invalid, or special
  36. conditions in the normal operation of the 80386 processor and others in its
  37. family.  (The 80386 family includes the 80386SX, the 80386DX, the 80486SX, and
  38. the 80486DX processors; their memory management architecture is essentially
  39. the same.  In this document, the term "386" refers to any and all of these
  40. processors.)  Exceptions cause the 386 processor to stop what it's doing and
  41. to try to react to the condition that caused the exception.  QEMM-386 is
  42. designed to capture some of these exceptions -- particularly those caused by
  43. protection faults or invalid instructions, which could cause a program or the
  44. entire system to crash -- and display a report to the user.  When the
  45. processor encounters an instruction that it does not want to execute, it
  46. passes control to the protected mode interrupt 13 (decimal) handler.
  47. QEMM-386's protected mode INT 13 handler posts the Exception #13 message.
  48. Neither DOS nor Microsoft's EMM386.EXE have a protected mode interrupt 13
  49. handler, so if an exception occurs using only DOS or EMM386.EXE, your system
  50. simply crashes and you have no report.
  51.  
  52.  
  53. Q. What causes an Exception #12 or Exception #13?
  54.  
  55. "...This may be due to an error in one of your programs, a conflict between
  56. two pieces of software, or a conflict between a piece of hardware and a piece
  57. of software...."
  58.  
  59. The exception reported is most commonly #13, the General Protection Fault
  60. exception.  This indicates that a program has tried to execute an invalid or
  61. privileged instruction.  On the 386 processor, programs can run at varying
  62. privilege levels, so that the processor can better protect application
  63. programs (which generally run at lower privilege levels) from crashing the
  64. operating system or control program (which typically runs at the highest
  65. privilege level).  DOS and QEMM-386 do not enforce this protection, but
  66. QEMM-386 can report when a program running at the lowest privilege level tries
  67. to execute a privileged instruction.  The result may be a system crash, but
  68. QEMM-386 does provide a report before the crash happens.
  69.  
  70. Invalid instructions are harder to classify, for indeed Exception #13 is
  71. something of a catch-all.  Some examples of invalid instructions include:
  72.  
  73. - 386-specific instructions that are disallowed when the processor is in
  74.   virtual 8086 mode.  The processor is in this mode whenever QEMM-386 is in an
  75.   ON state -- essentially when it is providing expanded memory or High RAM.
  76.  
  77. - A program trying to write data to a segment that has been marked as
  78.   executable or read-only (the data could overwrite program code).
  79.  
  80. - Trying to run program code from a data segment (if data is read as code, it
  81.   will be a series of meaningless or nonsensical instructions -- which, if
  82.   executed, could jump to invalid addresses or overwrite the operating system)
  83.  
  84. - Exceeding the limit of a segment.  Segments in virtual 8086 mode are not
  85.   permitted to exceed FFFFh (65535 decimal) bytes or to fall below 0 bytes.
  86.   Neither a program instruction nor a memory reference may span the boundary
  87.   of a segment.
  88.  
  89. It is this last which is the most common; this is a problem also known as
  90. "segment wrap", which we will discuss later.  Again, QEMM-386 is designed to
  91. trap and report these errors, but it cannot defend against the system crashes
  92. that they may cause.
  93.  
  94. Occasionally Exception #12, indicating a stack exception, will be reported.
  95. This is a protection violation very similar to Exception #13, but is one in
  96. which the stack segment is involved in some way.  Although no easier to solve,
  97. it is a somewhat less general report than Exception #13.
  98.  
  99. Very infrequently, an Exception #0 is reported.  This is not intentional; it
  100. is usually the result of QEMM's stack being corrupted while QEMM was trying to
  101. report another exception, or is the result of some other system error.
  102.  
  103. It is important to remember that in the vast majority of cases, QEMM-386 is
  104. not involved with the problem, but is merely reporting it.
  105.  
  106.  
  107. Q.  What do I do now?
  108.  
  109. "...It is likely that the system is unstable now and should be rebooted...."
  110.  
  111. QEMM-386 is designed to offer the user the opportunity to terminate the
  112. offending program, or to reboot the computer, but often the damage has already
  113. been done by the time that the exception is trapped and reported.  In this
  114. instance, you may find the computer locked regardless of what you choose.  If
  115. the computer is indeed hung, you should write down the information on the
  116. screen and then reboot the machine.
  117.  
  118. While QEMM-386's exception reports can be cryptic to non-programmers -- or to
  119. programmers who have little experience with assembly language -- the
  120. information that they provide can sometimes be quite helpful. Exception
  121. reports can help you to identify which program has triggered the exception
  122. message, what the invalid instruction was, and the state of the processor's
  123. registers when the error occurred.  Armed with this information, you may be
  124. able to help the developer of the offending application to determine the
  125. problem that led to the exception, and thus the developer may be able to
  126. provide a temporary workaround or a permananent fix.
  127.  
  128. The exception report is divided into three parts --
  129.  
  130. 1) The vector or class of exception, and its location and error code. The
  131. location of the exception indicates the address in memory at which the invalid
  132. instruction was attempted.  The program loaded at this address (if indeed a
  133. program is loaded there) should be noted by running Manifest.
  134.  
  135. Exception #13 at 1B12:0103, error code: 0000
  136.  
  137. In this example, the program loaded at address 1B12:xxxx is automatically your
  138. suspect.  Reboot your system in the same configuration as you had when the
  139. Exception #13 occurred.  If the problem happened during an application
  140. program, don't load the application just yet.  Load Manifest instead, and have
  141. a look at First Meg / Programs.
  142.  
  143. Memory Area   Size   Description
  144. 03D1 - 0465   2.3K  COMMAND
  145. 0466 - 046A   0.1K  (04C0)
  146. 046B - 0483   0.4K  COMMAND Environment
  147. 0484 - 0487   0.1K  COMMAND Data
  148. 0488 - 0498   0.3K  DV Environment
  149. 0499 - 04BE   0.6K  DV
  150. 04BF - 1A38    85K  DV Data
  151. 1A39 - 1A52   0.4K  COMMAND Data
  152. 1A53 - 1AE7   2.3K  COMMAND
  153. 1AE8 - 1B00   0.4K  COMMAND Environment
  154. 1B01 - 7E4F   397K  [Available]
  155.  
  156. The sample Exception #13 above happened in that Available range, so it was the
  157. program that would have been loaded had we not loaded Manifest -- that is, the
  158. application program.  If you have a TSR loaded low, and the Exception #13 is
  159. occuring within that TSR's address space, then it is your suspect, rather than
  160. the application.  In any case, the program whose code falls into the range in
  161. which the Exception #13 occurred likely has a problem of some type.
  162.  
  163. 2)  The second part of the Exception #13 message is the register dump:
  164.  
  165. AX=0000 BX=0000 CX=0000 DX=0000 SI=FFFF DI=0000 BP=0000
  166. DS=1B12 ES=1B12 SS=1B12 SP=FFFE Flags=7246
  167.  
  168. The registers are the temporary storage areas on the 80386 chip which are used
  169. for calculations and addressing.  Each register is two bytes (16 bits) in
  170. size, so each register is capable of holding a value from 0 to FFFF
  171. (hexadecimal), or from 0 to 65335 (decimal).
  172.  
  173. If any registers here are 0000 or FFFF, it's possible that you could be
  174. looking at a segment wrap.  A segment wrap happens whenever a program attempts
  175. to access -- read from or write to -- something beyond the limit of a segment.
  176. A word value consists of two adjacent bytes; if a word value were to begin at
  177. FFFF (which is the last byte of a segment), the second byte of that value will
  178. be outside the segment -- and an attempt to read from or write to that word
  179. will thus cause a protection violation.  Similarly, a doubleword is four
  180. adjacent bytes; if any of the last three bytes are outside of the segment
  181. limit, a segment wrap and a protection violation will occur when an access is
  182. attempted.
  183.  
  184. On an 8086 processor, it's actually possible for a segment wrap to occur
  185. without a protection violation, simply because the 8086 has no hardware
  186. protection at all.  What is the byte after the last byte of a segment? On the
  187. 8086, it's the FIRST byte of the same segment.  (Non-technical analogy for
  188. poker players: Queen - King - Ace - Two - Three is a straight in the
  189. penny-ante poker game played when the 8086 processor is dealing.  The 386
  190. processor is a very strict dealer, and does not permit this.)  It is possible
  191. (though unlikely) for a program to continue without a crash on an 8086
  192. processor when two "adjacent" bytes are actually a whole segment apart; it
  193. could theoretically be possible on a 386 too, but the exception is generated
  194. before the memory access can be completed.
  195.  
  196. This sort of problem is seen most commonly during a string move -- the program
  197. is copying a whole block of data from one range of addresses to another.  You
  198. may not understand this, and actually it doesn't matter if you don't.
  199. Briefly, though, SI stands for Source Index; DI stands for Destination Index.
  200. These two registers are used for string instructions -- instructions that load
  201. or copy information sequentially.  String instructions are extremely powerful
  202. and useful, since they allow the developer to deal with large amounts of data
  203. in a single pass.  A byte or a word value can be fetched from memory by one
  204. string instruction, dealt with, and then the result can be copied to a new
  205. memory location with a second string instruction -- and all this can be
  206. managed with an extremely tight, fast loop.  An entire range of addresses (for
  207. example, in screen memory) can even be filled with a given value using a
  208. single instruction.  The catch here is that the string instruction is only
  209. valid as long as the value of the SI or DI register does not fall outside the
  210. range addressable by these registers.  If either one of these tries to exceed
  211. FFFF (or tries to fall below 0000), as a string is being copied from one
  212. region of memory to another, you'll get a protection violation.
  213.  
  214. 3)       Instruction: A5 CC 00 00 00 00 00 00 00 00 00 00 00 00 00
  215.          Do you want to (T)erminate the program or (R)eboot?
  216.  
  217. This is the invalid instruction that the program was trying to execute when
  218. the processor stopped it.  Since most humans don't have a hope of interpreting
  219. machine language by looking at the opcodes, you can get a better
  220. interpretation of what is going on by examining this instruction with a
  221. program that can render machine codes into assembly language. (Well... it's
  222. better than nothing.)  To do so, go into DEBUG; type DEBUG at the DOS prompt.
  223.  
  224. Enter the values from the Instruction line by typing
  225.  
  226. E 100
  227.  
  228. at DEBUG's hyphen prompt, and then entering each byte (pair of digits) from
  229. the instruction line.  Follow each byte with a space.
  230.  
  231. (As a bonus -- if you're running under DESQview, you can Mark the information
  232. from the Exception #13 report, and Transfer it into DEBUG running in a
  233. different Big DOS window.)
  234.  
  235. If most of the bytes begin with a 4, 5, 6, or 7, there's a good chance that
  236. you're seeing a program trying to execute text, thinking that text to be code.
  237. This can happen in several circumstances, but frequent offenders are those
  238. programs which load code at the top of conventional memory during boot -- and
  239. therefore during the OPTIMIZE process -- and presume that no program will
  240. allocate that memory.  Programs which place parts of themselves at the top of
  241. conventional memory typically do so without protecting themselves from
  242. programs like LOADHI which may need to allocate all conventional memory at
  243. appropriate times; LOADHI (and programs like it) will overwrite the vulnerable
  244. code.
  245.  
  246. As a real-world example, PROTMAN, a program whose purpose in life is to manage
  247. the loading of various parts of 3Com and MS-LAN networks, did this in past
  248. versions, as explained in Quarterdeck Technical Note #173, PROTMAN.TEC.
  249. During the OPTIMIZE process, LOADHI would allocate all conventional memory
  250. while it was determining the size of the various drivers that were being
  251. loaded. PROTMAN would jump to what it thought was still its own code, but
  252. there would be LOADHI signatures there -- text -- and PROTMAN would crash.
  253.  
  254. You can see the contents of this string if you Dump the instruction you just
  255. entered; use DEBUG's D instruction to do this.
  256.  
  257. -d 100
  258.  
  259. 1DC0:0100  4F 41 44 48 49 53 49 47-4E 41 54 55 52 BF 42 87 LOADHISIGNATUREB
  260. 1DC0:0110  98 FF 6F E2 E9 FF 00 00-26 21 F1 B3 34 00 AF 1D ..o.....&!..4...
  261. 1DC0:0120  01 00 D3 E0 0B E8 59 5F-07 B0 00 AA 5F 9D F8 C3 ......Y_...._...
  262. 1DC0:0130  AA 41 FE 06 AD 90 C3 2E-C7 06 CF 88 00 00 2E 89 .A..............
  263.  
  264. ASCII codes starting with 2 are generally punctuation marks; bytes 30-39
  265. represent numeric digits; 3A-3F are punctuation, 41-5A are capital letters,
  266. 61-7A are small letters.  Any instruction made up mostly of these numbers is
  267. almost certainly text -- and therefore not executable program code.  The
  268. program that is trying to run such an instruction is doing so in error. When
  269. the instructions are NOT mostly in the 40-80 range, you should try to
  270. Unassemble them.
  271.  
  272. -u 100
  273.  
  274. 20C0:0100 A5            MOVSW
  275. 20C0:0101 CC            INT     3
  276. 20C0:0102 0000          ADD     [BX+SI],AL
  277.  
  278. This is the killer instruction from the example Exception #13 above. It's
  279. performing a MOVSW (MOVe String Word) at a point when the SI register is FFFF,
  280. and that means that it's trying to write a word value to or from the last byte
  281. of a segment, which (as described above) is illegal.
  282.  
  283. Other invalid instructions are harder for the non-programmers of the world to
  284. interpret.  Often the first byte of an invalid instruction is 0F -- which is a
  285. valid protected-mode instruction, but which the processor interprets as an
  286. invalid opcode if the machine is in Virtual 86 mode.  Exceptions of this kind
  287. showed up more commonly in the past, with programs that were trying to enter
  288. protected mode without calling the Virtual Control Program Interface.  VCPI is
  289. an industry-standard way for protected-mode software to coexist with 386
  290. expanded memory managers such as QEMM-386; all 386 memory managers these days
  291. are VCPI-providers, and almost all protected-mode programs are VCPI users (or
  292. "clients").  Non-VCPI protected-mode programs include some memory- and
  293. hardware-diagnostic programs, and programs that use the DPMI memory management
  294. specification exclusively.  Diagnostic programs typically recommend that you
  295. disable all memory-management software during diagnosis.  DPMI programs will
  296. typically accept VCPI memory management; those rare programs that do not will
  297. simply refuse to start up under QEMM-386.  In such cases, you may install
  298. QDPMI (the Quarterdeck DPMI Host) on your system; QDPMI is available on the
  299. Quarterdeck BBS at (310) 314-3227, Compuserve (!GO QUARTERDECK), or large
  300. local BBS systems.
  301.  
  302. How can an Exception #13 be fixed?  Two Quarterdeck Technical Notes can help
  303. you determine if you can solve the problem yourself.  Quarterdeck Technical
  304. Note #241, QEMM-386:  General Troubleshooting (TROUBLE.TEC) is a good place to
  305. start.  This note describes common problems and possible solutions, and will
  306. help if the cause of the Exception #13 is a memory conflict or bus-mastering
  307. issue.  Quarterdeck Technical Note #232, Exception #13 Advanced
  308. Troubleshooting (EX13FLOW.TEC) should help you to determine if there is
  309. anything at all that you can do yourself to fix the problem.
  310.  
  311. If you follow the instructions in both of these technical notes completely,
  312. and the Exception #13 persists, the prospects for a resolution are bleak,
  313. since the problem is almost certainly a bug in the offending program.  If this
  314. is so, unless you can alert the developer of the program (and make him or her
  315. understand all this, which might be another task altogether), you can never
  316. really make the problem go away, although sometimes you may be able to make it
  317. subside.
  318.  
  319. Changing the location of the offending program in memory will sometimes help.
  320. If you're running under DESQview, and you're sure that you've given the
  321. program enough memory (i.e., all you can give it), try adding 16 to the size
  322. of the script buffer on page 2 of Change a Program.  If you're not running
  323. under DESQview, try adding an extra file handle or two.  The key here is to
  324. change the location of the program in memory, which can occasionally be enough
  325. to provide temporary relief from the Exception #13.
  326.  
  327. There is a substantial caveat:  You're not fixing the problem by doing this;
  328. you're just making it submerge.  There's still probably a bug in the offending
  329. program -- you've just changed it from a bomb to a landmine.  If you can
  330. reproduce the problem consistently, you should still contact the publisher of
  331. the application with all of the data from the Exception #13 message, and all
  332. of the data that you can supply about your system and its current
  333. configuration.
  334.  
  335. With the exception (no pun intended) of the techniques mentioned above and in
  336. EX13FLOW.TEC, non-programmers can do little to fix the root cause or even the
  337. symptoms of Exception #13.  If you are unsuccessful in resolving a conflict,
  338. the information provided by the report should be forwarded, along with a
  339. Manifest printout and a complete description of your system, to the developer
  340. of the program that you were running at the time.
  341.  
  342.   ************************************************************************
  343.   *          Trademarks are property of their respective owners.         *
  344.   *This technical note may be copied and distributed freely as long as it*
  345.   *is distributed in its entirety and it is not distributed for profit.  *
  346.   *          Copyright (C) 1993-94 by Quarterdeck Office Systems         *
  347.   ************************ E N D   O F   F I L E *************************
  348.