Test add address sanitizer to arena
This commit is contained in:
2
build.sh
2
build.sh
@@ -1,3 +1,3 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
gcc -o bld code/build_main.cpp -g
|
gcc -o bld code/build_main.cpp -g
|
||||||
./bld
|
./bld
|
||||||
|
|||||||
@@ -20,13 +20,13 @@ int CompileFiles(Strs cc, Strs files) {
|
|||||||
Str exe = FilenameWithoutExt(files[0]);
|
Str exe = FilenameWithoutExt(files[0]);
|
||||||
Str filestr = Merge(files);
|
Str filestr = Merge(files);
|
||||||
if (cc == "gcc") {
|
if (cc == "gcc") {
|
||||||
result = OS_SystemF("g++ -o %Q.exe %Q -g -Wno-write-strings", exe, filestr);
|
result = OS_SystemF("g++ -o %Q.exe %Q -g -Wno-write-strings -fsanitize=address", exe, filestr);
|
||||||
}
|
}
|
||||||
else if (cc == "clang") {
|
else if (cc == "clang") {
|
||||||
result = OS_SystemF("clang++ -std=c++11 -o %Q.exe %Q -g -Wno-writable-strings", exe, filestr);
|
result = OS_SystemF("clang++ -std=c++11 -o %Q.exe %Q -g -Wno-writable-strings -fsanitize=address", exe, filestr);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = OS_SystemF("cl -Fe:%Q.exe %Q -Zi -WX -W3 -wd4200 -diagnostics:column -nologo -D_CRT_SECURE_NO_WARNINGS", exe, filestr);
|
result = OS_SystemF("cl -Fe:%Q.exe %Q -Zi -WX -W3 -wd4200 -diagnostics:column -nologo -D_CRT_SECURE_NO_WARNINGS -fsanitize=address -RTC1", exe, filestr);
|
||||||
}
|
}
|
||||||
if (result == 0) result = OS_SystemF(IF_WINDOWS_ELSE("", "./") "%Q.exe", exe);
|
if (result == 0) result = OS_SystemF(IF_WINDOWS_ELSE("", "./") "%Q.exe", exe);
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
38
code/arena.c
38
code/arena.c
@@ -33,6 +33,40 @@ MA_API void MA_MemoryCopy(void *dst, void *src, size_t size) {
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Marks memory region [addr, addr+size) as unaddressable.
|
||||||
|
// This memory must be previously allocated by the user program. Accessing
|
||||||
|
// addresses in this region from instrumented code is forbidden until
|
||||||
|
// this region is unpoisoned. This function is not guaranteed to poison
|
||||||
|
// the whole region - it may poison only subregion of [addr, addr+size) due
|
||||||
|
// to ASan alignment restrictions.
|
||||||
|
// Method is NOT thread-safe in the sense that no two threads can
|
||||||
|
// (un)poison memory in the same memory region simultaneously.
|
||||||
|
void __asan_poison_memory_region(void const volatile *addr, size_t size);
|
||||||
|
// Marks memory region [addr, addr+size) as addressable.
|
||||||
|
// This memory must be previously allocated by the user program. Accessing
|
||||||
|
// addresses in this region is allowed until this region is poisoned again.
|
||||||
|
// This function may unpoison a superregion of [addr, addr+size) due to
|
||||||
|
// ASan alignment restrictions.
|
||||||
|
// Method is NOT thread-safe in the sense that no two threads can
|
||||||
|
// (un)poison memory in the same memory region simultaneously.
|
||||||
|
void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
|
||||||
|
|
||||||
|
// User code should use macros instead of functions.
|
||||||
|
#if defined(__clang__)
|
||||||
|
#if defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer)
|
||||||
|
#define ASAN_POISON_MEMORY_REGION(addr, size) \
|
||||||
|
__asan_poison_memory_region((addr), (size))
|
||||||
|
#define ASAN_UNPOISON_MEMORY_REGION(addr, size) \
|
||||||
|
__asan_unpoison_memory_region((addr), (size))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifndef ASAN_POISON_MEMORY_REGION
|
||||||
|
#define ASAN_POISON_MEMORY_REGION(addr, size) \
|
||||||
|
((void)(addr), (void)(size))
|
||||||
|
#define ASAN_UNPOISON_MEMORY_REGION(addr, size) \
|
||||||
|
((void)(addr), (void)(size))
|
||||||
|
#endif
|
||||||
|
|
||||||
MA_API size_t MA_GetAlignOffset(size_t size, size_t align) {
|
MA_API size_t MA_GetAlignOffset(size_t size, size_t align) {
|
||||||
size_t mask = align - 1;
|
size_t mask = align - 1;
|
||||||
size_t val = size & mask;
|
size_t val = size & mask;
|
||||||
@@ -71,7 +105,9 @@ MA_StaticFunc uint8_t *MV__AdvanceCommit(MV_Memory *m, size_t *commit_size, size
|
|||||||
MA_API void MA_PopToPos(MA_Arena *arena, size_t pos) {
|
MA_API void MA_PopToPos(MA_Arena *arena, size_t pos) {
|
||||||
MA_ASSERT(arena->len >= arena->base_len);
|
MA_ASSERT(arena->len >= arena->base_len);
|
||||||
pos = MA_CLAMP(pos, arena->base_len, arena->len);
|
pos = MA_CLAMP(pos, arena->base_len, arena->len);
|
||||||
|
size_t size = arena->len - pos;
|
||||||
arena->len = pos;
|
arena->len = pos;
|
||||||
|
ASAN_POISON_MEMORY_REGION(arena->memory.data + pos, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
MA_API void MA_PopSize(MA_Arena *arena, size_t size) {
|
MA_API void MA_PopSize(MA_Arena *arena, size_t size) {
|
||||||
@@ -122,6 +158,7 @@ MA_API void *MA_PushSizeNonZeroed(MA_Arena *a, size_t size) {
|
|||||||
uint8_t *result = a->memory.data + aligned_len;
|
uint8_t *result = a->memory.data + aligned_len;
|
||||||
a->len += size_with_alignment;
|
a->len += size_with_alignment;
|
||||||
MA_ASSERT(a->len <= a->memory.commit);
|
MA_ASSERT(a->len <= a->memory.commit);
|
||||||
|
ASAN_UNPOISON_MEMORY_REGION(result, a->len);
|
||||||
return (void *)result;
|
return (void *)result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,6 +170,7 @@ MA_API void *MA_PushSize(MA_Arena *arena, size_t size) {
|
|||||||
|
|
||||||
MA_API void MA_InitEx(MA_Arena *a, size_t reserve) {
|
MA_API void MA_InitEx(MA_Arena *a, size_t reserve) {
|
||||||
a->memory = MV_Reserve(reserve);
|
a->memory = MV_Reserve(reserve);
|
||||||
|
ASAN_POISON_MEMORY_REGION(a->memory.data, a->memory.reserve);
|
||||||
a->alignment = MA_DEFAULT_ALIGNMENT;
|
a->alignment = MA_DEFAULT_ALIGNMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ void TestRemoveForLoop() {
|
|||||||
IO_Assert(array[5] == 6);
|
IO_Assert(array[5] == 6);
|
||||||
IO_Assert(array[3] == 3);
|
IO_Assert(array[3] == 3);
|
||||||
IO_Assert(array.len == 99);
|
IO_Assert(array.len == 99);
|
||||||
|
array.dealloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestBasic() {
|
void TestBasic() {
|
||||||
@@ -114,6 +115,8 @@ void TestCopy() {
|
|||||||
|
|
||||||
IO_Assert(b.cap == b.len && b.len == a.len);
|
IO_Assert(b.cap == b.len && b.len == a.len);
|
||||||
IO_Assert(a.len == c.len && a.cap == c.cap);
|
IO_Assert(a.len == c.len && a.cap == c.cap);
|
||||||
|
|
||||||
|
a.dealloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ void TestStrings() {
|
|||||||
IO_Assert(table.gets("1")->i == 1);
|
IO_Assert(table.gets("1")->i == 1);
|
||||||
IO_Assert(table.gets("2")->i == 2);
|
IO_Assert(table.gets("2")->i == 2);
|
||||||
IO_Assert(table.gets("3")->i == 3);
|
IO_Assert(table.gets("3")->i == 3);
|
||||||
|
table.dealloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
|||||||
Reference in New Issue
Block a user