⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 heapinfo.txt

📁 一个堆栈管理器的源码
💻 TXT
📖 第 1 页 / 共 4 页
字号:

            This symbol enables an alternate set of functions that
            test pointers for validity and report invalid pointers
            on stderr.  The defined value of the symbol is taken to
            be the stream on which error reports should appear. For
            example, -D_HEAPCHECK=stdout sends error reports to the
            standard output stream.

            STDMSC and NDEBUG both override _HEAPCHECK.  If either is
            defined _HEAPCHECK is ignored.

            For further details see section IV.C.


         c. _HEAPDEBUG -- debugging heap problems

            This symbol enables an alternate set of functions that
            diagnose heap problems.  The functions that alter the
            heap are replace by equivalents that check the heap
            consistency with _fheapchk(), perform the standard heap
            operation, and then record the transaction for diagnostic
            reports triggered by errors.

            The defined value of the symbol is taken to be the stream
            on which error reports should appear. For example,
            -D_HEAPDEBUG=stdout sends error reports to the standard
            output stream.

            Enabling _HEAPDEBUG also enables a stringent form of
            _HEAPCHECK.  Instead of a test on the value of the pointer
            offset, _HEAPDEBUG checks that a matching entry exists in
            the heap (this cheap as _HEAPDEBUG must traverse the heap
            to check for errors).  Thus _HEAPDEBUG guarantees that no
            pointer that happens to have a zero offset can masquerade
            as a heap pointer.

            STDMSC and NDEBUG both override _HEAPDEBUG.  If either is
            defined _HEAPCHECK is ignored.

            For further details see section IV.D.


         d. _HEAPTRACE -- tracing heap activity

            This symbol enables an alternate set of functions that
            trace heap activity.  Functions that alter the heap are
            replaced by equivalents that write a transaction record
            to the trace log file after every heap access.  The
            transaction reports give the sequence number, the name
            of the function, the value of the parameters, the source
            file and line number and the returned result.

            The defined value of the symbol is taken to be the stream
            on which transaction reports should appear.  For example,
            -D_HEAPTRACE=stdout sends reports to the standard output file.

            Enabling _HEAPTRACE implies that _HEAPDEBUG is enabled as well.

            STDMSC and NDEBUG both override _HEAPTRACE.  If either is
            defined _HEAPCHECK is ignored.

            For further details see section IV.E


   C. Direct access to the heap data structures.

      The heap manager is a layer between two interfaces.  On the
      bottom is the DOS memory manager that believes in arenas and
      paragraph alignment, but handles blocks larger than 64 Kb
      easily.  On the top is the C run-time library definition that
      believes in size_t, word alignment, and other limitations of
      32-bit segmented addressing on a 16-bit machine with an 8-bit
      oriented architecture.

      The two interfaces are represented explicitly.  On one hand
      there are arenas that match the DOS requirements (typdef _ARENA).
      The memory contained in an arena is managed with a list of chunks
      where each chunk conforms to the requirements of the C interface
      (typedef _CHUNK).

      In order to support reallocation and expansion of free'd memory
      blocks there is a separate list of chunks that have been free'd
      that are potential targets for reuse.  Prior to an allocation
      request the entries in this list are added to the free list, and
      adjacent free blocks are joined.  (Thus the name join list from
      to-be-joined).  This list is usualy empty and
      when not empty it is small so the overhead is tiny.

      To "walk" the heap you traverse the list of arenas based on
      _heaphead, and within each arena traverse the list of chunks based
      on the arena header.  The free and join lists may also be traveled
      based on their headers _freelist and _joinlist, but this is not
      actually necessary as all chunks, free or used, appear on their
      respective arena-control lists.


   D. The heap manager will handle non-DOS memory.  If you provide a
      block of memory with an initialized arena and chunk header the
      heap manager will happily manage the it as part of the memory
      pool.  For more information see the get-new-arena portion of
      _xalloc() in heaputil.c.  Be sure to set your _ARENA.isdos to
      FALSE to prevent _fheappack() from trying to give it back to DOS.

      This feature is especially useful on systems with non-DOS memory
      such as EMS or XMS "upper" memory in the BIOS area from C0000 to
      FFFFF, or video graphics memory in the A0000-AFFFF region.
        
      The next version of the heap manager will provide functions to
      add and delete non-DOS blocks of memory from the heap.


