Opened 13 years ago
Closed 12 years ago
#8123 closed bug (fixed)
PANIC: object_cache: tried to free invalid object pointer
Reported by: | beos_zealot | Owned by: | axeld |
---|---|---|---|
Priority: | normal | Milestone: | R1 |
Component: | System/Kernel | Version: | R1/Development |
Keywords: | slab deadbeef | Cc: | |
Blocked By: | Blocking: | ||
Platform: | x86 |
Description
Updated local Haiku SVN repository and started building anyboot image:
jam -j2 -q @anyboot
after several minutes of building I got PANIC (attached pic: PANIC - object_cache - tried to free invalid object pointer.jpg)
Haiku gcc4 hrev43224
Intel Core 2
2 GB RAM (swap on)
Attachments (4)
Change History (11)
by , 13 years ago
Attachment: | PANIC - object_cache - tried to free invalid object pointer.jpg added |
---|
comment:1 by , 13 years ago
Keywords: | slab deadbeef added; PANIC object_cache tried to free invalid object pointer removed |
---|---|
Owner: | changed from | to
Status: | new → assigned |
by , 13 years ago
Attachment: | deadbeef.jpg added |
---|
comment:2 by , 13 years ago
Second time encountered same PANIC (attached image: deadbeef.jpg) while building Haiku anyboot image.
Haiku gcc4 hrev43751
by , 12 years ago
Attachment: | reproduce.patch added |
---|
by , 12 years ago
Attachment: | check_unused.patch added |
---|
comment:3 by , 12 years ago
patch: | 0 → 1 |
---|
comment:4 by , 12 years ago
I've encountered this as well, or at least something very similar. The problem is in the block cache, when a cached_block with is_dirty = true, discard = false, transaction = NULL and ref_count = 0 is added to the unused_blocks list. This can happen when a transaction is aborted, or when the block cache is used without a transaction.
When RemoveUnusedBlocks() free's a block with these properties, it will call BlockWriter::WriteBlock(), which eventually leads to the block being re-added to the list in _BlockDone(). When execution returns to RemoveUnusedBlocks(), the block is free'd. So at this point we have a free'd block in the unused_blocks list, waiting to cause a crash.
reproduce.patch contains code to reproduce the crash, and check_unused.patch is my attempt at fixing the problem. As far as I can tell, cached_block::unused basically means "is this block in unused_list", so checking for that tells _BlockDone() that it was called from RemoveUnusedBlocks() and should not re-add the block.
comment:5 by , 12 years ago
Owner: | changed from | to
---|
comment:6 by , 12 years ago
Great findings! Actually, your patch is not entirely correct, even though it helps ignoring the problem: when a block is without a transaction, it mustn't be dirty anymore.
It looks both cache_abort_transaction(), and cache_abort_sub_transaction() don't deal with this correctly. The latter even has some more problems, as it does not reset the transaction field when it should.
I'm currently working on a revised patch. Thanks a lot in any case!
comment:7 by , 12 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
Maybe mmlr is interested in looking into that. The stack trace suggests that the magazine that is being emptied was already freed.