Title | mv2test failure |
Status | closed |
Priority | essential |
Assigned user | Gareth Rees |
Organization | Ravenbrook |
Description | Running mv2test produces the following assertion failure: MPS ASSERTION FAILURE: !cbs->inCBS cbs.c 94 |
Analysis | The backtrace looks like this: CBSEnter (cbs=0x103ffe1f0) at cbs.c:94 CBSDelete (cbs=0x103ffe1f0, base=0x10409c000, limit=0x10409e000) at cbs.c:1095 MVTReturnBlockSegs (mvt=0x103ffe160, block=0x103fef618, arena=0x1003a9000) at poolmv2.c:916 MVTNoteNew (cbs=0x103ffe1f0, block=0x103ff2c08, oldSize=8312, newSize=16504) at poolmv2.c:953 cbsBlockGrow (cbs=0x103ffe1f0, block=0x103ff2c08, oldSize=8312) at cbs.c:419 cbsInsertIntoTree (baseReturn=0x7fff5fbfa900, limitReturn=0x7fff5fbfa8f8, cbs=0x103ffe1f0, base=0x101dfd000, limit=0x101dfe3a0) at cbs.c:523 CBSInsertReturningRange (baseReturn=0x7fff5fbfa958, limitReturn=0x7fff5fbfa950, cbs=0x103ffe1f0, base=0x101dfd000, limit=0x101dfe3a0) at cbs.c:858 CBSInsert (cbs=0x103ffe1f0, base=0x101dfd000, limit=0x101dfe3a0) at cbs.c:895 MVTFree (pool=0x103ffe160, base=0x101dfd000, size=5024) at poolmv2.c:674 PoolFree (pool=0x103ffe160, old=0x101dfd000, size=5021) at pool.c:331 mps_free (pool=0x103ffe160, p=0x101dfd000, size=5021) at mpsi.c:706 stress (class=0x1002c7ad8, arena=0x1003a9000, size=0x100002230 <randomSize>) at mv2test.c:261 stress_with_arena_class (aclass=0x1002cb398) at mv2test.c:303 main (argc=1, argv=0x7fff5fbffa90) at mv2test.c:322 CBS callbacks are only allowed to call back into the CBS in very limited ways, and the CBSEnter/CBSLeave protocol checks this. In particular, MVTNoteNew (which is a CBS callback) is wrong to call MVTReturnBlockSegs. Why does it call it? Because the ABQ is full. The reason why CBSInsert and CBSDelete use callbacks (instead of returning the new or deleted block via a function parameters) is that each CBS maintains an "emergency list" of blocks which have been freed but for which it has not yet been able to allocate a CBSBlockStruct to refer to it (because of low memory). These emergency list blocks get merged back into the splay tree in an eager fashion, which might result in many calls to the callbacks. It's not good for the CBS to have this emergency block structure. Better if that's implemented in a separate module, and available as a fallback strategy in any pool (for example MV might want to use it instead of just losing memory). More detailed analysis and plan here [1]. |
How found | automated_test |
Evidence | [1] <https://info.ravenbrook.com/mail/2013/05/21/09-57-40/0/ > |
Observed in | 1.111.0 |
Created by | Gareth Rees |
Created on | 2013-05-16 16:10:07 |
Last modified by | Gareth Rees |
Last modified on | 2013-05-22 00:21:39 |
History | 2013-05-16 GDR Created. |
Change | Effect | Date | User | Description |
---|---|---|---|---|
182032 | closed | 2013-05-21 13:35:41 | Gareth Rees | Refactor MVT so that blocks are pushed onto the ABQ in just one place. Fix bug in MVTDelete: need to remove the whole of the old range from the ABQ, not just the range we're deleting. |