IV. Error handling and debugging   

   The replacement heap manager provides a heap that is harder to damage,
   and easier to debug than the original heap manager.  The following
   sections describes the salient features.


   A. Comprehensize error checking

      The heap checking performed by the MSC _fheapchk() is minimal.  It
      appears to be a simple limit test of heap pointers against the
      boundaries of the entire heap area.

      The replacement heap manager uses a detailed consistency check.
      Every pointer is validated against the individual arena limits.
      Further, the nodes in the linked lists are checked for reciprocity
      (MSC cannot do this because it does not have a doubly-linked list).

      The reciprocity test is an extermely powerful method of heap
      validation.  It is even possible to repair a damaged heap by
      appropriate use of the linked lists.  This facility is not
      included in this library because its usefulness is questionable,
      and it grossly exceeds the fuctionality of the specifications
      (the MSC heap manager).  The consistency check also verifies
      that the safety margins set by _heappad are intact.

      The actual validation routines are found in fheapwlk.c.  _Fheapchk()
      and _fheapset() use _fheapwalk() to traverse the heap.


   B. User controlled allocation padding for debugging.

      One classic problem with heap management is writing past the end
      of a buffer obtained from the heap.  This typically produces
      extremely hostile effects.  As the routines that handle
      heap-generated buffers are usually embedded in the lower layers
      of software, checking them can be tedious.

      One method of testing this mode of failure is to add extra space
      at the ends of the allocated areas.  If the failures stop, there
      is evidence of a heap problem.  Of course, changing sizes moves
      things around which can turn errors on and off randomly so the
      evidence is flimsy.  The problem with this debugging technique
      is that changing the buffer lengths manually is a time-consuming,
      error-prone operation with marginal utility.

      The replacement heap manager provides a control for automatically
      extending all heap allocation requests.  Thus an initialization
      parameter is enough to provide evidence for or against heap
      problems.  Typically the padding is set to one or two times the
      size of the structures being manipulated.

      Because the padding affects the distance between the data area
      and the heap control structures it cannot be changed after the
      heap has been initialized.  The heap manager takes a copy of
      _heappad when the heap is initialized and uses the copy thereafter.
      Thus _heappad must be set as early as possible, typically in main().

      Note that command-line wild cards processed with setargv.obj use
      the heap before main is started.  Normal programs without wild card
      expansion can use:

            extern size_t _heappad;     /* declare the global variable */

            int main()
            {
            _heappad = 100;             /* set the value */
            }

      But programs with wild card handling enabled (those linked with the
      special version of setargv.obj) must use:

            size_t _heappad = 100;      /* define the global and its value */

            int main()
            {
            }

      This sets the value at compile/link time rather than at run time.

      The safety margins are automatically filled when a heap entry
      is allocated.  The fill pattern is initially alternating bits,
      0x55, but it is reset by every call to _fheapset().  _Fheapchk()
      compares the two safety margins and reports _HEAPBADPTR if they
      differ.
   

   C. Heap pointers are distinctive and are checked for validity.

      All heap pointers are aligned on paragraph boundaries, so that
      a non-zero offset indicates an invalid pointer.  Since all of
      the functions receiving pointers as arguments check for invalid
      pointers it is hard to corrupt the heap with a non-heap pointer. 

      When an invalid pointer is detected the functions ignore the
      call and, where possible, return a failure indicator:

        _expand()     returns NULL

        _ffree()      does nothing because _ffree() is void

        _fheapwalk()  returns _HEAPBADPTR when _heapinfo._pentry is bad

        free()        does nothing because free() is void

        _frelocate()  returns NULL

        _hexpand()    returns NULL

        hrealloc()    returns NULL

        _hmsize()     returns zero

        _msize()      returns zero

        realloc()     returns NULL

      You may wish to compile your application with -D_HEAPCHECK=<stream>
      to get more active error handling.  The symbol _HEAPCHECK changes the
      standard heap access functions to alternates that test pointers
      for validity and report errors on the indicated stream file rather
      than silently ignoring them.

      The error messages appear on stderr and locate the offending
      function call by name, source file and line number.  You can
      install your own error handler by modifying or replacing
      _ptr_chk() in ptrchk.c.

      As a matter of fact, the pointer checks are quite simple and
      therefore very fast.  You may decide to leave the error checks
      enabled in working software just to catch the infrequent errors
      or the ones that will "never happen".

      Note that the paragraph alignment principle imples that a
      protected-mode equivalent of the replacement heap manager is
      feasible, with each heap entry having it's own selector value
      and (potentially) a individual set of permissions.


   D. Debugging with _HEAPDEBUG

      The symbol _HEAPDEBUG enables an alternate set of heap functions
      that aid in debugging.  The debug functions keep track of every
      heap entry they process, recording the function name, desired size,
      source file name and line number responsible for the entry, plus a
      transaction (sequence) number.  The debug functions also check the
      heap status prior to every heap access and print a diagnostic report
      if _fheapchk() reports a problem.  The value of _HEAPDEBUG is taken
      to be the stream on which diagnostic error reports should appear.

      Enabling _HEAPDEBUG also enables a stringent form of pointer
      validity checking.  Instead of a test on the value of the pointer
      offset, _HEAPDEBUG checks that a matching entry exists in the heap
      (this comes free because _HEAPDEBUG must traverse the heap anyway
      to check for errors).  Thus _HEAPDEBUG guarantees that no pointer
      that happens to have a zero offset can masquerade as a heap pointer.

      When a debug function detects an error it writes a diagnostic
      report to the indicated stream file and exits.  The report includes
      the following information:

            - the function detecting the error (function name, source
              file, and source line number)

            - the heap information on the offending entry (actual size,
              address, and used/free status)

            - a dump of the heap as described in section III.B.3.a
              including all of the debugging fields

      Debugging with an appropriate (non-zero) value in _heappad
      increases the chances of detecting a wild pointer or a pointer
      running past an end of a heap entry.

      The debugging capability of the replacement heap manager features
      the following benefits:

            - Mapping multiple heap entries to each debug record
              permits debugging of very large heaps by minimizing
              the memory overhead of debug mode.

            - Variable safety margin (_heappad) allows you to match
              the size of application structures.

            - No source code changes are necessary to activate the
              debugging capability, only recompilation with the
              -D_HEAPDEBUG=<stream> definition.

      The file dbugdemo.c illustrates the basic techniques.


   E. Debugging with _HEAPTRACE

      The symbol _HEAPTRACE enables an alternate set of heap functions
      that aid in debugging.  The debug functions report every heap
      transaction, including the sequence number, the name of the
      function, the value of the parameters, the source file and line
      number, and the returned result.  The transaction reports are 
      sent to the stream defined by -D_HEAPTRACE=<stream>.

      Note that the heap transaction sequence number is only a rough
      guide to the chronology of events.  First, heap operations in
      modules compiled without _HEAPTRACE or _HEAPDEBUG do not affect
      the sequence number so there may be hidden transactions.  Second,
      when the transaction is saved in a debug record the sequence
      number is stored as well.  Because all heap entries related to
      an individual function call (and of identical size) share a
      debug record they will all appear to have the sequence number
      of the most recent member.

      Enabling _HEAPTRACE also enables _HEAPDEBUG and _HEAPCHECK.


   F. Monitoring heap data

      The _heapwatch() function establishes the read-only status of
      heap entries.  Entries marked read-only are tested by the

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -