1 #include "libdevmapper.h"
6 * Checks that valgrind is picking up unallocated pool memory as
7 * uninitialised, even if the chunk has been recycled.
9 * $ valgrind --track-origins=yes ./pool_valgrind_t
11 * ==7023== Memcheck, a memory error detector
12 * ==7023== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
13 * ==7023== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
14 * ==7023== Command: ./pool_valgrind_t
16 * first branch worked (as expected)
17 * ==7023== Conditional jump or move depends on uninitialised value(s)
18 * ==7023== at 0x4009AC: main (in /home/ejt/work/lvm2/unit-tests/mm/pool_valgrind_t)
19 * ==7023== Uninitialised value was created by a client request
20 * ==7023== at 0x4E40CB8: dm_pool_free (in /home/ejt/work/lvm2/libdm/ioctl/libdevmapper.so.1.02)
21 * ==7023== by 0x4009A8: main (in /home/ejt/work/lvm2/unit-tests/mm/pool_valgrind_t)
23 * second branch worked (valgrind should have flagged this as an error)
25 * ==7023== HEAP SUMMARY:
26 * ==7023== in use at exit: 0 bytes in 0 blocks
27 * ==7023== total heap usage: 2 allocs, 2 frees, 2,104 bytes allocated
29 * ==7023== All heap blocks were freed -- no leaks are possible
31 * ==7023== For counts of detected and suppressed errors, rerun with: -v
32 * ==7023== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)
37 static void check_free()
41 struct dm_pool *p = dm_pool_create("blah", 1024);
43 for (i = 0; i < COUNT; i++)
44 blocks[i] = dm_pool_alloc(p, 37);
46 /* check we can access the last block */
47 blocks[COUNT - 1][0] = 'E';
48 if (blocks[COUNT - 1][0] == 'E')
49 printf("first branch worked (as expected)\n");
51 dm_pool_free(p, blocks[5]);
53 if (blocks[COUNT - 1][0] == 'E')
54 printf("second branch worked (valgrind should have flagged this as an error)\n");
59 /* Checks that freed chunks are marked NOACCESS */
60 static void check_free2()
62 struct dm_pool *p = dm_pool_create("", 900); /* 900 will get
70 data1 = dm_pool_alloc(p, 123);
73 data1 = dm_pool_alloc(p, 1024);
76 data2 = dm_pool_alloc(p, 123);
79 data2[0] = 'A'; /* should work fine */
81 dm_pool_free(p, data1);
84 * so now the first chunk is active, the second chunk has become
87 data2[0] = 'B'; /* should prompt an invalid write error */
92 static void check_alignment()
95 * Pool always tries to allocate blocks with particular alignment.
96 * So there are potentially small gaps between allocations. This
97 * test checks that valgrind is spotting illegal accesses to these
102 struct dm_pool *p = dm_pool_create("blah", 1024);
107 data1 = dm_pool_alloc_aligned(p, 1, 4);
109 data2 = dm_pool_alloc_aligned(p, 1, 4);
112 snprintf(buffer, sizeof(buffer), "%c", *(data1 + 1)); /* invalid read size 1 */
117 * Looking at the code I'm not sure allocations that are near the chunk
118 * size are working. So this test is trying to exhibit a specific problem.
120 static void check_allocation_near_chunk_size()
124 struct dm_pool *p = dm_pool_create("", 900);
127 * allocate a lot and then free everything so we know there
130 for (i = 0; i < 1000; i++) {
131 data = dm_pool_alloc(p, 37);
138 /* now we allocate something close to the chunk size ... */
139 data = dm_pool_alloc(p, 1020);
141 memset(data, 0, 1020);
146 /* FIXME: test the dbg_malloc at exit (this test should be in dbg_malloc) */
147 static void check_leak_detection()
150 struct dm_pool *p = dm_pool_create("", 1024);
152 for (i = 0; i < 10; i++)
153 dm_pool_alloc(p, (i + 1) * 37);
156 /* we shouldn't get any errors from this one */
157 static void check_object_growth()
160 struct dm_pool *p = dm_pool_create("", 32);
164 memset(data, 0, sizeof(data));
166 dm_pool_begin_object(p, 43);
167 for (i = 1; i < 100; i++)
168 dm_pool_grow_object(p, data, i);
169 obj = dm_pool_end_object(p);
174 int main(int argc, char **argv)
179 check_allocation_near_chunk_size();
180 check_leak_detection();
181 check_object_growth();