diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh
index 3655d3eae67e2d8d86626b1133055e3198a162e0..0bc16f120e58c9b857c30a37c0a8c0484e8abd53 100755
--- a/BUILD/SETUP.sh
+++ b/BUILD/SETUP.sh
@@ -119,8 +119,12 @@ fi
 
 # Set flags for various build configurations.
 # Used in -valgrind builds
-valgrind_flags="-USAFEMALLOC -UFORCE_INIT_OF_VARS -DHAVE_purify "
+# Override -DFORCE_INIT_OF_VARS from debug_cflags. It enables the macro
+# LINT_INIT(), which is only useful for silencing spurious warnings
+# of static analysis tools. We want LINT_INIT() to be a no-op in Valgrind.
+valgrind_flags="-UFORCE_INIT_OF_VARS -DHAVE_purify "
 valgrind_flags="$valgrind_flags -DMYSQL_SERVER_SUFFIX=-valgrind-max"
+valgrind_configs="--with-valgrind"
 #
 # Used in -debug builds
 debug_cflags="-DUNIV_MUST_NOT_INLINE -DEXTRA_DEBUG -DFORCE_INIT_OF_VARS "
diff --git a/BUILD/build_mccge.sh b/BUILD/build_mccge.sh
index 8ca31b2d119f93570d289d6e450a38109a38052e..2d7c0d2a2c2455e1065afbde5d146bef806d8113 100755
--- a/BUILD/build_mccge.sh
+++ b/BUILD/build_mccge.sh
@@ -1010,9 +1010,10 @@ set_ccache_usage()
 set_valgrind_flags()
 {
   if test "x$valgrind_flag" = "xyes" ; then
-    loc_valgrind_flags="-USAFEMALLOC -UFORCE_INIT_OF_VARS -DHAVE_purify "
+    loc_valgrind_flags="-UFORCE_INIT_OF_VARS -DHAVE_purify "
     loc_valgrind_flags="$loc_valgrind_flags -DMYSQL_SERVER_SUFFIX=-valgrind-max"
     compiler_flags="$compiler_flags $loc_valgrind_flags"
+    with_flags="$with_flags --with-valgrind"
   fi
 }
 
diff --git a/BUILD/compile-amd64-valgrind-max b/BUILD/compile-amd64-valgrind-max
index 962d0f17b04f724e09ed96319085ba0eb001c797..fb8dce38df3ec11883a7c09effda865a7f986f3b 100755
--- a/BUILD/compile-amd64-valgrind-max
+++ b/BUILD/compile-amd64-valgrind-max
@@ -4,7 +4,7 @@ path=`dirname $0`
 . "$path/SETUP.sh"
 
 extra_flags="$amd64_cflags $debug_cflags $valgrind_flags"
-extra_configs="$amd64_configs $debug_configs $max_configs"
+extra_configs="$amd64_configs $debug_configs $valgrind_configs $max_configs"
 
 . "$path/FINISH.sh"
 
diff --git a/BUILD/compile-pentium-icc-valgrind-max b/BUILD/compile-pentium-icc-valgrind-max
index 58acf892f5adf911285ee6d44ef2846c0d625755..0babf9ee88164b8d30f4b5b14de4e2ce695a1b37 100755
--- a/BUILD/compile-pentium-icc-valgrind-max
+++ b/BUILD/compile-pentium-icc-valgrind-max
@@ -29,6 +29,6 @@ extra_flags="$pentium_cflags $debug_cflags $valgrind_flags"
 c_warnings="-Wall -Wcheck -wd161,444,279,810,981,1292,1469,1572"
 cxx_warnings="$c_warnings -wd869,874"
 base_cxxflags="-fno-exceptions -fno-rtti"
-extra_configs="$pentium_configs $debug_configs"
+extra_configs="$pentium_configs $debug_configs $valgrind_configs"
 
 . "$path/FINISH.sh"
diff --git a/BUILD/compile-pentium-valgrind-max b/BUILD/compile-pentium-valgrind-max
index 09cc162d2befffa7f7ec1139ef589f06394fade4..8ef47bfbc17ec16566f0ff91474ed445699c63f1 100755
--- a/BUILD/compile-pentium-valgrind-max
+++ b/BUILD/compile-pentium-valgrind-max
@@ -4,7 +4,7 @@ path=`dirname $0`
 . "$path/SETUP.sh"
 
 extra_flags="$pentium_cflags $debug_cflags $valgrind_flags"
