Commit 0eef1735 authored by Monty's avatar Monty

Make debug multi thread safe

Fixes crashes in InList when calling _db_set_init (part of SET debug_dbug
in the test suite) from another thread.
parent 07977c13
...@@ -259,7 +259,7 @@ typedef struct _db_code_state_ { ...@@ -259,7 +259,7 @@ typedef struct _db_code_state_ {
#define ListDel(A,B,C) ListAddDel(A,B,C,EXCLUDE) #define ListDel(A,B,C) ListAddDel(A,B,C,EXCLUDE)
static struct link *ListAddDel(struct link *, const char *, const char *, int); static struct link *ListAddDel(struct link *, const char *, const char *, int);
static struct link *ListCopy(struct link *); static struct link *ListCopy(struct link *);
static int InList(struct link *linkp,const char *cp, int exact_match); static int InList(struct link *linkp,const char *cp,int exact_match);
static uint ListFlags(struct link *linkp); static uint ListFlags(struct link *linkp);
static void FreeList(struct link *linkp); static void FreeList(struct link *linkp);
...@@ -458,8 +458,8 @@ static int DbugParse(CODE_STATE *cs, const char *control) ...@@ -458,8 +458,8 @@ static int DbugParse(CODE_STATE *cs, const char *control)
if (!(org_cs_locked= cs->locked)) if (!(org_cs_locked= cs->locked))
{ {
cs->locked= 1;
pthread_mutex_lock(&THR_LOCK_dbug); pthread_mutex_lock(&THR_LOCK_dbug);
cs->locked= 1;
} }
if (control[0] == '-' && control[1] == '#') if (control[0] == '-' && control[1] == '#')
...@@ -666,8 +666,8 @@ static int DbugParse(CODE_STATE *cs, const char *control) ...@@ -666,8 +666,8 @@ static int DbugParse(CODE_STATE *cs, const char *control)
} }
if (!org_cs_locked) if (!org_cs_locked)
{ {
pthread_mutex_unlock(&THR_LOCK_dbug);
cs->locked= 0; cs->locked= 0;
pthread_mutex_unlock(&THR_LOCK_dbug);
} }
return !rel || f_used; return !rel || f_used;
} }
...@@ -1096,7 +1096,7 @@ int _db_explain_init_(char *buf, size_t len) ...@@ -1096,7 +1096,7 @@ int _db_explain_init_(char *buf, size_t len)
void _db_enter_(const char *_func_, const char *_file_, void _db_enter_(const char *_func_, const char *_file_,
uint _line_, struct _db_stack_frame_ *_stack_frame_) uint _line_, struct _db_stack_frame_ *_stack_frame_)
{ {
int save_errno; int save_errno, org_cs_locked;
CODE_STATE *cs; CODE_STATE *cs;
if (!((cs=code_state()))) if (!((cs=code_state())))
{ {
...@@ -1125,12 +1125,20 @@ void _db_enter_(const char *_func_, const char *_file_, ...@@ -1125,12 +1125,20 @@ void _db_enter_(const char *_func_, const char *_file_,
cs->stack->flags &= ~SANITY_CHECK_ON; cs->stack->flags &= ~SANITY_CHECK_ON;
if (TRACING) if (TRACING)
{ {
if (!cs->locked) if (!(org_cs_locked= cs->locked))
{
pthread_mutex_lock(&THR_LOCK_dbug); pthread_mutex_lock(&THR_LOCK_dbug);
cs->locked= 1;
}
DoPrefix(cs, _line_); DoPrefix(cs, _line_);
Indent(cs, cs->level); Indent(cs, cs->level);
(void) fprintf(cs->stack->out_file->file, ">%s\n", cs->func); (void) fprintf(cs->stack->out_file->file, ">%s\n", cs->func);
DbugFlush(cs); /* This does a unlock */ DbugFlush(cs); /* This does a unlock */
if (!org_cs_locked)
{
cs->locked= 0;
pthread_mutex_unlock(&THR_LOCK_dbug);
}
} }
break; break;
case DISABLE_TRACE: case DISABLE_TRACE:
...@@ -1181,16 +1189,25 @@ void _db_return_(struct _db_stack_frame_ *_stack_frame_) ...@@ -1181,16 +1189,25 @@ void _db_return_(struct _db_stack_frame_ *_stack_frame_)
if (DoTrace(cs) & DO_TRACE) if (DoTrace(cs) & DO_TRACE)
{ {
int org_cs_locked;
if ((cs->stack->flags & SANITY_CHECK_ON) && sf_sanity()) if ((cs->stack->flags & SANITY_CHECK_ON) && sf_sanity())
cs->stack->flags &= ~SANITY_CHECK_ON; cs->stack->flags &= ~SANITY_CHECK_ON;
if (TRACING) if (TRACING)
{ {
if (!cs->locked) if (!(org_cs_locked= cs->locked))
{
pthread_mutex_lock(&THR_LOCK_dbug); pthread_mutex_lock(&THR_LOCK_dbug);
cs->locked= 1;
}
DoPrefix(cs, _stack_frame_->line); DoPrefix(cs, _stack_frame_->line);
Indent(cs, cs->level); Indent(cs, cs->level);
(void) fprintf(cs->stack->out_file->file, "<%s\n", cs->func); (void) fprintf(cs->stack->out_file->file, "<%s\n", cs->func);
DbugFlush(cs); DbugFlush(cs);
if (!org_cs_locked)
{
cs->locked= 0;
pthread_mutex_unlock(&THR_LOCK_dbug);
}
} }
} }
/* /*
...@@ -1267,14 +1284,17 @@ void _db_doprnt_(const char *format,...) ...@@ -1267,14 +1284,17 @@ void _db_doprnt_(const char *format,...)
{ {
va_list args; va_list args;
CODE_STATE *cs; CODE_STATE *cs;
int save_errno; int save_errno, org_cs_locked;
get_code_state_or_return; get_code_state_or_return;
va_start(args,format); va_start(args,format);
if (!cs->locked) if (!(org_cs_locked= cs->locked))
{
pthread_mutex_lock(&THR_LOCK_dbug); pthread_mutex_lock(&THR_LOCK_dbug);
cs->locked= 1;
}
save_errno=errno; save_errno=errno;
DoPrefix(cs, cs->u_line); DoPrefix(cs, cs->u_line);
if (TRACING) if (TRACING)
...@@ -1284,6 +1304,11 @@ void _db_doprnt_(const char *format,...) ...@@ -1284,6 +1304,11 @@ void _db_doprnt_(const char *format,...)
(void) fprintf(cs->stack->out_file->file, "%s: ", cs->u_keyword); (void) fprintf(cs->stack->out_file->file, "%s: ", cs->u_keyword);
DbugVfprintf(cs->stack->out_file->file, format, args); DbugVfprintf(cs->stack->out_file->file, format, args);
DbugFlush(cs); DbugFlush(cs);
if (!org_cs_locked)
{
cs->locked= 0;
pthread_mutex_unlock(&THR_LOCK_dbug);
}
errno=save_errno; errno=save_errno;
va_end(args); va_end(args);
...@@ -1323,12 +1348,15 @@ static void DbugVfprintf(FILE *stream, const char* format, va_list args) ...@@ -1323,12 +1348,15 @@ static void DbugVfprintf(FILE *stream, const char* format, va_list args)
void _db_dump_(uint _line_, const char *keyword, void _db_dump_(uint _line_, const char *keyword,
const unsigned char *memory, size_t length) const unsigned char *memory, size_t length)
{ {
int pos; int pos, org_cs_locked;
CODE_STATE *cs; CODE_STATE *cs;
get_code_state_or_return; get_code_state_or_return;
if (!cs->locked) if (!(org_cs_locked= cs->locked))
{
pthread_mutex_lock(&THR_LOCK_dbug); pthread_mutex_lock(&THR_LOCK_dbug);
cs->locked= 1;
}
if (_db_keyword_(cs, keyword, 0)) if (_db_keyword_(cs, keyword, 0))
{ {
DoPrefix(cs, _line_); DoPrefix(cs, _line_);
...@@ -1360,8 +1388,11 @@ void _db_dump_(uint _line_, const char *keyword, ...@@ -1360,8 +1388,11 @@ void _db_dump_(uint _line_, const char *keyword,
(void) fputc('\n',cs->stack->out_file->file); (void) fputc('\n',cs->stack->out_file->file);
DbugFlush(cs); DbugFlush(cs);
} }
else if (!cs->locked) if (!org_cs_locked)
{
cs->locked= 0;
pthread_mutex_unlock(&THR_LOCK_dbug); pthread_mutex_unlock(&THR_LOCK_dbug);
}
} }
...@@ -1509,11 +1540,13 @@ static struct link *ListCopy(struct link *orig) ...@@ -1509,11 +1540,13 @@ static struct link *ListCopy(struct link *orig)
static int InList(struct link *linkp, const char *cp, int exact_match) static int InList(struct link *linkp, const char *cp, int exact_match)
{ {
int result; int result;
for (result=MATCHED; linkp != NULL; linkp= linkp->next_link) for (result=MATCHED; linkp != NULL; linkp= linkp->next_link)
{ {
if (!(exact_match ? strcmp(linkp->str,cp) : fnmatch(linkp->str, cp, 0))) if (!(exact_match ? strcmp(linkp->str,cp) : fnmatch(linkp->str, cp, 0)))
return linkp->flags; {
result= linkp->flags;
break;
}
if (!(linkp->flags & EXCLUDE)) if (!(linkp->flags & EXCLUDE))
result=NOT_MATCHED; result=NOT_MATCHED;
if (linkp->flags & SUBDIR) if (linkp->flags & SUBDIR)
...@@ -1647,6 +1680,7 @@ void _db_end_() ...@@ -1647,6 +1680,7 @@ void _db_end_()
FreeState(cs, 0); FreeState(cs, 0);
pthread_mutex_destroy(&THR_LOCK_dbug); pthread_mutex_destroy(&THR_LOCK_dbug);
init_done= 0; init_done= 0;
_dbug_on_= 0;
} }
...@@ -1665,22 +1699,39 @@ void _db_end_() ...@@ -1665,22 +1699,39 @@ void _db_end_()
static int DoTrace(CODE_STATE *cs) static int DoTrace(CODE_STATE *cs)
{ {
int res= DONT_TRACE;
if (!cs->locked)
pthread_mutex_lock(&THR_LOCK_dbug);
if ((cs->stack->maxdepth == 0 || cs->level <= cs->stack->maxdepth) && if ((cs->stack->maxdepth == 0 || cs->level <= cs->stack->maxdepth) &&
InList(cs->stack->processes, cs->process, 0) & (MATCHED|INCLUDE)) InList(cs->stack->processes, cs->process, 0) & (MATCHED|INCLUDE))
{
switch(InList(cs->stack->functions, cs->func, 0)) { switch(InList(cs->stack->functions, cs->func, 0)) {
case INCLUDE|SUBDIR: return ENABLE_TRACE; case INCLUDE|SUBDIR:
case INCLUDE: return DO_TRACE; res= ENABLE_TRACE;
break;
case INCLUDE:
res= DO_TRACE;
break;
case MATCHED|SUBDIR: case MATCHED|SUBDIR:
case NOT_MATCHED|SUBDIR: case NOT_MATCHED|SUBDIR:
case MATCHED: return framep_trace_flag(cs, cs->framep) ? case MATCHED:
DO_TRACE : DONT_TRACE; res= (framep_trace_flag(cs, cs->framep) ? DO_TRACE : DONT_TRACE);
break;
case EXCLUDE: case EXCLUDE:
case NOT_MATCHED: return DONT_TRACE; case NOT_MATCHED:
case EXCLUDE|SUBDIR: return DISABLE_TRACE; res= DONT_TRACE;
break;
case EXCLUDE|SUBDIR:
res= DISABLE_TRACE;
break;
} }
return DONT_TRACE; }
if (!cs->locked)
pthread_mutex_unlock(&THR_LOCK_dbug);
return res;
} }
FILE *_db_fp_(void) FILE *_db_fp_(void)
{ {
CODE_STATE *cs; CODE_STATE *cs;
...@@ -1711,10 +1762,17 @@ FILE *_db_fp_(void) ...@@ -1711,10 +1762,17 @@ 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;
int res;
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 0;
if (!cs->locked)
pthread_mutex_lock(&THR_LOCK_dbug);
res= (InList(cs->stack->keywords, keyword, strict) & match);
if (!cs->locked)
pthread_mutex_unlock(&THR_LOCK_dbug);
return res != 0;
} }
/* /*
...@@ -2130,8 +2188,6 @@ static void DbugFlush(CODE_STATE *cs) ...@@ -2130,8 +2188,6 @@ static void DbugFlush(CODE_STATE *cs)
if (cs->stack->delay) if (cs->stack->delay)
(void) Delay(cs->stack->delay); (void) Delay(cs->stack->delay);
} }
if (!cs->locked)
pthread_mutex_unlock(&THR_LOCK_dbug);
} /* DbugFlush */ } /* DbugFlush */
...@@ -2141,9 +2197,15 @@ void _db_flush_() ...@@ -2141,9 +2197,15 @@ void _db_flush_()
{ {
CODE_STATE *cs; CODE_STATE *cs;
get_code_state_or_return; get_code_state_or_return;
(void) fflush(cs->stack->out_file->file); if (DEBUGGING)
{
pthread_mutex_lock(&THR_LOCK_dbug);
(void) fflush(cs->stack->out_file->file);
pthread_mutex_unlock(&THR_LOCK_dbug);
}
} }
#ifndef __WIN__ #ifndef __WIN__
void _db_suicide_() void _db_suicide_()
{ {
......
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