From b968b2f66237c9c102c4c58d570fee9b9b95fb57 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 9 Oct 2012 11:32:40 -0700 Subject: [PATCH] Bug#67156: Sporadic query cache related crash in pthread_rwlock_init() Reinitializing the query cache might lead to a crash inside pthread_rwlock_init() on Mac OS X. Mac OS X's pthread_rwlock_init() implements a check to detect attempts to reinitialize a previously initialized but not yet destroyed read/write lock. This check works by looking for a signature within the rwlock object and, if the signature matches, some pointer variables within the object are dereferenced. When MySQL's query cache is resized (e.g. SET query_cache_size = ...), or simply deinitialized, the memory used to allocate blocks is freed without explicitly deinitializing the allocated blocks. In particular, 'queries blocks' contain rwlock objects that are not properly destroyed. If the query cache is resized, and the same memory region is used, and a new query block is allocated in the same position, attempting to initialize the block's read/write lock might crash if the read-write lock object signature was preserved but yet somehow some of its fields were corrupted. The solution is to properly destroy the used read-write lock objects. --- sql/sql_cache.cc | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index f8bb25e..6c90d43 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1127,7 +1127,7 @@ ulong Query_cache::resize(ulong query_cache_size_arg) { BLOCK_LOCK_WR(block); Query_cache_query *query= block->query(); - if (query && query->writer()) + if (query->writer()) { /* Drop the writer; this will cancel any attempts to store @@ -1137,7 +1137,7 @@ ulong Query_cache::resize(ulong query_cache_size_arg) query->writer(0); refused++; } - BLOCK_UNLOCK_WR(block); + query->unlock_n_destroy(); block= block->next; } while (block != queries_blocks); } -- 1.7.4.4