Add DRD suppression patterns for races triggered by std::ostream
[valgrind.git] / drd / tests / custom_alloc.c
blob858155ef8b907c2ba3f7158e392036d40789f3bc
1 #include <unistd.h>
2 #include "tests/sys_mman.h"
3 #include <assert.h>
4 #include <stdlib.h>
6 #include "../drd.h"
8 #define SUPERBLOCK_SIZE 100000
10 //-------------------------------------------------------------------------
11 // Allocator
12 //-------------------------------------------------------------------------
14 void* get_superblock(void)
16 void* p = mmap( 0, SUPERBLOCK_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC,
17 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0 );
19 assert(p != ((void*)(-1)));
21 return p;
24 // has a redzone
25 static void* custom_alloc(int size)
27 #define RZ 8
28 static void* hp = 0; // current heap pointer
29 static void* hp_lim = 0; // maximum usable byte in current block
30 int size2 = size + RZ*2;
31 void* p;
33 if (hp + size2 > hp_lim) {
34 hp = get_superblock();
35 hp_lim = hp + SUPERBLOCK_SIZE - 1;
38 p = hp + RZ;
39 hp += size2;
41 VALGRIND_MALLOCLIKE_BLOCK( p, size, RZ, /*is_zeroed*/1 );
42 return (void*)p;
45 static void custom_free(void* p)
47 // don't actually free any memory... but mark it as freed
48 VALGRIND_FREELIKE_BLOCK( p, RZ );
50 #undef RZ
54 //-------------------------------------------------------------------------
55 // Rest
56 //-------------------------------------------------------------------------
58 void make_leak(void)
60 int* array2 __attribute__((unused)) = custom_alloc(sizeof(int) * 10);
61 array2 = 0; // leak
62 return;
65 int main(void)
67 int* array;
68 int* array3;
70 array = custom_alloc(sizeof(int) * 10);
71 array[8] = 8;
72 array[9] = 8;
73 array[10] = 10; // invalid write (ok w/o MALLOCLIKE -- in superblock)
75 custom_free(array); // ok
77 custom_free(NULL); // invalid free (ok without MALLOCLIKE)
79 array3 = malloc(sizeof(int) * 10);
80 custom_free(array3); // mismatched free (ok without MALLOCLIKE)
82 make_leak();
83 return array[0]; // use after free (ok without MALLOCLIKE)
84 // (nb: initialised because is_zeroed==1 above)
85 // unfortunately not identified as being in a free'd
86 // block because the freeing of the block and shadow
87 // chunk isn't postponed.
89 // leak from make_leak()