-extra_configs="$pentium_configs $debug_configs $max_configs"
+extra_configs="$pentium_configs $debug_configs $valgrind_configs $max_configs"
 
 . "$path/FINISH.sh"
 
diff --git a/BUILD/compile-pentium-valgrind-max-no-ndb b/BUILD/compile-pentium-valgrind-max-no-ndb
index 66f6ae08a7fc6a36579e08ac3af33ce13e28417e..f480f83ebf79bc108af4451f73dfb5675045e3bc 100755
--- a/BUILD/compile-pentium-valgrind-max-no-ndb
+++ b/BUILD/compile-pentium-valgrind-max-no-ndb
@@ -4,7 +4,7 @@ path=`dirname $0`
 . "$path/SETUP.sh"
 
 extra_flags="$pentium_cflags $debug_cflags $valgrind_flags"
-extra_configs="$pentium_configs $debug_configs $max_no_ndb_configs"
+extra_configs="$pentium_configs $debug_configs $valgrind_configs $max_no_ndb_configs"
 
 . "$path/FINISH.sh"
 
diff --git a/BUILD/compile-pentium64-valgrind-max b/BUILD/compile-pentium64-valgrind-max
index fa476cbb50a97196f4f0d9933deed5ca8d69fe9a..eb3d20c874d687e012d424a812b52434677bf08a 100755
--- a/BUILD/compile-pentium64-valgrind-max
+++ b/BUILD/compile-pentium64-valgrind-max
@@ -4,7 +4,7 @@ path=`dirname $0`
 . "$path/SETUP.sh"
 
 extra_flags="$pentium64_cflags $debug_cflags $valgrind_flags"
-extra_configs="$pentium_configs $debug_configs $max_configs"
+extra_configs="$pentium_configs $debug_configs $valgrind_configs $max_configs"
 
 . "$path/FINISH.sh"
 
diff --git a/configure.in b/configure.in
index ec74b15efb0960513e7725514c45a84f5b23222c..cb9bedde3ce0111cdc6ba9bb2bbde56b0ad7cc83 100644
--- a/configure.in
+++ b/configure.in
@@ -1844,6 +1844,17 @@ else
   CXXFLAGS="$OPTIMIZE_CXXFLAGS $CXXFLAGS"
 fi
 
