fix(memhub): detection 记录表满时 realloc 扩容 - 原 32MB/16B=2M 条满后新 alloc 无记录,is_alive 误报读取悬空(hdr=0x5 活跃块不在记录表);改为 stdlib.realloc 翻倍扩容(对齐 chk_stack),保证 is_alive/_det_probe 全程覆盖
This commit is contained in:
1 parent
b3b82a8093
commit
40f10f6348
1 file changed
+18
-4
+18
-4
@@ -323,6 +323,7 @@ class MemBuddy(MemManager):
|
||||
# detection=1 → alloc 前后 2 字节 0xCDCD 标记 + 记录表 + 每次 alloc 后探测
|
||||
detection: t.CInt = 0
|
||||
detection_size: t.CSizeT = MEMBUDDY_DET_RECORD_SIZE
|
||||
_det_arena: t.CVoid | t.CPtr = None # 记录区基址(stdlib.malloc,供 realloc 扩容)
|
||||
_det_records: t.CUInt64T | t.CPtr = None # 记录表(每 2×u64 = 1 条:{ptr, size})
|
||||
_det_count: t.CSizeT = 0 # 已记录条数
|
||||
_det_cap: t.CSizeT = 0 # 记录容量(条)
|
||||
@@ -410,6 +411,7 @@ class MemBuddy(MemManager):
|
||||
det_arena: t.CVoid | t.CPtr = t.CVoid(
|
||||
stdlib.malloc(self.detection_size), t.CPtr)
|
||||
if det_arena is not None:
|
||||
self._det_arena = det_arena
|
||||
self._det_records = (t.CUInt64T | t.CPtr)(t.CVoid(det_arena, t.CPtr))
|
||||
self._det_cap = self.detection_size // 16
|
||||
self._det_count = 0
|
||||
@@ -657,10 +659,22 @@ class MemBuddy(MemManager):
|
||||
tail_d: t.CUInt64T = base_ret_d + 2 + t.CUInt64T(size)
|
||||
m_t_d: t.CUInt16T | t.CPtr = (t.CUInt16T | t.CPtr)(t.CVoid(tail_d, t.CPtr))
|
||||
m_t_d[0] = t.CUInt16T(MEMBUDDY_DET_MARKER)
|
||||
if self._det_records is not None and self._det_count < self._det_cap:
|
||||
self._det_records[self._det_count * 2] = base_ret_d + 2
|
||||
self._det_records[self._det_count * 2 + 1] = t.CUInt64T(size)
|
||||
self._det_count += 1
|
||||
if self._det_records is not None:
|
||||
if self._det_count >= self._det_cap:
|
||||
# 记录表满:stdlib.realloc 翻倍扩容(防 is_alive/_det_probe
|
||||
# 因容量耗尽漏检——SlotsBugTest 编译 includes 超 2M 次 alloc,
|
||||
# 满后新块无记录 → is_alive 误报"读取悬空")
|
||||
new_cap: t.CSizeT = self._det_cap * 2
|
||||
new_rec: t.CVoid | t.CPtr = t.CVoid(
|
||||
stdlib.realloc(self._det_arena, new_cap * 16), t.CPtr)
|
||||
if new_rec is not None:
|
||||
self._det_arena = new_rec
|
||||
self._det_records = (t.CUInt64T | t.CPtr)(t.CVoid(new_rec, t.CPtr))
|
||||
self._det_cap = new_cap
|
||||
if self._det_count < self._det_cap:
|
||||
self._det_records[self._det_count * 2] = base_ret_d + 2
|
||||
self._det_records[self._det_count * 2 + 1] = t.CUInt64T(size)
|
||||
self._det_count += 1
|
||||
self._det_probe()
|
||||
result = t.CVoid(base_ret_d + 2, t.CPtr)
|
||||
if result is None:
|
||||
|
||||
Reference in new issue
Block a user