Commit 53382ac1 authored by Jan Lindström's avatar Jan Lindström

MDEV-8079: Crash when running MariaDB Debug with InnoDB on Windows

Problem was that std::vector was allocated using calloc instead of
new, this caused vector constructor not being called and vector
metadata not initialized.
parent ff1e0821
...@@ -49,27 +49,6 @@ Created 9/5/1995 Heikki Tuuri ...@@ -49,27 +49,6 @@ Created 9/5/1995 Heikki Tuuri
#include <vector> #include <vector>
/* There is a bug in Visual Studio 2010.
Visual Studio has a feature "Checked Iterators". In a debug build, every
iterator operation is checked at runtime for errors, e.g., out of range.
Because of bug there is runtime error on following code
for (std::vector<sync_level_t>::iterator it = array->elems.begin(); it !=
array->elems.end(); ++it) and runtime check fails on comparison
it != array->elems.end() that is correct and standard way to do end
of range comparison.
Disable this "Checked Iterators" for Windows and Debug if defined.
*/
#ifdef UNIV_DEBUG
#ifdef __WIN__
#ifdef _ITERATOR_DEBUG_LEVEL
#undef _ITERATOR_DEBUG_LEVEL
#define _ITERATOR_DEBUG_LEVEL 0
#endif /* _ITERATOR_DEBUG_LEVEL */
#endif /* __WIN__*/
#endif /* UNIV_DEBUG */
#include <vector>
/* /*
REASONS FOR IMPLEMENTING THE SPIN LOCK MUTEX REASONS FOR IMPLEMENTING THE SPIN LOCK MUTEX
============================================ ============================================
...@@ -247,11 +226,8 @@ UNIV_INTERN ibool sync_order_checks_on = FALSE; ...@@ -247,11 +226,8 @@ UNIV_INTERN ibool sync_order_checks_on = FALSE;
static const ulint SYNC_THREAD_N_LEVELS = 10000; static const ulint SYNC_THREAD_N_LEVELS = 10000;
/** Array for tracking sync levels per thread. */ /** Array for tracking sync levels per thread. */
struct sync_arr_t { typedef std::vector<sync_level_t> sync_arr_t;
ulint n_elems; /*!< Number of elements in the array */
std::vector<sync_level_t> elems; /*!< Vector of elements */
};
/** Mutexes or rw-locks held by a thread */ /** Mutexes or rw-locks held by a thread */
struct sync_thread_t{ struct sync_thread_t{
...@@ -879,10 +855,10 @@ sync_thread_levels_g( ...@@ -879,10 +855,10 @@ sync_thread_levels_g(
{ {
ulint i; ulint i;
for (i = 0; i < arr->n_elems; i++) { for (i = 0; i < arr->size(); i++) {
const sync_level_t* slot; const sync_level_t* slot;
slot = &arr->elems[i]; slot = (const sync_level_t*)&(arr->at(i));
if (slot->latch != NULL && slot->level <= limit) { if (slot->latch != NULL && slot->level <= limit) {
if (warn) { if (warn) {
...@@ -914,10 +890,10 @@ sync_thread_levels_contain( ...@@ -914,10 +890,10 @@ sync_thread_levels_contain(
{ {
ulint i; ulint i;
for (i = 0; i < arr->n_elems; i++) { for (i = 0; i < arr->size(); i++) {
const sync_level_t* slot; const sync_level_t* slot;
slot = &arr->elems[i]; slot = (const sync_level_t*)&(arr->at(i));
if (slot->latch != NULL && slot->level == level) { if (slot->latch != NULL && slot->level == level) {
...@@ -961,10 +937,10 @@ sync_thread_levels_contains( ...@@ -961,10 +937,10 @@ sync_thread_levels_contains(
arr = thread_slot->levels; arr = thread_slot->levels;
for (i = 0; i < arr->n_elems; i++) { for (i = 0; i < arr->size(); i++) {
sync_level_t* slot; sync_level_t* slot;
slot = &arr->elems[i]; slot = (sync_level_t*)&(arr->at(i));
if (slot->latch != NULL && slot->level == level) { if (slot->latch != NULL && slot->level == level) {
...@@ -1010,10 +986,10 @@ sync_thread_levels_nonempty_gen( ...@@ -1010,10 +986,10 @@ sync_thread_levels_nonempty_gen(
arr = thread_slot->levels; arr = thread_slot->levels;
for (i = 0; i < arr->n_elems; ++i) { for (i = 0; i < arr->size(); ++i) {
const sync_level_t* slot; const sync_level_t* slot;
slot = &arr->elems[i]; slot = (const sync_level_t*)&(arr->at(i));
if (slot->latch != NULL if (slot->latch != NULL
&& (!dict_mutex_allowed && (!dict_mutex_allowed
...@@ -1070,10 +1046,10 @@ sync_thread_levels_nonempty_trx( ...@@ -1070,10 +1046,10 @@ sync_thread_levels_nonempty_trx(
arr = thread_slot->levels; arr = thread_slot->levels;
for (i = 0; i < arr->n_elems; ++i) { for (i = 0; i < arr->size(); ++i) {
const sync_level_t* slot; const sync_level_t* slot;
slot = &arr->elems[i]; slot = (const sync_level_t*)&(arr->at(i));
if (slot->latch != NULL if (slot->latch != NULL
&& (!has_search_latch && (!has_search_latch
...@@ -1133,7 +1109,7 @@ sync_thread_add_level( ...@@ -1133,7 +1109,7 @@ sync_thread_add_level(
if (thread_slot == NULL) { if (thread_slot == NULL) {
/* We have to allocate the level array for a new thread */ /* We have to allocate the level array for a new thread */
array = static_cast<sync_arr_t*>(calloc(1, sizeof(sync_arr_t))); array = new sync_arr_t();
ut_a(array != NULL); ut_a(array != NULL);
thread_slot = sync_thread_level_arrays_find_free(); thread_slot = sync_thread_level_arrays_find_free();
thread_slot->levels = array; thread_slot->levels = array;
...@@ -1347,10 +1323,9 @@ sync_thread_add_level( ...@@ -1347,10 +1323,9 @@ sync_thread_add_level(
levels_ok: levels_ok:
array->n_elems++;
sync_level.latch = latch; sync_level.latch = latch;
sync_level.level = level; sync_level.level = level;
array->elems.push_back(sync_level); array->push_back(sync_level);
mutex_exit(&sync_thread_mutex); mutex_exit(&sync_thread_mutex);
} }
...@@ -1396,15 +1371,14 @@ sync_thread_reset_level( ...@@ -1396,15 +1371,14 @@ sync_thread_reset_level(
array = thread_slot->levels; array = thread_slot->levels;
for (std::vector<sync_level_t>::iterator it = array->elems.begin(); it != array->elems.end(); ++it) { for (std::vector<sync_level_t>::iterator it = array->begin(); it != array->end(); ++it) {
sync_level_t level = *it; sync_level_t level = *it;
if (level.latch != latch) { if (level.latch != latch) {
continue; continue;
} }
array->elems.erase(it); array->erase(it);
array->n_elems--;
mutex_exit(&sync_thread_mutex); mutex_exit(&sync_thread_mutex);
return(TRUE); return(TRUE);
} }
...@@ -1491,9 +1465,7 @@ sync_thread_level_arrays_free(void) ...@@ -1491,9 +1465,7 @@ sync_thread_level_arrays_free(void)
/* If this slot was allocated then free the slot memory too. */ /* If this slot was allocated then free the slot memory too. */
if (slot->levels != NULL) { if (slot->levels != NULL) {
slot->levels->elems.erase(slot->levels->elems.begin(),slot->levels->elems.end()); delete slot->levels;
free(slot->levels);
slot->levels = NULL;
} }
} }
......
...@@ -50,27 +50,6 @@ Created 9/5/1995 Heikki Tuuri ...@@ -50,27 +50,6 @@ Created 9/5/1995 Heikki Tuuri
#include <vector> #include <vector>
/* There is a bug in Visual Studio 2010.
Visual Studio has a feature "Checked Iterators". In a debug build, every
iterator operation is checked at runtime for errors, e.g., out of range.
Because of bug there is runtime error on following code
for (std::vector<sync_level_t>::iterator it = array->elems.begin(); it !=
array->elems.end(); ++it) and runtime check fails on comparison
it != array->elems.end() that is correct and standard way to do end
of range comparison.
Disable this "Checked Iterators" for Windows and Debug if defined.
*/
#ifdef UNIV_DEBUG
#ifdef __WIN__
#ifdef _ITERATOR_DEBUG_LEVEL
#undef _ITERATOR_DEBUG_LEVEL
#define _ITERATOR_DEBUG_LEVEL 0
#endif /* _ITERATOR_DEBUG_LEVEL */
#endif /* __WIN__*/
#endif /* UNIV_DEBUG */
#include <vector>
/* /*
REASONS FOR IMPLEMENTING THE SPIN LOCK MUTEX REASONS FOR IMPLEMENTING THE SPIN LOCK MUTEX
============================================ ============================================
...@@ -251,11 +230,8 @@ UNIV_INTERN ibool sync_order_checks_on = FALSE; ...@@ -251,11 +230,8 @@ UNIV_INTERN ibool sync_order_checks_on = FALSE;
static const ulint SYNC_THREAD_N_LEVELS = 10000; static const ulint SYNC_THREAD_N_LEVELS = 10000;
/** Array for tracking sync levels per thread. */ /** Array for tracking sync levels per thread. */
struct sync_arr_t { typedef std::vector<sync_level_t> sync_arr_t;
ulint n_elems; /*!< Number of elements in the array */
std::vector<sync_level_t> elems; /*!< Vector of elements */
};
/** Mutexes or rw-locks held by a thread */ /** Mutexes or rw-locks held by a thread */
struct sync_thread_t{ struct sync_thread_t{
...@@ -982,10 +958,10 @@ sync_thread_levels_g( ...@@ -982,10 +958,10 @@ sync_thread_levels_g(
{ {
ulint i; ulint i;
for (i = 0; i < arr->n_elems; i++) { for (i = 0; i < arr->size(); i++) {
const sync_level_t* slot; const sync_level_t* slot;
slot = &arr->elems[i]; slot = (const sync_level_t*)&(arr->at(i));
if (slot->latch != NULL && slot->level <= limit) { if (slot->latch != NULL && slot->level <= limit) {
if (warn) { if (warn) {
...@@ -1017,10 +993,10 @@ sync_thread_levels_contain( ...@@ -1017,10 +993,10 @@ sync_thread_levels_contain(
{ {
ulint i; ulint i;
for (i = 0; i < arr->n_elems; i++) { for (i = 0; i < arr->size(); i++) {
const sync_level_t* slot; const sync_level_t* slot;
slot = &arr->elems[i]; slot = (const sync_level_t*)&(arr->at(i));
if (slot->latch != NULL && slot->level == level) { if (slot->latch != NULL && slot->level == level) {
...@@ -1064,10 +1040,10 @@ sync_thread_levels_contains( ...@@ -1064,10 +1040,10 @@ sync_thread_levels_contains(
arr = thread_slot->levels; arr = thread_slot->levels;
for (i = 0; i < arr->n_elems; i++) { for (i = 0; i < arr->size(); i++) {
sync_level_t* slot; sync_level_t* slot;
slot = &arr->elems[i]; slot = (sync_level_t*)&(arr->at(i));
if (slot->latch != NULL && slot->level == level) { if (slot->latch != NULL && slot->level == level) {
...@@ -1113,10 +1089,10 @@ sync_thread_levels_nonempty_gen( ...@@ -1113,10 +1089,10 @@ sync_thread_levels_nonempty_gen(
arr = thread_slot->levels; arr = thread_slot->levels;
for (i = 0; i < arr->n_elems; ++i) { for (i = 0; i < arr->size(); ++i) {
const sync_level_t* slot; const sync_level_t* slot;
slot = &arr->elems[i]; slot = (const sync_level_t*)&(arr->at(i));
if (slot->latch != NULL if (slot->latch != NULL
&& (!dict_mutex_allowed && (!dict_mutex_allowed
...@@ -1173,10 +1149,10 @@ sync_thread_levels_nonempty_trx( ...@@ -1173,10 +1149,10 @@ sync_thread_levels_nonempty_trx(
arr = thread_slot->levels; arr = thread_slot->levels;
for (i = 0; i < arr->n_elems; ++i) { for (i = 0; i < arr->size(); ++i) {
const sync_level_t* slot; const sync_level_t* slot;
slot = &arr->elems[i]; slot = (const sync_level_t*)&(arr->at(i));
if (slot->latch != NULL if (slot->latch != NULL
&& (!has_search_latch && (!has_search_latch
...@@ -1236,7 +1212,7 @@ sync_thread_add_level( ...@@ -1236,7 +1212,7 @@ sync_thread_add_level(
if (thread_slot == NULL) { if (thread_slot == NULL) {
/* We have to allocate the level array for a new thread */ /* We have to allocate the level array for a new thread */
array = static_cast<sync_arr_t*>(calloc(1, sizeof(sync_arr_t))); array = new sync_arr_t();
ut_a(array != NULL); ut_a(array != NULL);
thread_slot = sync_thread_level_arrays_find_free(); thread_slot = sync_thread_level_arrays_find_free();
thread_slot->levels = array; thread_slot->levels = array;
...@@ -1467,10 +1443,9 @@ sync_thread_add_level( ...@@ -1467,10 +1443,9 @@ sync_thread_add_level(
levels_ok: levels_ok:
array->n_elems++;
sync_level.latch = latch; sync_level.latch = latch;
sync_level.level = level; sync_level.level = level;
array->elems.push_back(sync_level); array->push_back(sync_level);
mutex_exit(&sync_thread_mutex); mutex_exit(&sync_thread_mutex);
} }
...@@ -1516,15 +1491,14 @@ sync_thread_reset_level( ...@@ -1516,15 +1491,14 @@ sync_thread_reset_level(
array = thread_slot->levels; array = thread_slot->levels;
for (std::vector<sync_level_t>::iterator it = array->elems.begin(); it != array->elems.end(); ++it) { for (std::vector<sync_level_t>::iterator it = array->begin(); it != array->end(); ++it) {
sync_level_t level = *it; sync_level_t level = *it;
if (level.latch != latch) { if (level.latch != latch) {
continue; continue;
} }
array->elems.erase(it); array->erase(it);
array->n_elems--;
mutex_exit(&sync_thread_mutex); mutex_exit(&sync_thread_mutex);
return(TRUE); return(TRUE);
} }
...@@ -1612,9 +1586,7 @@ sync_thread_level_arrays_free(void) ...@@ -1612,9 +1586,7 @@ sync_thread_level_arrays_free(void)
/* If this slot was allocated then free the slot memory too. */ /* If this slot was allocated then free the slot memory too. */
if (slot->levels != NULL) { if (slot->levels != NULL) {
slot->levels->elems.erase(slot->levels->elems.begin(),slot->levels->elems.end()); delete slot->levels;
free(slot->levels);
slot->levels = NULL;
} }
} }
......
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