+AC_ARG_WITH([valgrind],
+  [AS_HELP_STRING([--with-valgrind],
+    [Valgrind instrumentation @<:@default=no@:>@])],
+    [], [with_valgrind=no])
+
+if test "$with_valgrind" != "no"
+then
+  AC_CHECK_HEADERS([valgrind/valgrind.h valgrind/memcheck.h],
+    [AC_DEFINE([HAVE_VALGRIND], [1], [Define for Valgrind support])])
+fi
+
 # Debug Sync Facility. NOTE: depends on 'with_debug'. Must be behind it.
 AC_MSG_CHECKING(if Debug Sync Facility should be enabled.)
 AC_ARG_ENABLE(debug_sync,
diff --git a/include/m_string.h b/include/m_string.h
index 7bd39e7483fc846280931fe84d1d80f395628ce0..1a2a508edfb0b2cca57ae87d8f5e3ec3ea5aa41c 100644
--- a/include/m_string.h
+++ b/include/m_string.h
@@ -127,9 +127,6 @@ extern	size_t bcmp(const uchar *s1,const uchar *s2,size_t len);
 extern	size_t my_bcmp(const uchar *s1,const uchar *s2,size_t len);
 #undef bcmp
 #define bcmp(A,B,C) my_bcmp((A),(B),(C))
-#define bzero_if_purify(A,B) bzero(A,B)
-#else
-#define bzero_if_purify(A,B)
 #endif /* HAVE_purify */
 
 #ifndef bmove512
diff --git a/include/my_sys.h b/include/my_sys.h
index ac10628f943d0a9cb9a930b99e1bee73ccad009f..727ff7c58b4a6fe230c9394ad807131d17430360 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -28,6 +28,19 @@ typedef struct my_aio_result {
 } my_aio_result;
 #endif
 
+#ifdef HAVE_VALGRIND
+# include <valgrind/memcheck.h>
+# define MEM_UNDEFINED(a,len) VALGRIND_MAKE_MEM_UNDEFINED(a,len)
+# define MEM_NOACCESS(a,len) VALGRIND_MAKE_MEM_NOACCESS(a,len)
+# define MEM_CHECK_ADDRESSABLE(a,len) VALGRIND_CHECK_MEM_IS_ADDRESSABLE(a,len)
+# define MEM_CHECK_DEFINED(a,len) VALGRIND_CHECK_MEM_IS_DEFINED(a,len)
+#else /* HAVE_VALGRIND */
+# define MEM_UNDEFINED(a,len) ((void) 0)
+# define MEM_NOACCESS(a,len) ((void) 0)
+# define MEM_CHECK_ADDRESSABLE(a,len) ((void) 0)
+# define MEM_CHECK_DEFINED(a,len) ((void) 0)
+#endif /* HAVE_VALGRIND */
+
 #ifndef THREAD
 extern int NEAR my_errno;		/* Last error in mysys */
 #else
@@ -156,7 +169,7 @@ extern int NEAR my_errno;		/* Last error in mysys */
 #define my_memdup(A,B,C) _my_memdup((A),(B), __FILE__,__LINE__,C)
 #define my_strdup(A,C) _my_strdup((A), __FILE__,__LINE__,C)
 #define my_strndup(A,B,C) _my_strndup((A),(B),__FILE__,__LINE__,C)
-#define TRASH(A,B) bfill(A, B, 0x8F)
+#define TRASH(A,B) do { bfill(A, B, 0x8F); MEM_UNDEFINED(A, B); } while (0)
 #define QUICK_SAFEMALLOC sf_malloc_quick=1
 #define NORMAL_SAFEMALLOC sf_malloc_quick=0
 extern uint sf_malloc_prehunc,sf_malloc_endhunc,sf_malloc_quick;
@@ -184,7 +197,7 @@ extern char *my_strndup(const char *from, size_t length,
 #define CALLER_INFO_PROTO   /* nothing */
 #define CALLER_INFO         /* nothing */
 #define ORIG_CALLER_INFO    /* nothing */
-#define TRASH(A,B) /* nothing */
+#define TRASH(A,B) do{MEM_CHECK_ADDRESSABLE(A,B);MEM_UNDEFINED(A,B);} while (0)
 #endif
 
 #if defined(ENABLED_DEBUG_SYNC)
diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c
index efe281ba1bbe9ca5b3b49ae470017b61c6c02e67..936248677f5a1c6665b6e434576a80b9b72b28d7 100644
--- a/mysys/safemalloc.c
+++ b/mysys/safemalloc.c
@@ -190,9 +190,12 @@ void *_mymalloc(size_t size, const char *filename, uint lineno, myf MyFlags)
   sf_malloc_count++;
   mysql_mutex_unlock(&THR_LOCK_malloc);
 
+  MEM_CHECK_ADDRESSABLE(data, size);
   /* Set the memory to the aribtrary wierd value */
   if ((MyFlags & MY_ZEROFILL) || !sf_malloc_quick)
     bfill(data, size, (char) (MyFlags & MY_ZEROFILL ? 0 : ALLOC_VAL));
+  if (!(MyFlags & MY_ZEROFILL))
+    MEM_UNDEFINED(data, size);
   /* Return a pointer to the real data */
   DBUG_PRINT("exit",("ptr: %p", data));
   if (sf_min_adress > data)
@@ -309,7 +312,9 @@ void _myfree(void *ptr, const char *filename, uint lineno, myf myflags)
   if (!sf_malloc_quick)
     bfill(ptr, irem->datasize, (pchar) FREE_VAL);
 #endif
+  MEM_NOACCESS(ptr, irem->datasize);
   *((uint32*) ((char*) ptr- sizeof(uint32)))= ~MAGICKEY;
+  MEM_NOACCESS((char*) ptr - sizeof(uint32), sizeof(uint32));
   /* Actually free the memory */
   free((char*) irem);
   DBUG_VOID_RETURN;
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index 96faa84c6ff449547b657cae09d1b48c3f21b7aa..11cec113fc8182a1e705fcafe4f1b892a8383a72 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -182,9 +182,9 @@ command. Not tested on Windows. */
 #define UNIV_COMPILE_TEST_FUNCS
 */
 
-#ifdef HAVE_purify
+#if defined HAVE_VALGRIND
 # define UNIV_DEBUG_VALGRIND
-#endif /* HAVE_purify */
+#endif /* HAVE_VALGRIND */
 #if 0
 #define UNIV_DEBUG_VALGRIND			/* Enable extra
 						Valgrind instrumentation */