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. Patch backported from 10.3
This commit is contained in:
parent
5144861be9
commit
550c8bdb81
107
dbug/dbug.c
107
dbug/dbug.c
@ -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)
|
|||||||
}
|
}
|
||||||
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)
|
|||||||
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_,
|
|||||||
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_)
|
|||||||
|
|
||||||
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,...)
|
|||||||
{
|
{
|
||||||
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,...)
|
|||||||
(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)
|
|||||||
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,9 +1388,12 @@ 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)
|
|||||||
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_()
|
|||||||
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,21 +1699,38 @@ 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)
|
||||||
{
|
{
|
||||||
@ -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)
|
|||||||
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,7 +2197,12 @@ void _db_flush_()
|
|||||||
{
|
{
|
||||||
CODE_STATE *cs;
|
CODE_STATE *cs;
|
||||||
get_code_state_or_return;
|
get_code_state_or_return;
|
||||||
|
if (DEBUGGING)
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&THR_LOCK_dbug);
|
||||||
(void) fflush(cs->stack->out_file->file);
|
(void) fflush(cs->stack->out_file->file);
|
||||||
|
pthread_mutex_unlock(&THR_LOCK_dbug);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user