From: Julian Seward Date: Sun, 23 Jan 2011 20:47:26 +0000 (+0000) Subject: Add a new mempool test resulting from work on #254420, and update X-Git-Tag: svn/VALGRIND_3_7_0~693 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4e4990009a7edf9863d1c8e5ef417748aa8fdffe;p=thirdparty%2Fvalgrind.git Add a new mempool test resulting from work on #254420, and update expected output for an existing test. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11510 --- diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am index 8af36038d8..1b7ea2c842 100644 --- a/memcheck/tests/Makefile.am +++ b/memcheck/tests/Makefile.am @@ -114,6 +114,7 @@ EXTRA_DIST = \ memcmptest.stderr.exp memcmptest.stderr.exp2 \ memcmptest.stdout.exp memcmptest.vgtest \ mempool.stderr.exp mempool.vgtest \ + mempool2.stderr.exp mempool2.vgtest \ metadata.stderr.exp metadata.stdout.exp metadata.vgtest \ mismatches.stderr.exp mismatches.vgtest \ mmaptest.stderr.exp mmaptest.vgtest \ @@ -224,7 +225,7 @@ check_PROGRAMS = \ malloc_free_fill \ malloc_usable malloc1 malloc2 malloc3 manuel1 manuel2 manuel3 \ match-overrun \ - memalign_test memalign2 memcmptest mempool mmaptest \ + memalign_test memalign2 memcmptest mempool mempool2 mmaptest \ mismatches new_override metadata \ nanoleak_supp nanoleak2 new_nothrow \ noisy_child \ diff --git a/memcheck/tests/mempool.stderr.exp b/memcheck/tests/mempool.stderr.exp index 8ca7f0625a..b2ab3b4b49 100644 --- a/memcheck/tests/mempool.stderr.exp +++ b/memcheck/tests/mempool.stderr.exp @@ -1,19 +1,17 @@ Invalid write of size 1 at 0x........: test (mempool.c:130) by 0x........: main (mempool.c:154) - Address 0x........ is 7 bytes inside a block of size 100,000 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: make_pool (mempool.c:44) - by 0x........: test (mempool.c:117) + Address 0x........ is 1 bytes before a block of size 10 client-defined + at 0x........: allocate (mempool.c:105) + by 0x........: test (mempool.c:121) by 0x........: main (mempool.c:154) Invalid write of size 1 at 0x........: test (mempool.c:131) by 0x........: main (mempool.c:154) - Address 0x........ is 18 bytes inside a block of size 100,000 alloc'd - at 0x........: malloc (vg_replace_malloc.c:...) - by 0x........: make_pool (mempool.c:44) - by 0x........: test (mempool.c:117) + Address 0x........ is 0 bytes after a block of size 10 client-defined + at 0x........: allocate (mempool.c:105) + by 0x........: test (mempool.c:121) by 0x........: main (mempool.c:154) Invalid write of size 1 diff --git a/memcheck/tests/mempool2.c b/memcheck/tests/mempool2.c new file mode 100644 index 0000000000..9404ade607 --- /dev/null +++ b/memcheck/tests/mempool2.c @@ -0,0 +1,176 @@ + +// Simplified version of mempool.c, that is more oriented towards +// checking that the description of invalid addresses is correct. + +#include +#include +#include "tests/sys_mman.h" +#include +#include + +#include "../memcheck.h" + +#define SUPERBLOCK_SIZE 100000 +#define REDZONE_SIZE 8 + +typedef struct _level_list +{ + struct _level_list *next; + char *where; + // Padding ensures the struct is the same size on 32-bit and 64-bit + // machines. + char padding[16 - 2*sizeof(char*)]; +} level_list; + +typedef struct _pool { + char *mem; + char *where; + level_list *levels; + int size, left; + // Padding ensures the struct is the same size on 32-bit and 64-bit + // machines. + char padding[24 - 3*sizeof(char*)]; +} pool; + +pool *make_pool( int use_mmap ) +{ + pool *p; + + if (use_mmap) { + p = (pool *)mmap(0, sizeof(pool), PROT_READ|PROT_WRITE|PROT_EXEC, + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + p->where = p->mem = (char *)mmap(NULL, SUPERBLOCK_SIZE, + PROT_READ|PROT_WRITE|PROT_EXEC, + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + } else { + p = (pool *)malloc(sizeof(pool)); + p->where = p->mem = (char *)malloc(SUPERBLOCK_SIZE); + } + + p->size = p->left = SUPERBLOCK_SIZE; + p->levels = NULL; + VALGRIND_MAKE_MEM_NOACCESS(p->where, SUPERBLOCK_SIZE); + return p; +} + +void push(pool *p, int use_mmap ) +{ + level_list *l; + + if (use_mmap) + l = (level_list *)mmap(0, sizeof(level_list), + PROT_READ|PROT_WRITE|PROT_EXEC, + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + else + l = (level_list *)malloc(sizeof(level_list)); + + l->next = p->levels; + l->where = p->where; + VALGRIND_CREATE_MEMPOOL(l->where, REDZONE_SIZE, 0); + p->levels = l; +} + +void pop(pool *p, int use_mmap) +{ + level_list *l = p->levels; + p->levels = l->next; + VALGRIND_DESTROY_MEMPOOL(l->where); + VALGRIND_MAKE_MEM_NOACCESS(l->where, p->where-l->where); + p->where = l->where; + if (use_mmap) + munmap(l, sizeof(level_list)); + else + free(l); +} + +void destroy_pool(pool *p, int use_mmap) +{ + level_list *l = p->levels; + + while(l) { + pop(p, use_mmap); + } + if (use_mmap) { + munmap(p->mem, SUPERBLOCK_SIZE); + munmap(p, sizeof(pool)); + } else { + free(p->mem); + free(p); + } +} + +char *allocate(pool *p, int size) +{ + char *where; + p->left -= size + (REDZONE_SIZE*2); + where = p->where + REDZONE_SIZE; + p->where += size + (REDZONE_SIZE*2); + VALGRIND_MEMPOOL_ALLOC(p->levels->where, where, size); + return where; +} + +//------------------------------------------------------------------------- +// Rest +//------------------------------------------------------------------------- + +void test(void) +{ + char *x1, *x2; + char res = 0; + + // p1 is a malloc-backed pool + pool *p1 = make_pool(0); + + // p2 is a mmap-backed pool + pool *p2 = make_pool(1); + + push(p1, 0); + push(p2, 1); + + x1 = allocate(p1, 10); + x2 = allocate(p2, 20); + + fprintf(stderr, + "\n------ out of range reads in malloc-backed pool ------\n\n"); + res += x1[-1]; + res += x1[10]; + + fprintf(stderr, + "\n------ out of range reads in mmap-backed pool ------\n\n"); + res += x2[-1]; // invalid + res += x2[20]; // invalid + + fprintf(stderr, + "\n------ read free in malloc-backed pool ------\n\n"); + VALGRIND_MEMPOOL_FREE(p1, x1); + res += x1[5]; + + fprintf(stderr, + "\n------ read free in mmap-backed pool ------\n\n"); + VALGRIND_MEMPOOL_FREE(p2, x2); + res += x2[11]; + + fprintf(stderr, + "\n------ double free in malloc-backed pool ------\n\n"); + VALGRIND_MEMPOOL_FREE(p1, x1); + + fprintf(stderr, + "\n------ double free in mmap-backed pool ------\n\n"); + VALGRIND_MEMPOOL_FREE(p2, x2); + + // claim res is used, so gcc can't nuke this all + __asm__ __volatile__("" : : "r"(res)); + + fprintf(stderr, + "\n------ done ------\n\n"); + pop(p1, 0); + pop(p2, 1); + destroy_pool(p1, 0); + destroy_pool(p2, 1); +} + +int main(void) +{ + test(); + return 0; +} diff --git a/memcheck/tests/mempool2.stderr.exp b/memcheck/tests/mempool2.stderr.exp new file mode 100644 index 0000000000..76d84adc7f --- /dev/null +++ b/memcheck/tests/mempool2.stderr.exp @@ -0,0 +1,81 @@ + +------ out of range reads in malloc-backed pool ------ + +Invalid read of size 1 + at 0x........: test (mempool2.c:135) + by 0x........: main (mempool2.c:174) + Address 0x........ is 1 bytes before a block of size 10 client-defined + at 0x........: allocate (mempool2.c:108) + by 0x........: test (mempool2.c:130) + by 0x........: main (mempool2.c:174) + +Invalid read of size 1 + at 0x........: test (mempool2.c:136) + by 0x........: main (mempool2.c:174) + Address 0x........ is 0 bytes after a block of size 10 client-defined + at 0x........: allocate (mempool2.c:108) + by 0x........: test (mempool2.c:130) + by 0x........: main (mempool2.c:174) + + +------ out of range reads in mmap-backed pool ------ + +Invalid read of size 1 + at 0x........: test (mempool2.c:140) + by 0x........: main (mempool2.c:174) + Address 0x........ is 1 bytes before a block of size 20 client-defined + at 0x........: allocate (mempool2.c:108) + by 0x........: test (mempool2.c:131) + by 0x........: main (mempool2.c:174) + +Invalid read of size 1 + at 0x........: test (mempool2.c:141) + by 0x........: main (mempool2.c:174) + Address 0x........ is 0 bytes after a block of size 20 client-defined + at 0x........: allocate (mempool2.c:108) + by 0x........: test (mempool2.c:131) + by 0x........: main (mempool2.c:174) + + +------ read free in malloc-backed pool ------ + +Illegal memory pool address + at 0x........: test (mempool2.c:145) + by 0x........: main (mempool2.c:174) + Address 0x........ is 0 bytes inside a block of size 32 alloc'd + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: make_pool (mempool2.c:46) + by 0x........: test (mempool2.c:122) + by 0x........: main (mempool2.c:174) + + +------ read free in mmap-backed pool ------ + +Illegal memory pool address + at 0x........: test (mempool2.c:150) + by 0x........: main (mempool2.c:174) + Address 0x........ is not stack'd, malloc'd or (recently) free'd + + +------ double free in malloc-backed pool ------ + +Illegal memory pool address + at 0x........: test (mempool2.c:155) + by 0x........: main (mempool2.c:174) + Address 0x........ is 0 bytes inside a block of size 32 alloc'd + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: make_pool (mempool2.c:46) + by 0x........: test (mempool2.c:122) + by 0x........: main (mempool2.c:174) + + +------ double free in mmap-backed pool ------ + +Illegal memory pool address + at 0x........: test (mempool2.c:159) + by 0x........: main (mempool2.c:174) + Address 0x........ is not stack'd, malloc'd or (recently) free'd + + +------ done ------ + diff --git a/memcheck/tests/mempool2.vgtest b/memcheck/tests/mempool2.vgtest new file mode 100644 index 0000000000..4d6837c29b --- /dev/null +++ b/memcheck/tests/mempool2.vgtest @@ -0,0 +1,2 @@ +prog: mempool2 +vgopts: -q --leak-check=yes