summaryrefslogtreecommitdiff
path: root/dbug
diff options
context:
space:
mode:
authorEugene Kosov <claprix@yandex.ru>2019-11-23 23:26:35 +0700
committerEugene Kosov <claprix@yandex.ru>2019-11-28 11:59:27 +0700
commit2855edf9ee0344e596ff4b9ee70a23421ae60405 (patch)
treedbcc47c531ddae4ca1a76aa3e00e8a1ce372a9b2 /dbug
parent6218bf1b416219aef37301f054136fcdcc404d45 (diff)
downloadmariadb-git-2855edf9ee0344e596ff4b9ee70a23421ae60405.tar.gz
try to fix data races in DBUG
init_settings.keywords and it's pointee are shared data. Protect them with mutex too.
Diffstat (limited to 'dbug')
-rw-r--r--dbug/dbug.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/dbug/dbug.c b/dbug/dbug.c
index 78605983ccb..21f86ded0a5 100644
--- a/dbug/dbug.c
+++ b/dbug/dbug.c
@@ -320,6 +320,10 @@ static void DbugVfprintf(FILE *stream, const char* format, va_list args);
*/
#include <my_pthread.h>
+/*
+** Protects writing to all file descriptors, init_settings.keywords
+** pointer and it's pointee - a linked list with keywords.
+*/
static pthread_mutex_t THR_LOCK_dbug;
static void LockMutex(CODE_STATE *cs)
@@ -332,6 +336,16 @@ static void UnlockMutex(CODE_STATE *cs)
if (!cs->locked)
pthread_mutex_unlock(&THR_LOCK_dbug);
}
+static void LockIfInitSettings(CODE_STATE *cs)
+{
+ if (cs->stack == &init_settings)
+ LockMutex(cs);
+}
+static void UnlockIfInitSettings(CODE_STATE *cs)
+{
+ if (cs->stack == &init_settings)
+ UnlockMutex(cs);
+}
static CODE_STATE *code_state(void)
{
@@ -476,7 +490,9 @@ static int DbugParse(CODE_STATE *cs, const char *control)
stack->sub_level= 0;
stack->out_file= sstderr;
stack->functions= NULL;
+ LockIfInitSettings(cs);
stack->keywords= NULL;
+ UnlockIfInitSettings(cs);
stack->processes= NULL;
}
else if (!stack->out_file)
@@ -492,7 +508,9 @@ static int DbugParse(CODE_STATE *cs, const char *control)
{
/* never share with the global parent - it can change under your feet */
stack->functions= ListCopy(init_settings.functions);
+ LockIfInitSettings(cs);
stack->keywords= ListCopy(init_settings.keywords);
+ UnlockIfInitSettings(cs);
stack->processes= ListCopy(init_settings.processes);
}
else
@@ -516,21 +534,31 @@ static int DbugParse(CODE_STATE *cs, const char *control)
case 'd':
if (sign < 0 && control == end)
{
+ LockIfInitSettings(cs);
if (!is_shared(stack, keywords))
FreeList(stack->keywords);
stack->keywords=NULL;
+ UnlockIfInitSettings(cs);
stack->flags &= ~DEBUG_ON;
break;
}
+ LockIfInitSettings(cs);
if (rel && is_shared(stack, keywords))
stack->keywords= ListCopy(stack->keywords);
+ UnlockIfInitSettings(cs);
if (sign < 0)
{
if (DEBUGGING)
+ {
+ LockIfInitSettings(cs);
stack->keywords= ListDel(stack->keywords, control, end);
+ UnlockIfInitSettings(cs);
+ }
break;
}
+ LockIfInitSettings(cs);
stack->keywords= ListAdd(stack->keywords, control, end);
+ UnlockIfInitSettings(cs);
stack->flags |= DEBUG_ON;
break;
case 'D':
@@ -997,7 +1025,9 @@ int _db_explain_ (CODE_STATE *cs, char *buf, size_t len)
get_code_state_if_not_set_or_return *buf=0;
+ LockIfInitSettings(cs);
op_list_to_buf('d', cs->stack->keywords, DEBUGGING);
+ UnlockIfInitSettings(cs);
op_int_to_buf ('D', cs->stack->delay, 0);
op_list_to_buf('f', cs->stack->functions, cs->stack->functions);
op_bool_to_buf('F', cs->stack->flags & FILE_ON);
@@ -1578,8 +1608,10 @@ static void PushState(CODE_STATE *cs)
static void FreeState(CODE_STATE *cs, int free_state)
{
struct settings *state= cs->stack;
+ LockIfInitSettings(cs);
if (!is_shared(state, keywords))
FreeList(state->keywords);
+ UnlockIfInitSettings(cs);
if (!is_shared(state, functions))
FreeList(state->functions);
if (!is_shared(state, processes))
@@ -1702,10 +1734,16 @@ FILE *_db_fp_(void)
BOOLEAN _db_keyword_(CODE_STATE *cs, const char *keyword, int strict)
{
int match= strict ? INCLUDE : INCLUDE|MATCHED;
+ BOOLEAN result = FALSE;
get_code_state_if_not_set_or_return FALSE;
- return (DEBUGGING && DoTrace(cs) & DO_TRACE &&
- InList(cs->stack->keywords, keyword, strict) & match);
+ if (!DEBUGGING || !(DoTrace(cs) & DO_TRACE))
+ return FALSE;
+
+ LockIfInitSettings(cs);
+ result= (InList(cs->stack->keywords, keyword, strict) & match) ? TRUE : FALSE;
+ UnlockIfInitSettings(cs);
+ return result;
}
/*