Skip to content

Commit

Permalink
mem: more valgrind instrumentation
Browse files Browse the repository at this point in the history
(continuing work on #949)

- use memcheck only on pkg memory
- use memcheck "red zones" to detect buffer over/underflows
  • Loading branch information
camilleoudot committed Feb 28, 2017
1 parent 44f0830 commit 62c9ac4
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 15 deletions.
66 changes: 51 additions & 15 deletions src/core/mem/q_malloc.c
Expand Up @@ -61,7 +61,13 @@


#define ROUNDTO_MASK (~((unsigned long)ROUNDTO-1))
#define ROUNDUP(s) (((s)+(ROUNDTO-1))&ROUNDTO_MASK)

#ifdef VALGRIND_MEMCHECK
#define ROUNDUP(s) (((s+sizeof(_qm_redzone_t))+(ROUNDTO-1))&ROUNDTO_MASK)
#else
#define ROUNDUP(s) (((s)+(ROUNDTO-1))&ROUNDTO_MASK)
#endif /* #ifdef VALGRIND_MEMCHECK */

#define ROUNDDOWN(s) ((s)&ROUNDTO_MASK)


Expand Down Expand Up @@ -163,7 +169,10 @@ static inline void qm_insert_free(struct qm_block* qm, struct qm_frag* frag)
if (frag->size <= f->size) break;
}
#ifdef VALGRIND_MEMCHECK
VALGRIND_MEMPOOL_FREE(qm, (char*)frag + sizeof(struct qm_frag));
if (qm->type == MEM_TYPE_PKG) {
VALGRIND_DISCARD((char*)frag + sizeof(struct qm_frag));
VALGRIND_MEMPOOL_FREE(qm, (char*)frag + sizeof(struct qm_frag));
}
#endif /* #ifdef VALGRIND_MEMCHECK */
/*insert it here*/
prev=FRAG_END(f)->prev_free;
Expand Down Expand Up @@ -240,12 +249,17 @@ struct qm_block* qm_malloc_init(char* address, unsigned long size, int type)
}

#ifdef VALGRIND_MEMCHECK
VALGRIND_CREATE_MEMPOOL(qm, 0 /*sizeof(unsigned long)*/, 0);
VALGRIND_MEMPOOL_ALLOC(qm, qm->first_frag, sizeof(struct qm_frag));
VALGRIND_MAKE_MEM_DEFINED(qm->first_frag, sizeof(struct qm_frag));
VALGRIND_MEMPOOL_ALLOC(qm, FRAG_END(qm->first_frag), sizeof(struct qm_frag_end));
VALGRIND_MAKE_MEM_DEFINED(FRAG_END(qm->first_frag), sizeof(struct qm_frag_end));
VALGRIND_MEMPOOL_ALLOC(qm, (char*)qm->first_frag + sizeof(struct qm_frag), qm->first_frag->size);
if (qm->type == MEM_TYPE_PKG) {
VALGRIND_CREATE_MEMPOOL(qm, sizeof(unsigned long), 0);
VALGRIND_MEMPOOL_ALLOC(qm, qm->first_frag, sizeof(struct qm_frag) - sizeof(_qm_redzone_t));
VALGRIND_CREATE_BLOCK(qm->first_frag, sizeof(struct qm_frag) - sizeof(_qm_redzone_t), "fragment header (init)");
VALGRIND_MAKE_MEM_DEFINED(qm->first_frag, sizeof(struct qm_frag) - sizeof(_qm_redzone_t));
VALGRIND_MEMPOOL_ALLOC(qm, FRAG_END(qm->first_frag), sizeof(struct qm_frag_end) - sizeof(_qm_redzone_t));
VALGRIND_CREATE_BLOCK(FRAG_END(qm->first_frag), sizeof(struct qm_frag_end) - sizeof(_qm_redzone_t), "fragment tail (init)");
VALGRIND_MAKE_MEM_DEFINED(FRAG_END(qm->first_frag), sizeof(struct qm_frag_end) - sizeof(_qm_redzone_t));
VALGRIND_MEMPOOL_ALLOC(qm, (char*)qm->first_frag + sizeof(struct qm_frag), qm->first_frag->size - sizeof(_qm_redzone_t));
VALGRIND_CREATE_BLOCK((char*)qm->first_frag + sizeof(struct qm_frag), qm->first_frag->size - sizeof(_qm_redzone_t), "fragment data (init)");
}
#endif /* #ifdef VALGRIND_MEMCHECK */

/* link initial fragment into the free list*/
Expand All @@ -267,7 +281,10 @@ static inline void qm_detach_free(struct qm_block* qm, struct qm_frag* frag)
struct qm_frag *prev;
struct qm_frag *next;
#ifdef VALGRIND_MEMCHECK
VALGRIND_MEMPOOL_ALLOC(qm, (char*)frag + sizeof(struct qm_frag), frag->size);
if (qm->type == MEM_TYPE_PKG) {
VALGRIND_MEMPOOL_ALLOC(qm, (char*)frag + sizeof(struct qm_frag), frag->size - sizeof(_qm_redzone_t));
VALGRIND_CREATE_BLOCK((char*)frag + sizeof(struct qm_frag), frag->size - sizeof(_qm_redzone_t), "fragment data (detach)");
}
#endif /* #ifdef VALGRIND_MEMCHECK */

