Fix memory issues because of pointer to item in dynamic array, add clang-cl, add address sanitizer stuff

This commit is contained in:
Krzosa Karol
2024-08-05 10:44:00 +02:00
parent 10f0d7dca2
commit 55465ad6de
14 changed files with 141 additions and 104 deletions

View File

@@ -442,6 +442,12 @@ void BoundedAdd(Array<T> *arr, T item) {
if (arr->len + 1 <= arr->cap) arr->data[arr->len++] = item;
}
template <class T>
void BoundedAddError(Array<T> *arr, T item) {
Assert(arr->len + 1 <= arr->cap);
if (arr->len + 1 <= arr->cap) arr->data[arr->len++] = item;
}
template <class T>
T *Alloc(Array<T> *arr, T item) {
TryGrowing(arr);
@@ -790,7 +796,7 @@ int64_t CreateWidecharFromChar(wchar_t *buffer, int64_t buffer_size, char *i
inline bool operator==(String a, String b) { return AreEqual(a, b); }
inline bool operator!=(String a, String b) { return !AreEqual(a, b); }
#if defined(__has_attribute)
#if defined(__has_attribute) && defined(_MSC_VER) && !defined(__clang__)
#if __has_attribute(format)
#define PrintfFormatAttribute(fmt, va) __attribute__((format(printf, fmt, va)))
#endif
@@ -1598,6 +1604,22 @@ String ToString(Allocator allocator, wchar_t *wstring) {
return result;
}
#if DEBUG_BUILD
#define USE_ADDRESS_SANITIZER
#endif
#if defined(USE_ADDRESS_SANITIZER)
#include <sanitizer/asan_interface.h>
#endif
#if !defined(ASAN_POISON_MEMORY_REGION)
#define MA_ASAN_POISON_MEMORY_REGION(addr, size) ((void)(addr), (void)(size))
#define MA_ASAN_UNPOISON_MEMORY_REGION(addr, size) ((void)(addr), (void)(size))
#else
#define MA_ASAN_POISON_MEMORY_REGION(addr, size) ASAN_POISON_MEMORY_REGION(addr, size)
#define MA_ASAN_UNPOISON_MEMORY_REGION(addr, size) ASAN_UNPOISON_MEMORY_REGION(addr, size)
#endif
void InitArena(Arena *arena, size_t reserve) {
reserve = AlignUp(reserve, PAGE_SIZE);
arena->align = DEFAULT_ALIGNMENT;
@@ -1647,7 +1669,6 @@ void *PushSize(Arena *arena, size_t size) {
if (arena->align) {
align_offset = GetAlignOffset((uintptr_t)arena->data + arena->len, arena->align);
}
size_t align_len = arena->len + align_offset;
size_t size_with_alignment = size + align_offset;
size_t new_len = arena->len + size_with_alignment;
if (new_len > arena->commit) {
@@ -1656,7 +1677,10 @@ void *PushSize(Arena *arena, size_t size) {
size_t to_commit_clamped = ClampTop(to_commit, arena->reserve);
if (to_commit_clamped > 0) {
bool success = VCommit(arena->data + arena->commit, to_commit_clamped);
if (success) arena->commit += to_commit_clamped;
if (success) {
MA_ASAN_UNPOISON_MEMORY_REGION(arena->data + arena->commit, to_commit_clamped);
arena->commit += to_commit_clamped;
}
}
if (new_len > arena->commit) {
return NULL;
@@ -1664,6 +1688,7 @@ void *PushSize(Arena *arena, size_t size) {
}
uint8_t *result = arena->data + arena->len + align_offset;
arena->len = new_len;
MA_ASAN_UNPOISON_MEMORY_REGION(result, size);
return (void *)result;
}
@@ -1674,6 +1699,18 @@ void Release(Arena *arena) {
if (zero_memory) MemoryZero(arena, sizeof(Arena));
}
void PopToPos(Arena *arena, size_t pos) {
// base_len is used for bootstraping arenas, it denotes the
// space occupied by the arena. If len is smaller then base_len then
// we start to overwrite the arena itself - pure barbarism.
Assert(arena->len >= arena->base_len);
pos = Clamp(pos, arena->base_len, arena->len);
size_t size = arena->len - pos;
arena->len = pos;
MA_ASAN_POISON_MEMORY_REGION(arena->data + arena->len, size);
}
void *ArenaAllocatorProc(void *object, int kind, void *p, size_t size) {
if (kind == AllocatorKind_Allocate) {
return PushSize((Arena *)object, size);

View File

@@ -52,20 +52,20 @@ Rect2I ToRect2I(Rect2 r) { return {ToVec2I(r.min), ToVec2I(r.max)}; }
Rect2 ToRect2(Rect2I r) { return {ToVec2(r.min), ToVec2(r.max)}; }
// clang-format off
Rect2 operator-(Rect2 r, Rect2 value) { return { r.min.x - value.min.x, r.min.y - value.min.y, r.max.x - value.max.x, r.max.y - value.max.y }; }
Rect2 operator+(Rect2 r, Rect2 value) { return { r.min.x + value.min.x, r.min.y + value.min.y, r.max.x + value.max.x, r.max.y + value.max.y }; }
Rect2 operator*(Rect2 r, Rect2 value) { return { r.min.x * value.min.x, r.min.y * value.min.y, r.max.x * value.max.x, r.max.y * value.max.y }; }
Rect2 operator/(Rect2 r, Rect2 value) { return { r.min.x / value.min.x, r.min.y / value.min.y, r.max.x / value.max.x, r.max.y / value.max.y }; }
Rect2 operator-(Rect2 r, Rect2 value) { return { {r.min.x - value.min.x, r.min.y - value.min.y}, {r.max.x - value.max.x, r.max.y - value.max.y} }; }
Rect2 operator+(Rect2 r, Rect2 value) { return { {r.min.x + value.min.x, r.min.y + value.min.y}, {r.max.x + value.max.x, r.max.y + value.max.y} }; }
Rect2 operator*(Rect2 r, Rect2 value) { return { {r.min.x * value.min.x, r.min.y * value.min.y}, {r.max.x * value.max.x, r.max.y * value.max.y} }; }
Rect2 operator/(Rect2 r, Rect2 value) { return { {r.min.x / value.min.x, r.min.y / value.min.y}, {r.max.x / value.max.x, r.max.y / value.max.y} }; }
Rect2 operator-(Rect2 r, Vec2 value) { return { r.min.x - value.x, r.min.y - value.y, r.max.x - value.x, r.max.y - value.y }; }
Rect2 operator+(Rect2 r, Vec2 value) { return { r.min.x + value.x, r.min.y + value.y, r.max.x + value.x, r.max.y + value.y }; }
Rect2 operator*(Rect2 r, Vec2 value) { return { r.min.x * value.x, r.min.y * value.y, r.max.x * value.x, r.max.y * value.y }; }
Rect2 operator/(Rect2 r, Vec2 value) { return { r.min.x / value.x, r.min.y / value.y, r.max.x / value.x, r.max.y / value.y }; }
Rect2 operator-(Rect2 r, Vec2 value) { return { {r.min.x - value.x, r.min.y - value.y}, {r.max.x - value.x, r.max.y - value.y} }; }
Rect2 operator+(Rect2 r, Vec2 value) { return { {r.min.x + value.x, r.min.y + value.y}, {r.max.x + value.x, r.max.y + value.y} }; }
Rect2 operator*(Rect2 r, Vec2 value) { return { {r.min.x * value.x, r.min.y * value.y}, {r.max.x * value.x, r.max.y * value.y} }; }
Rect2 operator/(Rect2 r, Vec2 value) { return { {r.min.x / value.x, r.min.y / value.y}, {r.max.x / value.x, r.max.y / value.y} }; }
Rect2 operator-(Rect2 r, float value) { return { r.min.x - value, r.min.y - value, r.max.x - value, r.max.y - value }; }
Rect2 operator+(Rect2 r, float value) { return { r.min.x + value, r.min.y + value, r.max.x + value, r.max.y + value }; }
Rect2 operator*(Rect2 r, float value) { return { r.min.x * value, r.min.y * value, r.max.x * value, r.max.y * value }; }
Rect2 operator/(Rect2 r, float value) { return { r.min.x / value, r.min.y / value, r.max.x / value, r.max.y / value }; }
Rect2 operator-(Rect2 r, float value) { return { {r.min.x - value, r.min.y - value}, {r.max.x - value, r.max.y - value} }; }
Rect2 operator+(Rect2 r, float value) { return { {r.min.x + value, r.min.y + value}, {r.max.x + value, r.max.y + value} }; }
Rect2 operator*(Rect2 r, float value) { return { {r.min.x * value, r.min.y * value}, {r.max.x * value, r.max.y * value} }; }
Rect2 operator/(Rect2 r, float value) { return { {r.min.x / value, r.min.y / value}, {r.max.x / value, r.max.y / value} }; }
Rect2 operator-=(Rect2 &r, Rect2 value) { r = r - value; return r; }
Rect2 operator+=(Rect2 &r, Rect2 value) { r = r + value; return r; }

View File

@@ -24,20 +24,20 @@ Vec2I GetSize(Rect2I r) {
}
// clang-format off
Rect2I operator-(Rect2I r, Rect2I value) { return { r.min.x - value.min.x, r.min.y - value.min.y, r.max.x - value.max.x, r.max.y - value.max.y }; }
Rect2I operator+(Rect2I r, Rect2I value) { return { r.min.x + value.min.x, r.min.y + value.min.y, r.max.x + value.max.x, r.max.y + value.max.y }; }
Rect2I operator*(Rect2I r, Rect2I value) { return { r.min.x * value.min.x, r.min.y * value.min.y, r.max.x * value.max.x, r.max.y * value.max.y }; }
Rect2I operator/(Rect2I r, Rect2I value) { return { r.min.x / value.min.x, r.min.y / value.min.y, r.max.x / value.max.x, r.max.y / value.max.y }; }
Rect2I operator-(Rect2I r, Rect2I value) { return { {r.min.x - value.min.x, r.min.y - value.min.y}, {r.max.x - value.max.x, r.max.y - value.max.y} }; }
Rect2I operator+(Rect2I r, Rect2I value) { return { {r.min.x + value.min.x, r.min.y + value.min.y}, {r.max.x + value.max.x, r.max.y + value.max.y} }; }
Rect2I operator*(Rect2I r, Rect2I value) { return { {r.min.x * value.min.x, r.min.y * value.min.y}, {r.max.x * value.max.x, r.max.y * value.max.y} }; }
Rect2I operator/(Rect2I r, Rect2I value) { return { {r.min.x / value.min.x, r.min.y / value.min.y}, {r.max.x / value.max.x, r.max.y / value.max.y} }; }
Rect2I operator-(Rect2I r, Vec2I value) { return { r.min.x - value.x, r.min.y - value.y, r.max.x - value.x, r.max.y - value.y }; }
Rect2I operator+(Rect2I r, Vec2I value) { return { r.min.x + value.x, r.min.y + value.y, r.max.x + value.x, r.max.y + value.y }; }
Rect2I operator*(Rect2I r, Vec2I value) { return { r.min.x * value.x, r.min.y * value.y, r.max.x * value.x, r.max.y * value.y }; }
Rect2I operator/(Rect2I r, Vec2I value) { return { r.min.x / value.x, r.min.y / value.y, r.max.x / value.x, r.max.y / value.y }; }
Rect2I operator-(Rect2I r, Vec2I value) { return { {r.min.x - value.x, r.min.y - value.y}, {r.max.x - value.x, r.max.y - value.y} }; }
Rect2I operator+(Rect2I r, Vec2I value) { return { {r.min.x + value.x, r.min.y + value.y}, {r.max.x + value.x, r.max.y + value.y} }; }
Rect2I operator*(Rect2I r, Vec2I value) { return { {r.min.x * value.x, r.min.y * value.y}, {r.max.x * value.x, r.max.y * value.y} }; }
Rect2I operator/(Rect2I r, Vec2I value) { return { {r.min.x / value.x, r.min.y / value.y}, {r.max.x / value.x, r.max.y / value.y} }; }
Rect2I operator-(Rect2I r, Int value) { return { r.min.x - value, r.min.y - value, r.max.x - value, r.max.y - value }; }
Rect2I operator+(Rect2I r, Int value) { return { r.min.x + value, r.min.y + value, r.max.x + value, r.max.y + value }; }
Rect2I operator*(Rect2I r, Int value) { return { r.min.x * value, r.min.y * value, r.max.x * value, r.max.y * value }; }
Rect2I operator/(Rect2I r, Int value) { return { r.min.x / value, r.min.y / value, r.max.x / value, r.max.y / value }; }
Rect2I operator-(Rect2I r, Int value) { return { {r.min.x - value, r.min.y - value}, {r.max.x - value, r.max.y - value} }; }
Rect2I operator+(Rect2I r, Int value) { return { {r.min.x + value, r.min.y + value}, {r.max.x + value, r.max.y + value} }; }
Rect2I operator*(Rect2I r, Int value) { return { {r.min.x * value, r.min.y * value}, {r.max.x * value, r.max.y * value} }; }
Rect2I operator/(Rect2I r, Int value) { return { {r.min.x / value, r.min.y / value}, {r.max.x / value, r.max.y / value} }; }
Rect2I operator-=(Rect2I &r, Rect2I value) { r = r - value; return r; }
Rect2I operator+=(Rect2I &r, Rect2I value) { r = r + value; return r; }