fine-grained valgrind support (warning: slow)

This commit is contained in:
Peter McGoron 2024-07-14 01:43:56 -04:00
parent 2effa0f98c
commit 7731d1136b
2 changed files with 22 additions and 4 deletions

View File

@ -9,9 +9,6 @@ CFLAGS=-Wall -std=c89 -Werror -pedantic -fPIC -g -Iinclude -I. -Wno-unused-funct
tests: string_tests htable_tests tests: string_tests htable_tests
with_valgrind:
make EXTRACFLAGS=-DUNS_VALGRIND
COMMON_OBJECTS=uns.o COMMON_OBJECTS=uns.o
uns.o: uns.c include/uns.h uns.o: uns.c include/uns.h

View File

@ -16,14 +16,21 @@
*/ */
#include <stdio.h> #include <stdio.h>
/* XXX: Currently valgrind marks the header region as valid for all
* functions, when it should only be valid inside allocator calls.
*/
#ifdef UNS_VALGRIND #ifdef UNS_VALGRIND
# include <valgrind/valgrind.h> # include <valgrind/valgrind.h>
# include <valgrind/memcheck.h>
# define REDZONE 16 # define REDZONE 16
#else #else
# define REDZONE 0 # define REDZONE 0
# define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed) (void)0 # define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed) (void)0
# define VALGRIND_DESTROY_MEMPOOL(pool) (void)0 # define VALGRIND_DESTROY_MEMPOOL(pool) (void)0
# define VALGRIND_MEMPOOL_ALLOC(pool, ptr, siz) (void)0 # define VALGRIND_MEMPOOL_ALLOC(pool, ptr, siz) (void)0
# define VALGRIND_CHECK_MEM_IS_ADDRESSABLE(p, len) 0
# define VALGRIND_MAKE_MEM_DEFINED(p, len) (void)0
# define VALGRIND_MAKE_MEM_NOACCESS(p, len) (void)0
#endif #endif
#include <stdlib.h> #include <stdlib.h>
@ -134,7 +141,13 @@ static void hdr_read(struct hdr *hdr, unsigned char *p)
assert(hdr); assert(hdr);
assert(p); assert(p);
if (VALGRIND_CHECK_MEM_IS_ADDRESSABLE(p + HDR_LEN, 1) != 0)
abort();
VALGRIND_MAKE_MEM_DEFINED(p, HDR_LEN);
memcpy(&hdr->len, p, HDR_LEN); memcpy(&hdr->len, p, HDR_LEN);
VALGRIND_MAKE_MEM_NOACCESS(p, HDR_LEN);
if (hdr->len < 0) { if (hdr->len < 0) {
hdr->typ = RECORD; hdr->typ = RECORD;
hdr->len = -hdr->len; hdr->len = -hdr->len;
@ -144,6 +157,9 @@ static void hdr_read(struct hdr *hdr, unsigned char *p)
} else { } else {
hdr->typ = REGION; hdr->typ = REGION;
} }
if (VALGRIND_CHECK_MEM_IS_ADDRESSABLE(p + HDR_LEN, hdr->len) != 0)
abort();
} }
/** Destructure header from a pointer to a region. /** Destructure header from a pointer to a region.
@ -178,7 +194,12 @@ static void hdr_write_direct(struct hdr *hdr, unsigned char *p)
case RECORD: s = -hdr->len; break; case RECORD: s = -hdr->len; break;
} }
if (VALGRIND_CHECK_MEM_IS_ADDRESSABLE(p + HDR_LEN, hdr->len) != 0)
abort();
VALGRIND_MAKE_MEM_DEFINED(p, HDR_LEN);
memcpy(p, &s, HDR_LEN); memcpy(p, &s, HDR_LEN);
VALGRIND_MAKE_MEM_NOACCESS(p, HDR_LEN);
} }
/** Write to the header of a region. /** Write to the header of a region.
@ -225,7 +246,7 @@ static void *raw_alloc(struct ctx *ctx, uns_sword len, int is_record)
assert(enough_space(ctx, len)); assert(enough_space(ctx, len));
p = ctx->tospace_alloc; p = ctx->tospace_alloc;
VALGRIND_MEMPOOL_ALLOC(ctx->tospace, p, len); VALGRIND_MEMPOOL_ALLOC(ctx->tospace, p + HDR_LEN, len - HDR_LEN);
hdr_write_direct(&hdr, p); hdr_write_direct(&hdr, p);
ctx->tospace_alloc += len + REDZONE; ctx->tospace_alloc += len + REDZONE;