prev=FRAG_END(frag)->prev_free;
Expand Down Expand Up @@ -331,22 +348,38 @@ int split_frag(struct qm_block* qm, struct qm_frag* f, size_t new_size)
if (rest>(FRAG_OVERHEAD+MIN_FRAG_SIZE)){
#endif
#ifdef VALGRIND_MEMCHECK
VALGRIND_MEMPOOL_CHANGE(qm, (char*)f + sizeof(struct qm_frag), (char*)f + sizeof(struct qm_frag), new_size);
if (qm->type == MEM_TYPE_PKG) {
VALGRIND_DISCARD((char*)f + sizeof(struct qm_frag));
VALGRIND_MEMPOOL_FREE(qm, (char*)f + sizeof(struct qm_frag));
VALGRIND_MEMPOOL_ALLOC(qm, (char*)f + sizeof(struct qm_frag), new_size - sizeof(_qm_redzone_t));
VALGRIND_CREATE_BLOCK((char*)f + sizeof(struct qm_frag), new_size - sizeof(_qm_redzone_t), "fragment data (split 1)");
VALGRIND_DISCARD(FRAG_END(f));
VALGRIND_CREATE_BLOCK(FRAG_END(f), sizeof(struct qm_frag_end) - sizeof(_qm_redzone_t), "fragment tail (split 2)");
}
#endif /* #ifdef VALGRIND_MEMCHECK */
f->size=new_size;
/*split the fragment*/
end=FRAG_END(f);
#ifdef VALGRIND_MEMCHECK
VALGRIND_MEMPOOL_ALLOC(qm, end, sizeof(struct qm_frag_end));
if (qm->type == MEM_TYPE_PKG) {
VALGRIND_MEMPOOL_ALLOC(qm, end, sizeof(struct qm_frag_end) - sizeof(_qm_redzone_t));
VALGRIND_CREATE_BLOCK(end, sizeof(struct qm_frag_end) - sizeof(_qm_redzone_t), "fragment tail (split 1)");
}
#endif /* #ifdef VALGRIND_MEMCHECK */
end->size=new_size;
n=(struct qm_frag*)((char*)end+sizeof(struct qm_frag_end));
#ifdef VALGRIND_MEMCHECK
VALGRIND_MEMPOOL_ALLOC(qm, n, sizeof(struct qm_frag));
if (qm->type == MEM_TYPE_PKG) {
VALGRIND_MEMPOOL_ALLOC(qm, n, sizeof(struct qm_frag) - sizeof(_qm_redzone_t));
VALGRIND_CREATE_BLOCK(n, sizeof(struct qm_frag) - sizeof(_qm_redzone_t), "fragment header (split 2)");
}
#endif /* #ifdef VALGRIND_MEMCHECK */
n->size=rest-FRAG_OVERHEAD;
#ifdef VALGRIND_MEMCHECK
VALGRIND_MEMPOOL_ALLOC(qm, (char *)n + sizeof(struct qm_frag), n->size);
if (qm->type == MEM_TYPE_PKG) {
VALGRIND_MEMPOOL_ALLOC(qm, (char *)n + sizeof(struct qm_frag), n->size - sizeof(_qm_redzone_t));
VALGRIND_CREATE_BLOCK((char *)n + sizeof(struct qm_frag), n->size - sizeof(_qm_redzone_t), "fragment data (split 2)");
}
#endif /* #ifdef VALGRIND_MEMCHECK */
FRAG_END(n)->size=n->size;
FRAG_CLEAR_USED(n); /* never used */
Expand Down Expand Up @@ -500,8 +533,7 @@ void qm_free(void* qmp, void* p)
else return;
}
#endif

f=(struct qm_frag*) ((char*)p-sizeof(struct qm_frag));
f=(struct qm_frag*) ((char*)p-sizeof(struct qm_frag));

#ifdef DBG_QM_MALLOC
qm_debug_frag(qm, f, file, line);
Expand Down Expand Up @@ -698,7 +730,11 @@ void* qm_realloc(void* qmp, void* p, size_t size)
#endif
if (ptr){
/* copy, need by libssl */
#ifdef VALGRIND_MEMCHECK
memcpy(ptr, p, orig_size - sizeof(_qm_redzone_t));
#else
memcpy(ptr, p, orig_size);
#endif /* #ifdef VALGRIND_MEMCHECK */
} else {
#ifdef DBG_QM_MALLOC
LOG(L_ERR, "qm_realloc(%p, %lu) called from %s: %s(%d), module: %s; qm_malloc() failed!\n",
Expand Down
10 changes: 10 additions & 0 deletions src/core/mem/q_malloc.h
Expand Up @@ -71,6 +71,10 @@
* ROUNDTO from bucket to bucket
* +1 .... end - size = 2^k, big buckets */

#ifdef VALGRIND_MEMCHECK
typedef void * _qm_redzone_t;
#endif

struct qm_frag{
unsigned long size;
union{
Expand All @@ -84,6 +88,9 @@ struct qm_frag{
unsigned long line;
unsigned long check;
#endif
#ifdef VALGRIND_MEMCHECK
_qm_redzone_t _rz;
#endif /* #ifdef VALGRIND_MEMCHECK */
};

struct qm_frag_end{
Expand All @@ -95,6 +102,9 @@ struct qm_frag_end{
#endif
unsigned long size;
struct qm_frag* prev_free;
#ifdef VALGRIND_MEMCHECK
_qm_redzone_t _rz;
#endif /* #ifdef VALGRIND_MEMCHECK */
};


Expand Down

0 comments on commit 62c9ac4

Please sign in to comment.