home *** CD-ROM | disk | FTP | other *** search
/ MS-DOS 8.0 / MS-DOS8.iso / SOFTWARE / QEMM / TECHNOTE / EXCEPT13.TEC < prev    next >
Text File  |  1997-05-15  |  20KB  |  401 lines

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