Commit 2855edf9 authored by Eugene Kosov's avatar Eugene Kosov

try to fix data races in DBUG

init_settings.keywords and it's pointee are shared data. Protect them
with mutex too.
parent 6218bf1b
...@@ -320,6 +320,10 @@ static void DbugVfprintf(FILE *stream, const char* format, va_list args); ...@@ -320,6 +320,10 @@ static void DbugVfprintf(FILE *stream, const char* format, va_list args);
*/ */
#include <my_pthread.h> #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 pthread_mutex_t THR_LOCK_dbug;
static void LockMutex(CODE_STATE *cs) static void LockMutex(CODE_STATE *cs)
...@@ -332,6 +336,16 @@ static void UnlockMutex(CODE_STATE *cs) ...@@ -332,6 +336,16 @@ static void UnlockMutex(CODE_STATE *cs)
if (!cs->locked) if (!cs->locked)
pthread_mutex_unlock(&THR_LOCK_dbug); 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) static CODE_STATE *code_state(void)
{ {
...@@ -476,7 +490,9 @@ static int DbugParse(CODE_STATE *cs, const char *control) ...@@ -476,7 +490,9 @@ static int DbugParse(CODE_STATE *cs, const char *control)
stack->sub_level= 0; stack->sub_level= 0;
stack->out_file= sstderr; stack->out_file= sstderr;
stack->functions= NULL; stack->functions= NULL;
LockIfInitSettings(cs);
stack->keywords= NULL; stack->keywords= NULL;
UnlockIfInitSettings(cs);
stack->processes= NULL; stack->processes= NULL;
} }
else if (!stack->out_file) else if (!stack->out_file)
...@@ -492,7 +508,9 @@ static int DbugParse(CODE_STATE *cs, const char *control) ...@@ -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 */ /* never share with the global parent - it can change under your feet */
stack->functions= ListCopy(init_settings.functions); stack->functions= ListCopy(init_settings.functions);
LockIfInitSettings(cs);
stack->keywords= ListCopy(init_settings.keywords); stack->keywords= ListCopy(init_settings.keywords);
UnlockIfInitSettings(cs);
stack->processes= ListCopy(init_settings.processes); stack->processes= ListCopy(init_settings.processes);
} }
else else
...@@ -516,21 +534,31 @@ static int DbugParse(CODE_STATE *cs, const char *control) ...@@ -516,21 +534,31 @@ static int DbugParse(CODE_STATE *cs, const char *control)
case 'd': case 'd':
if (sign < 0 && control == end) if (sign < 0 && control == end)
{ {
LockIfInitSettings(cs);
if (!is_shared(stack, keywords)) if (!is_shared(stack, keywords))
FreeList(stack->keywords); FreeList(stack->keywords);
stack->keywords=NULL; stack->keywords=NULL;
UnlockIfInitSettings(cs);
stack->flags &= ~DEBUG_ON; stack->flags &= ~DEBUG_ON;
break; break;
} }
LockIfInitSettings(cs);
if (rel && is_shared(stack, keywords)) if (rel && is_shared(stack, keywords))
stack->keywords= ListCopy(stack->keywords); stack->keywords= ListCopy(stack->keywords);
UnlockIfInitSettings(cs);
if (sign < 0) if (sign < 0)
{ {
if (DEBUGGING) if (DEBUGGING)
{
LockIfInitSettings(cs);
stack->keywords= ListDel(stack->keywords, control, end); stack->keywords= ListDel(stack->keywords, control, end);
UnlockIfInitSettings(cs);
}
break; break;
} }
LockIfInitSettings(cs);
stack->keywords= ListAdd(stack->keywords, control, end); stack->keywords= ListAdd(stack->keywords, control, end);
UnlockIfInitSettings(cs);
stack->flags |= DEBUG_ON; stack->flags |= DEBUG_ON;
break; break;
case 'D': case 'D':
...@@ -997,7 +1025,9 @@ int _db_explain_ (CODE_STATE *cs, char *buf, size_t len) ...@@ -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; get_code_state_if_not_set_or_return *buf=0;
LockIfInitSettings(cs);
op_list_to_buf('d', cs->stack->keywords, DEBUGGING); op_list_to_buf('d', cs->stack->keywords, DEBUGGING);
UnlockIfInitSettings(cs);
op_int_to_buf ('D', cs->stack->delay, 0); op_int_to_buf ('D', cs->stack->delay, 0);
op_list_to_buf('f', cs->stack->functions, cs->stack->functions); op_list_to_buf('f', cs->stack->functions, cs->stack->functions);
op_bool_to_buf('F', cs->stack->flags & FILE_ON); op_bool_to_buf('F', cs->stack->flags & FILE_ON);
...@@ -1578,8 +1608,10 @@ static void PushState(CODE_STATE *cs) ...@@ -1578,8 +1608,10 @@ static void PushState(CODE_STATE *cs)
static void FreeState(CODE_STATE *cs, int free_state) static void FreeState(CODE_STATE *cs, int free_state)
{ {
struct settings *state= cs->stack; struct settings *state= cs->stack;
LockIfInitSettings(cs);
if (!is_shared(state, keywords)) if (!is_shared(state, keywords))
FreeList(state->keywords); FreeList(state->keywords);
UnlockIfInitSettings(cs);
if (!is_shared(state, functions)) if (!is_shared(state, functions))
FreeList(state->functions); FreeList(state->functions);
if (!is_shared(state, processes)) if (!is_shared(state, processes))
...@@ -1702,10 +1734,16 @@ FILE *_db_fp_(void) ...@@ -1702,10 +1734,16 @@ FILE *_db_fp_(void)
BOOLEAN _db_keyword_(CODE_STATE *cs, const char *keyword, int strict) BOOLEAN _db_keyword_(CODE_STATE *cs, const char *keyword, int strict)
{ {
int match= strict ? INCLUDE : INCLUDE|MATCHED; int match= strict ? INCLUDE : INCLUDE|MATCHED;
BOOLEAN result = FALSE;
get_code_state_if_not_set_or_return FALSE; get_code_state_if_not_set_or_return FALSE;
return (DEBUGGING && DoTrace(cs) & DO_TRACE && if (!DEBUGGING || !(DoTrace(cs) & DO_TRACE))
InList(cs->stack->keywords, keyword, strict) & match); return FALSE;
LockIfInitSettings(cs);
result= (InList(cs->stack->keywords, keyword, strict) & match) ? TRUE : FALSE;
UnlockIfInitSettings(cs);
return result;
} }
/* /*
......
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