Fix (garbager) : The back pointer validity constraint was wrong.

"Igor V. Melichev" <[email protected]>
Newsgroups gmane.comp.printing.ghostscript.patches
Message-ID <[email protected]>
[Log message beg]
Fix (garbager) : The back pointer validity constraint was wrong.

DETAILS :

Bug 687021 "A crash in memory manager"

Here is what happens :

A big chunk is allocated by i_alloc_struct_array.
Later a part of the array is released.
Then another object is allocated in the released area.
Then the object is being relocated.
The old validity constraint in igc_reloc_struct_ptr assumed that the object
is in a chunk of the standard size.
However it is not.
The check fails, and gs_exit() is called.
The latter calls vm_reclaim and falls into an infinite recursion and
crashes.

This patch enhances the constraint for instandard (big) chunks.
Unfortunately their sizes can't easy obtain from igc_reloc_struct_ptr,
therefore the new check only works for pointers to same chunk.
A new field (DEBUG=1 only) is inserted into gc_state_s to access the chunk
from
igc_reloc_struct_ptr. We're not happy of this solution,
but there is no idea how to improve it.


EXPECTED DIFFERENCES :

With -Z? the old code failed with pdfwrite->ppmraw with the following tests
:

040-01.ps
091-01.ps
110-01.ps
282-01.ps
Altona.Page_3.2002-09-27.pdf    (crash)

The new code doesn't fail with -Z? .

Nightly regression doesn't test -Z? .
[Log message end]

Branches: HEAD.


Changes:



*** f:\casper\HEAD\gs\src\igc.c Wed Sep  3 19:21:27 2003
--- files\gs\src\igc.c Thu Oct 16 00:53:15 2003
***************
*** 1189,1192 ****
--- 1189,1195 ----
      SCAN_CHUNK_OBJECTS(cp)
   DO_ALL
+ #if DEBUG
+  pstate->container = cp;
+ #endif
      /* We need to relocate the pointers in an object iff */
      /* it is o_untraced, or it is a useful object. */
***************
*** 1206,1209 ****
--- 1209,1215 ----
    (*proc) (pre + 1, size, pre->o_type, pstate);
   }
+ #if DEBUG
+  pstate->container = 0;
+ #endif
      END_OBJECTS_SCAN
  }
***************
*** 1241,1248 ****
  #ifdef DEBUG
       /* Do some sanity checking. */
!      if (back > gcst->space_local->chunk_size >> obj_back_shift) {
    lprintf2("Invalid back pointer %u at 0x%lx!\n",
      back, (ulong) obj);
    gs_abort();
       }
  #endif
--- 1247,1260 ----
  #ifdef DEBUG
       /* Do some sanity checking. */
!      chunk_t *cp = gcst->container;
!
!      if (cp != 0 && cp->cbase <= (byte *)obj && (byte *)obj <cp->ctop) {
!   if (back > (cp->ctop - cp->cbase) >> obj_back_shift) {
        lprintf2("Invalid back pointer %u at 0x%lx!\n",
          back, (ulong) obj);
        gs_abort();
+   }
+      } else {
+   /* Pointed to unknown chunk. Can't check it, sorry. */
       }
  #endif



*** f:\casper\HEAD\gs\src\igc.h Sun Jun 16 08:47:10 2002
--- files\gs\src\igc.h Thu Oct 16 00:46:40 2003
***************
*** 68,71 ****
--- 68,74 ----
      gs_raw_memory_t *heap; /* for extending mark stack */
      name_table *ntable;  /* (implicitly referenced by names) */
+ #if DEBUG
+     chunk_t *container;
+ #endif
  };
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.