diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2025-06-05 00:51:35 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2025-06-05 09:59:02 -0400 |
| commit | 053b5ab41a7747f83b25906ea46446eba8c6ea9a (patch) | |
| tree | d244e72365d1c222182dad6d8f21c68d6ef89536 /pkmem.h | |
| parent | 54c3fbaaf3e10c4b9aa15f3d32864b0ebfc06eee (diff) | |
pkmem: handle accessing uninitialized debug blocks
Diffstat (limited to 'pkmem.h')
| -rw-r--r-- | pkmem.h | 26 |
1 files changed, 23 insertions, 3 deletions
@@ -251,6 +251,8 @@ pk_mem_bucket_create(const char* description, int64_t sz, enum PK_MEMBUCKET_FLAG bkt->debug_head_r = 0; bkt->debug_block_capacity = 128; bkt->debug_blocks = (struct pk_memblock*)aligned_alloc(alignof(struct pk_memblock), sizeof(struct pk_memblock) * 128); + bkt->debug_blocks[0].ptr = NULL; + bkt->debug_blocks[0].size = 0; #endif return bkt; @@ -269,7 +271,7 @@ pk_mem_bucket_destroy(struct pk_membucket* bkt) void pk_mem_bucket_reset(struct pk_membucket* bkt) { - if (PK_HAS_FLAG(bkt->flags, PK_MEMBUCKET_FLAG_TRANSIENT) == true) { + if (PK_HAS_FLAG(bkt->flags, PK_MEMBUCKET_FLAG_TRANSIENT) == false) { PK_LOG_ERR("WARNING: pk_bucket_reset called on non-transient pk_membucket\n"); } bkt->head = 0; @@ -288,6 +290,8 @@ pk_mem_bucket_reset(struct pk_membucket* bkt) #ifdef PK_MEMORY_DEBUGGER bkt->debug_head_l = 0; bkt->debug_head_r = 0; + bkt->debug_blocks[0].ptr = NULL; + bkt->debug_blocks[0].size = 0; #endif } @@ -330,6 +334,7 @@ pk_bucket_insert_block(struct pk_membucket* bkt, const struct pk_memblock* block break; } } + assert(old_block != NULL); if (i == 0 && old_block != NULL) { *old_block = *block; } else { @@ -414,20 +419,32 @@ pk_new_bkt(size_t sz, size_t alignment, struct pk_membucket* bkt) if (bkt->debug_head_r == bkt->debug_block_capacity) { struct pk_memblock *debug_blocks; - debug_blocks = (struct pk_memblock*)aligned_alloc(alignof(struct pk_memblock), sizeof(struct pk_memblock) * bkt->debug_block_capacity + 128); + debug_blocks = (struct pk_memblock*)aligned_alloc(alignof(struct pk_memblock), sizeof(struct pk_memblock) * (bkt->debug_block_capacity + 128)); assert(debug_blocks != NULL); memcpy(debug_blocks, bkt->debug_blocks, sizeof(struct pk_memblock) * bkt->debug_block_capacity); free(bkt->debug_blocks); bkt->debug_blocks = debug_blocks; + bkt->debug_block_capacity += 128; } + bkt->debug_blocks[bkt->debug_head_r].ptr = NULL; + bkt->debug_blocks[bkt->debug_head_r].size = 0; + } else { + // 2025-06-05 JCB + // This intentionally looks at debug_head_r, which could potentially + // be uninitialized. I added some logic elsewhere to ensure that + // whenever debug_head_r is incremented, we set the related block + // to NULL/0 so that this will catch size==0. + // I was experiencing an issue where in testing it was initialized to + // NULL/0, but then in a client application it was garbage data. for (ii = bkt->debug_head_l+1; ii <= bkt->debug_head_r; ++ii) { if (bkt->debug_blocks[ii].size == 0) { bkt->debug_head_l = ii; break; } } + assert(ii != bkt->debug_head_r+1); } assert(bkt->debug_head_l <= bkt->debug_head_r); bkt->debug_blocks[i].data = (char*)data; @@ -516,7 +533,10 @@ pk_delete_bkt(const void* ptr, size_t sz, struct pk_membucket* bkt) if (i <= bkt->debug_head_l) { bkt->debug_head_l = i-1; } - if (i == bkt->debug_head_r) { + if (i == bkt->debug_head_r+1) { + if (bkt->debug_head_l == bkt->debug_head_r) { + bkt->debug_head_l--; + } bkt->debug_head_r--; } assert(bkt->debug_head_l <= bkt->debug_head_r); |
