Disable usage of AddressSanitizer pending a per-allocator review

It has been discovered that AddressSanitizer does not keep a 1:1 mapping
of which bytes are poisoned and which are not. This can cause issues for
allocations less than 8 bytes and where addresses straddle 8-byte
boundaries.

See the following link for more information:

https://github.com/google/sanitizers/wiki/AddressSanitizerAlgorithm#mapping
This commit is contained in:
Feoramund
2025-06-15 15:06:28 -04:00
parent 0b2cf9a4ca
commit efba9a1fb7
6 changed files with 108 additions and 92 deletions
+12 -12
View File
@@ -3,7 +3,7 @@ package mem_virtual
import "core:mem"
import "core:sync"
import "base:sanitizer"
// import "base:sanitizer"
Arena_Kind :: enum uint {
Growing = 0, // Chained memory blocks (singly linked list).
@@ -55,7 +55,7 @@ arena_init_growing :: proc(arena: ^Arena, reserved: uint = DEFAULT_ARENA_GROWING
if arena.minimum_block_size == 0 {
arena.minimum_block_size = reserved
}
sanitizer.address_poison(arena.curr_block.base[:arena.curr_block.committed])
// sanitizer.address_poison(arena.curr_block.base[:arena.curr_block.committed])
return
}
@@ -68,7 +68,7 @@ arena_init_static :: proc(arena: ^Arena, reserved: uint = DEFAULT_ARENA_STATIC_R
arena.curr_block = memory_block_alloc(commit_size, reserved, {}) or_return
arena.total_used = 0
arena.total_reserved = arena.curr_block.reserved
sanitizer.address_poison(arena.curr_block.base[:arena.curr_block.committed])
// sanitizer.address_poison(arena.curr_block.base[:arena.curr_block.committed])
return
}
@@ -82,7 +82,7 @@ arena_init_buffer :: proc(arena: ^Arena, buffer: []byte) -> (err: Allocator_Erro
arena.kind = .Buffer
sanitizer.address_poison(buffer[:])
// sanitizer.address_poison(buffer[:])
block_base := raw_data(buffer)
block := (^Memory_Block)(block_base)
@@ -163,7 +163,7 @@ arena_alloc :: proc(arena: ^Arena, size: uint, alignment: uint, loc := #caller_l
arena.total_used = arena.curr_block.used
}
sanitizer.address_unpoison(data)
// sanitizer.address_unpoison(data)
return
}
@@ -182,7 +182,7 @@ arena_static_reset_to :: proc(arena: ^Arena, pos: uint, loc := #caller_location)
mem.zero_slice(arena.curr_block.base[arena.curr_block.used:][:prev_pos-pos])
}
arena.total_used = arena.curr_block.used
sanitizer.address_poison(arena.curr_block.base[:arena.curr_block.committed])
// sanitizer.address_poison(arena.curr_block.base[:arena.curr_block.committed])
return true
} else if pos == 0 {
arena.total_used = 0
@@ -200,7 +200,7 @@ arena_growing_free_last_memory_block :: proc(arena: ^Arena, loc := #caller_locat
arena.total_reserved -= free_block.reserved
arena.curr_block = free_block.prev
sanitizer.address_poison(free_block.base[:free_block.committed])
// sanitizer.address_poison(free_block.base[:free_block.committed])
memory_block_dealloc(free_block)
}
}
@@ -219,9 +219,9 @@ arena_free_all :: proc(arena: ^Arena, loc := #caller_location) {
if arena.curr_block != nil {
curr_block_used := int(arena.curr_block.used)
arena.curr_block.used = 0
sanitizer.address_unpoison(arena.curr_block.base[:curr_block_used])
// sanitizer.address_unpoison(arena.curr_block.base[:curr_block_used])
mem.zero(arena.curr_block.base, curr_block_used)
sanitizer.address_poison(arena.curr_block.base[:arena.curr_block.committed])
// sanitizer.address_poison(arena.curr_block.base[:arena.curr_block.committed])
}
arena.total_used = 0
case .Static, .Buffer:
@@ -349,7 +349,7 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
if size < old_size {
// shrink data in-place
data = old_data[:size]
sanitizer.address_poison(old_data[size:old_size])
// sanitizer.address_poison(old_data[size:old_size])
return
}
@@ -363,7 +363,7 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
_ = alloc_from_memory_block(block, new_end - old_end, 1, default_commit_size=arena.default_commit_size) or_return
arena.total_used += block.used - prev_used
data = block.base[start:new_end]
sanitizer.address_unpoison(data)
// sanitizer.address_unpoison(data)
return
}
}
@@ -374,7 +374,7 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode,
return
}
copy(new_memory, old_data[:old_size])
sanitizer.address_poison(old_data[:old_size])
// sanitizer.address_poison(old_data[:old_size])
return new_memory, nil
case .Query_Features:
set := (^mem.Allocator_Mode_Set)(old_memory)
+5 -5
View File
@@ -2,7 +2,7 @@ package mem_virtual
import "core:mem"
import "base:intrinsics"
import "base:sanitizer"
// import "base:sanitizer"
import "base:runtime"
_ :: runtime
@@ -22,7 +22,7 @@ reserve :: proc "contextless" (size: uint) -> (data: []byte, err: Allocator_Erro
@(no_sanitize_address)
commit :: proc "contextless" (data: rawptr, size: uint) -> Allocator_Error {
sanitizer.address_unpoison(data, size)
// sanitizer.address_unpoison(data, size)
return _commit(data, size)
}
@@ -35,13 +35,13 @@ reserve_and_commit :: proc "contextless" (size: uint) -> (data: []byte, err: All
@(no_sanitize_address)
decommit :: proc "contextless" (data: rawptr, size: uint) {
sanitizer.address_poison(data, size)
// sanitizer.address_poison(data, size)
_decommit(data, size)
}
@(no_sanitize_address)
release :: proc "contextless" (data: rawptr, size: uint) {
sanitizer.address_unpoison(data, size)
// sanitizer.address_unpoison(data, size)
_release(data, size)
}
@@ -179,7 +179,7 @@ alloc_from_memory_block :: proc(block: ^Memory_Block, min_size, alignment: uint,
data = block.base[block.used+alignment_offset:][:min_size]
block.used += size
sanitizer.address_unpoison(data)
// sanitizer.address_unpoison(data)
return
}