Commit 8637931f authored by Marko Mäkelä's avatar Marko Mäkelä

Add ASAN instrumentation (and more strict Valgrind) to InnoDB

mem_heap_free_heap_top(): Remove UNIV_MEM_ASSERT_W() and unpoison
the memory region first, because part of it may have been poisoned
by an earlier mem_heap_free_top() call.
Poison the address range at the end.

mem_heap_block_free(): Poison the address range at the end.

UNIV_MEM_ASSERT_AND_ALLOC(): Replace with UNIV_MEM_ALLOC().
We want to keep the address ranges poisoned (unaccessible) as
long as possible.

UNIV_MEM_ASSERT_AND_FREE(): Replace with UNIV_MEM_FREE().
parent 70a9b12d
/***************************************************************************** /*****************************************************************************
Copyright (c) 2006, 2011, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2006, 2011, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -438,7 +439,7 @@ buf_buddy_free_low( ...@@ -438,7 +439,7 @@ buf_buddy_free_low(
buf_pool->buddy_stat[i].used--; buf_pool->buddy_stat[i].used--;
recombine: recombine:
UNIV_MEM_ASSERT_AND_ALLOC(buf, BUF_BUDDY_LOW << i); UNIV_MEM_ALLOC(buf, BUF_BUDDY_LOW << i);
((buf_page_t*) buf)->state = BUF_BLOCK_ZIP_FREE; ((buf_page_t*) buf)->state = BUF_BLOCK_ZIP_FREE;
if (i == BUF_BUDDY_SIZES) { if (i == BUF_BUDDY_SIZES) {
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -1953,8 +1954,7 @@ buf_LRU_block_free_non_file_page( ...@@ -1953,8 +1954,7 @@ buf_LRU_block_free_non_file_page(
UT_LIST_ADD_FIRST(list, buf_pool->free, (&block->page)); UT_LIST_ADD_FIRST(list, buf_pool->free, (&block->page));
ut_d(block->page.in_free_list = TRUE); ut_d(block->page.in_free_list = TRUE);
UNIV_MEM_FREE(block->frame, UNIV_PAGE_SIZE);
UNIV_MEM_ASSERT_AND_FREE(block->frame, UNIV_PAGE_SIZE);
} }
/******************************************************************//** /******************************************************************//**
......
...@@ -297,6 +297,7 @@ mem_heap_free_heap_top( ...@@ -297,6 +297,7 @@ mem_heap_free_heap_top(
#ifdef UNIV_MEM_DEBUG #ifdef UNIV_MEM_DEBUG
ut_ad(mem_block_get_start(block) <= mem_block_get_free(block)); ut_ad(mem_block_get_start(block) <= mem_block_get_free(block));
UNIV_MEM_ALLOC(old_top, (byte*)block + block->len - old_top);
/* In the debug version erase block from top up */ /* In the debug version erase block from top up */
mem_erase_buf(old_top, (byte*)block + block->len - old_top); mem_erase_buf(old_top, (byte*)block + block->len - old_top);
...@@ -304,10 +305,8 @@ mem_heap_free_heap_top( ...@@ -304,10 +305,8 @@ mem_heap_free_heap_top(
mutex_enter(&mem_hash_mutex); mutex_enter(&mem_hash_mutex);
mem_current_allocated_memory -= (total_size - size); mem_current_allocated_memory -= (total_size - size);
mutex_exit(&mem_hash_mutex); mutex_exit(&mem_hash_mutex);
#else /* UNIV_MEM_DEBUG */
UNIV_MEM_ASSERT_W(old_top, (byte*)block + block->len - old_top);
#endif /* UNIV_MEM_DEBUG */ #endif /* UNIV_MEM_DEBUG */
UNIV_MEM_ALLOC(old_top, (byte*)block + block->len - old_top); UNIV_MEM_FREE(old_top, (byte*)block + block->len - old_top);
/* If free == start, we may free the block if it is not the first /* If free == start, we may free the block if it is not the first
one */ one */
...@@ -388,11 +387,11 @@ mem_heap_free_top( ...@@ -388,11 +387,11 @@ mem_heap_free_top(
/* Subtract the free field of block */ /* Subtract the free field of block */
mem_block_set_free(block, mem_block_get_free(block) mem_block_set_free(block, mem_block_get_free(block)
- MEM_SPACE_NEEDED(n)); - MEM_SPACE_NEEDED(n));
UNIV_MEM_ASSERT_W((byte*) block + mem_block_get_free(block), n);
#ifdef UNIV_MEM_DEBUG #ifdef UNIV_MEM_DEBUG
ut_ad(mem_block_get_start(block) <= mem_block_get_free(block)); ut_ad(mem_block_get_start(block) <= mem_block_get_free(block));
UNIV_MEM_ALLOC((byte*) block + mem_block_get_free(block), n);
/* In the debug version check the consistency, and erase field */ /* In the debug version check the consistency, and erase field */
mem_field_erase((byte*)block + mem_block_get_free(block), n); mem_field_erase((byte*)block + mem_block_get_free(block), n);
#endif #endif
...@@ -404,11 +403,7 @@ mem_heap_free_top( ...@@ -404,11 +403,7 @@ mem_heap_free_top(
== mem_block_get_start(block))) { == mem_block_get_start(block))) {
mem_heap_block_free(heap, block); mem_heap_block_free(heap, block);
} else { } else {
/* Avoid a bogus UNIV_MEM_ASSERT_W() warning in a UNIV_MEM_FREE((byte*) block + mem_block_get_free(block), n);
subsequent invocation of mem_heap_free_top().
Originally, this was UNIV_MEM_FREE(), to catch writes
to freed memory. */
UNIV_MEM_ALLOC((byte*) block + mem_block_get_free(block), n);
} }
} }
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -923,7 +924,7 @@ rec_offs_set_n_alloc( ...@@ -923,7 +924,7 @@ rec_offs_set_n_alloc(
{ {
ut_ad(offsets); ut_ad(offsets);
ut_ad(n_alloc > REC_OFFS_HEADER_SIZE); ut_ad(n_alloc > REC_OFFS_HEADER_SIZE);
UNIV_MEM_ASSERT_AND_ALLOC(offsets, n_alloc * sizeof *offsets); UNIV_MEM_ALLOC(offsets, n_alloc * sizeof *offsets);
offsets[0] = n_alloc; offsets[0] = n_alloc;
} }
......
...@@ -536,13 +536,4 @@ typedef void* os_thread_ret_t; ...@@ -536,13 +536,4 @@ typedef void* os_thread_ret_t;
# define UNIV_MEM_ASSERT_W(addr, size) do {} while(0) # define UNIV_MEM_ASSERT_W(addr, size) do {} while(0)
#endif #endif
#define UNIV_MEM_ASSERT_AND_FREE(addr, size) do { \
UNIV_MEM_ASSERT_W(addr, size); \
UNIV_MEM_FREE(addr, size); \
} while (0)
#define UNIV_MEM_ASSERT_AND_ALLOC(addr, size) do { \
UNIV_MEM_ASSERT_W(addr, size); \
UNIV_MEM_ALLOC(addr, size); \
} while (0)
#endif #endif
/***************************************************************************** /*****************************************************************************
Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved. Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
Copyright (c) 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -502,13 +503,13 @@ mem_heap_block_free( ...@@ -502,13 +503,13 @@ mem_heap_block_free(
#ifndef UNIV_HOTBACKUP #ifndef UNIV_HOTBACKUP
if (!srv_use_sys_malloc) { if (!srv_use_sys_malloc) {
#ifdef UNIV_MEM_DEBUG #ifdef UNIV_MEM_DEBUG
UNIV_MEM_ALLOC(block, len);
/* In the debug version we set the memory to a random /* In the debug version we set the memory to a random
combination of hex 0xDE and 0xAD. */ combination of hex 0xDE and 0xAD. */
mem_erase_buf((byte*)block, len); mem_erase_buf((byte*)block, len);
#else /* UNIV_MEM_DEBUG */
UNIV_MEM_ASSERT_AND_FREE(block, len);
#endif /* UNIV_MEM_DEBUG */ #endif /* UNIV_MEM_DEBUG */
UNIV_MEM_FREE(block, len);
} }
if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) { if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) {
...@@ -522,13 +523,13 @@ mem_heap_block_free( ...@@ -522,13 +523,13 @@ mem_heap_block_free(
} }
#else /* !UNIV_HOTBACKUP */ #else /* !UNIV_HOTBACKUP */
#ifdef UNIV_MEM_DEBUG #ifdef UNIV_MEM_DEBUG
UNIV_MEM_ALLOC(block, len);
/* In the debug version we set the memory to a random /* In the debug version we set the memory to a random
combination of hex 0xDE and 0xAD. */ combination of hex 0xDE and 0xAD. */
mem_erase_buf((byte*)block, len); mem_erase_buf((byte*)block, len);
#else /* UNIV_MEM_DEBUG */
UNIV_MEM_ASSERT_AND_FREE(block, len);
#endif /* UNIV_MEM_DEBUG */ #endif /* UNIV_MEM_DEBUG */
UNIV_MEM_FREE(block, len);
ut_free(block); ut_free(block);
#endif /* !UNIV_HOTBACKUP */ #endif /* !UNIV_HOTBACKUP */
} }
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 2006, 2011, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2006, 2011, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -500,7 +501,7 @@ buf_buddy_free_low( ...@@ -500,7 +501,7 @@ buf_buddy_free_low(
buf_pool->buddy_stat[i].used--; buf_pool->buddy_stat[i].used--;
recombine: recombine:
UNIV_MEM_ASSERT_AND_ALLOC(buf, BUF_BUDDY_LOW << i); UNIV_MEM_ALLOC(buf, BUF_BUDDY_LOW << i);
((buf_page_t*) buf)->state = BUF_BLOCK_ZIP_FREE; ((buf_page_t*) buf)->state = BUF_BLOCK_ZIP_FREE;
if (i == BUF_BUDDY_SIZES) { if (i == BUF_BUDDY_SIZES) {
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -2146,7 +2147,7 @@ buf_LRU_block_free_non_file_page( ...@@ -2146,7 +2147,7 @@ buf_LRU_block_free_non_file_page(
ut_d(block->page.in_free_list = TRUE); ut_d(block->page.in_free_list = TRUE);
mutex_exit(&buf_pool->free_list_mutex); mutex_exit(&buf_pool->free_list_mutex);
UNIV_MEM_ASSERT_AND_FREE(block->frame, UNIV_PAGE_SIZE); UNIV_MEM_FREE(block->frame, UNIV_PAGE_SIZE);
} }
/******************************************************************//** /******************************************************************//**
......
...@@ -297,6 +297,7 @@ mem_heap_free_heap_top( ...@@ -297,6 +297,7 @@ mem_heap_free_heap_top(
#ifdef UNIV_MEM_DEBUG #ifdef UNIV_MEM_DEBUG
ut_ad(mem_block_get_start(block) <= mem_block_get_free(block)); ut_ad(mem_block_get_start(block) <= mem_block_get_free(block));
UNIV_MEM_ALLOC(old_top, (byte*)block + block->len - old_top);
/* In the debug version erase block from top up */ /* In the debug version erase block from top up */
mem_erase_buf(old_top, (byte*)block + block->len - old_top); mem_erase_buf(old_top, (byte*)block + block->len - old_top);
...@@ -304,10 +305,8 @@ mem_heap_free_heap_top( ...@@ -304,10 +305,8 @@ mem_heap_free_heap_top(
mutex_enter(&mem_hash_mutex); mutex_enter(&mem_hash_mutex);
mem_current_allocated_memory -= (total_size - size); mem_current_allocated_memory -= (total_size - size);
mutex_exit(&mem_hash_mutex); mutex_exit(&mem_hash_mutex);
#else /* UNIV_MEM_DEBUG */
UNIV_MEM_ASSERT_W(old_top, (byte*)block + block->len - old_top);
#endif /* UNIV_MEM_DEBUG */ #endif /* UNIV_MEM_DEBUG */
UNIV_MEM_ALLOC(old_top, (byte*)block + block->len - old_top); UNIV_MEM_FREE(old_top, (byte*)block + block->len - old_top);
/* If free == start, we may free the block if it is not the first /* If free == start, we may free the block if it is not the first
one */ one */
...@@ -388,11 +387,11 @@ mem_heap_free_top( ...@@ -388,11 +387,11 @@ mem_heap_free_top(
/* Subtract the free field of block */ /* Subtract the free field of block */
mem_block_set_free(block, mem_block_get_free(block) mem_block_set_free(block, mem_block_get_free(block)
- MEM_SPACE_NEEDED(n)); - MEM_SPACE_NEEDED(n));
UNIV_MEM_ASSERT_W((byte*) block + mem_block_get_free(block), n);
#ifdef UNIV_MEM_DEBUG #ifdef UNIV_MEM_DEBUG
ut_ad(mem_block_get_start(block) <= mem_block_get_free(block)); ut_ad(mem_block_get_start(block) <= mem_block_get_free(block));
UNIV_MEM_ALLOC((byte*) block + mem_block_get_free(block), n);
/* In the debug version check the consistency, and erase field */ /* In the debug version check the consistency, and erase field */
mem_field_erase((byte*)block + mem_block_get_free(block), n); mem_field_erase((byte*)block + mem_block_get_free(block), n);
#endif #endif
...@@ -404,11 +403,7 @@ mem_heap_free_top( ...@@ -404,11 +403,7 @@ mem_heap_free_top(
== mem_block_get_start(block))) { == mem_block_get_start(block))) {
mem_heap_block_free(heap, block); mem_heap_block_free(heap, block);
} else { } else {
/* Avoid a bogus UNIV_MEM_ASSERT_W() warning in a UNIV_MEM_FREE((byte*) block + mem_block_get_free(block), n);
subsequent invocation of mem_heap_free_top().
Originally, this was UNIV_MEM_FREE(), to catch writes
to freed memory. */
UNIV_MEM_ALLOC((byte*) block + mem_block_get_free(block), n);
} }
} }
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -923,7 +924,7 @@ rec_offs_set_n_alloc( ...@@ -923,7 +924,7 @@ rec_offs_set_n_alloc(
{ {
ut_ad(offsets); ut_ad(offsets);
ut_ad(n_alloc > REC_OFFS_HEADER_SIZE); ut_ad(n_alloc > REC_OFFS_HEADER_SIZE);
UNIV_MEM_ASSERT_AND_ALLOC(offsets, n_alloc * sizeof *offsets); UNIV_MEM_ALLOC(offsets, n_alloc * sizeof *offsets);
offsets[0] = n_alloc; offsets[0] = n_alloc;
} }
......
...@@ -549,14 +549,6 @@ typedef void* os_thread_ret_t; ...@@ -549,14 +549,6 @@ typedef void* os_thread_ret_t;
# define UNIV_MEM_ASSERT_RW(addr, size) do {} while(0) # define UNIV_MEM_ASSERT_RW(addr, size) do {} while(0)
# define UNIV_MEM_ASSERT_W(addr, size) do {} while(0) # define UNIV_MEM_ASSERT_W(addr, size) do {} while(0)
#endif #endif
#define UNIV_MEM_ASSERT_AND_FREE(addr, size) do { \
UNIV_MEM_ASSERT_W(addr, size); \
UNIV_MEM_FREE(addr, size); \
} while (0)
#define UNIV_MEM_ASSERT_AND_ALLOC(addr, size) do { \
UNIV_MEM_ASSERT_W(addr, size); \
UNIV_MEM_ALLOC(addr, size); \
} while (0)
extern ulint srv_page_size_shift; extern ulint srv_page_size_shift;
extern ulint srv_page_size; extern ulint srv_page_size;
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved. Copyright (c) 1994, 2010, Innobase Oy. All Rights Reserved.
Copyright (c) 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -502,13 +503,13 @@ mem_heap_block_free( ...@@ -502,13 +503,13 @@ mem_heap_block_free(
#ifndef UNIV_HOTBACKUP #ifndef UNIV_HOTBACKUP
if (!srv_use_sys_malloc) { if (!srv_use_sys_malloc) {
#ifdef UNIV_MEM_DEBUG #ifdef UNIV_MEM_DEBUG
UNIV_MEM_ALLOC(block, len);
/* In the debug version we set the memory to a random /* In the debug version we set the memory to a random
combination of hex 0xDE and 0xAD. */ combination of hex 0xDE and 0xAD. */
mem_erase_buf((byte*)block, len); mem_erase_buf((byte*)block, len);
#else /* UNIV_MEM_DEBUG */
UNIV_MEM_ASSERT_AND_FREE(block, len);
#endif /* UNIV_MEM_DEBUG */ #endif /* UNIV_MEM_DEBUG */
UNIV_MEM_FREE(block, len);
} }
if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) { if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) {
...@@ -522,13 +523,13 @@ mem_heap_block_free( ...@@ -522,13 +523,13 @@ mem_heap_block_free(
} }
#else /* !UNIV_HOTBACKUP */ #else /* !UNIV_HOTBACKUP */
#ifdef UNIV_MEM_DEBUG #ifdef UNIV_MEM_DEBUG
UNIV_MEM_ALLOC(block, len);
/* In the debug version we set the memory to a random /* In the debug version we set the memory to a random
combination of hex 0xDE and 0xAD. */ combination of hex 0xDE and 0xAD. */
mem_erase_buf((byte*)block, len); mem_erase_buf((byte*)block, len);
#else /* UNIV_MEM_DEBUG */
UNIV_MEM_ASSERT_AND_FREE(block, len);
#endif /* UNIV_MEM_DEBUG */ #endif /* UNIV_MEM_DEBUG */
UNIV_MEM_FREE(block, len);
ut_free(block); ut_free(block);
#endif /* !UNIV_HOTBACKUP */ #endif /* !UNIV_HOTBACKUP */
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment