|Title||Growing an arena can allocate a chunk with no memory|
|Assigned user||Gareth Rees|
|Description||MMQA test function/26.c asserts at ref.c:43 .|
|Analysis||See  for a backtrace and  for analysis. Summary of the problem:|
1. VMArenaGrow was called with size=7778.
2. It tried to create chunks and keept failing until eventually it succeeded in creating a chunk with base=0xbffdc000 limit=0xbffde000 — that is, just 8192 bytes (one arena grain).
3. ChunkInit used the first grain of the chunk for the ChunkStruct and the page tables, and finally called ArenaFreeLandInsert with the remainder of the chunk — but because the chunk is only one grain long, there was no remainder.
The underlying problem is that VMArenaGrow has a calculation of the minimum size of a chunk here:
Size chunkMin = 4 * 1024; /* typical single page */
This is bogus:
1. The arena grain size can vary. It should call ArenaGrainSize to determine the unit of allocation.
2. The chunk needs overhead for the ChuckStruct and the page tables.
3. When (as here) the arena is being grown in order to satisfy an allocation request, there's no point in allocating a chunk that is too small to satisfy the request. So the minimum size should be at least as large as the allocation request plus chunk overhead.
Additionally, the problem should have been caught much earlier:
4. LandInsert should assert that its range is non-empty.
5. So should ArenaFreeLandInsert.
6. ChunkInit should assert that there is space left over in the chunk after the header and page table have been allocated.
|Created by||Gareth Rees|
|Created on||2016-04-11 14:16:20|
|Last modified by||Gareth Rees|
|Last modified on||2016-04-20 17:55:44|
|History||2016-04-11 GDR Created.|
|190952||closed||2016-04-11 20:33:38||Gareth Rees||When growing an arena: (i) don't create a chunk that's too small for the allocation that's going to follow; (ii) don't create a chunk that's larger than necessary.|
|190728||closed||2016-04-05 16:08:54||Richard Brooksby||Pre-release patch for 1.115.0, fixing test/function/26.c, which was allocating a chunk with zero size available for allocations.|