http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57761

            Bug ID: 57761
           Summary: USE_PROC_FOR_LIBRARIES does not work correctly
           Product: gcc
           Version: 4.8.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: boehm-gc
          Assignee: unassigned at gcc dot gnu.org
          Reporter: bernd.edlinger at hotmail dot de

Created attachment 30410
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=30410&action=edit
Proposed patch to fix this defect.

usually this code is not used, but if the define USE_PROC_FOR_LIBRARIES
is set there is linux code in dyn_loac.c at function GC_register_map_entries
that does not work correctly. What happens is that this code computes
heap bounds, but it may happen that some root segments are in between
the heap segments.

    /* Compute heap bounds. FIXME: Should be done by add_to_heap?       */
        least_ha = (word)(-1);
        greatest_ha = 0;
        for (i = 0; i < GC_n_heap_sects; ++i) {
            word sect_start = (word)GC_heap_sects[i].hs_start;
            word sect_end = sect_start + GC_heap_sects[i].hs_bytes;
            if (sect_start < least_ha) least_ha = sect_start;
            if (sect_end > greatest_ha) greatest_ha = sect_end;
        }
        if (greatest_ha < (word)GC_scratch_last_end_ptr)
            greatest_ha = (word)GC_scratch_last_end_ptr;

Later the map file is parsed, and all segments that fall in between
the least_ha and greatest_ha are ignored:

 if (start >= least_ha && end <= greatest_ha) continue;

usually the heap segments start from small addresses and the
map file concatenates adjacent segments with identical attributes.

If the least_ha is below the data segment and the greatest_ha above
the data segment, the gc can discard objects, that are still in use.

This leads to all kinds of crashes, and an occasionally an assertion at
finalize.c line 648: GC_ASSERT(GC_is_marked(GC_base((ptr_t)curr_fo)));

The reason for this is that "fo_head" may reside in a data segment
that is removed from the root set by the above if statement.

The attached patch fixes this by intersecting the heap segments
from the writable data segments which form the root segments.

Reply via email to