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
};