Protect stack->keywords with THR_LOCK_dbug

This solves a core dump in MariaDB when one sets the GLOBAL.DEBUG variable in mysql-test-run when other threads are checking the keyword list

dbug/dbug.c:
  Protect stack->keywords with THR_LOCK_dbug
This commit is contained in:
Michael Widenius 2009-12-07 02:52:40 +02:00
parent 6dd90cc9b3
commit f6b6ae912c

View file

@ -497,12 +497,18 @@ int DbugParse(CODE_STATE *cs, const char *control)
const char *end; const char *end;
int rel, f_used=0; int rel, f_used=0;
struct settings *stack; struct settings *stack;
int org_cs_locked;
stack= cs->stack; stack= cs->stack;
if (!(org_cs_locked= cs->locked))
{
cs->locked= 1;
pthread_mutex_lock(&THR_LOCK_dbug);
}
if (control[0] == '-' && control[1] == '#') if (control[0] == '-' && control[1] == '#')
control+=2; control+=2;
rel= control[0] == '+' || control[0] == '-'; rel= control[0] == '+' || control[0] == '-';
if ((!rel || (!stack->out_file && !stack->next))) if ((!rel || (!stack->out_file && !stack->next)))
{ {
@ -550,9 +556,11 @@ int DbugParse(CODE_STATE *cs, const char *control)
while (control < end) while (control < end)
{ {
int c, sign= (*control == '+') ? 1 : (*control == '-') ? -1 : 0; int c, sign= (*control == '+') ? 1 : (*control == '-') ? -1 : 0;
if (sign) control++; if (sign)
control++;
c= *control++; c= *control++;
if (*control == ',') control++; if (*control == ',')
control++;
/* XXX when adding new cases here, don't forget _db_explain_ ! */ /* XXX when adding new cases here, don't forget _db_explain_ ! */
switch (c) { switch (c) {
case 'd': case 'd':
@ -718,8 +726,13 @@ int DbugParse(CODE_STATE *cs, const char *control)
control=end+1; control=end+1;
end= DbugStrTok(control); end= DbugStrTok(control);
} }
return !rel || f_used; if (!org_cs_locked)
{
pthread_mutex_unlock(&THR_LOCK_dbug);
cs->locked= 0;
} }
return !rel || f_used;}
#define framep_trace_flag(cs, frp) (frp ? \ #define framep_trace_flag(cs, frp) (frp ? \
frp->level & TRACE_ON : \ frp->level & TRACE_ON : \
@ -1340,11 +1353,11 @@ void _db_doprnt_(const char *format,...)
va_start(args,format); va_start(args,format);
if (!cs->locked)
pthread_mutex_lock(&THR_LOCK_dbug);
if (_db_keyword_(cs, cs->u_keyword, 0)) if (_db_keyword_(cs, cs->u_keyword, 0))
{ {
int save_errno=errno; int save_errno=errno;
if (!cs->locked)
pthread_mutex_lock(&THR_LOCK_dbug);
DoPrefix(cs, cs->u_line); DoPrefix(cs, cs->u_line);
if (TRACING) if (TRACING)
Indent(cs, cs->level + 1); Indent(cs, cs->level + 1);
@ -1356,6 +1369,9 @@ void _db_doprnt_(const char *format,...)
DbugFlush(cs); DbugFlush(cs);
errno=save_errno; errno=save_errno;
} }
else if (!cs->locked)
pthread_mutex_unlock(&THR_LOCK_dbug);
va_end(args); va_end(args);
} }
@ -1386,10 +1402,10 @@ void _db_dump_(uint _line_, const char *keyword,
CODE_STATE *cs; CODE_STATE *cs;
get_code_state_or_return; get_code_state_or_return;
if (_db_keyword_(cs, keyword, 0))
{
if (!cs->locked) if (!cs->locked)
pthread_mutex_lock(&THR_LOCK_dbug); pthread_mutex_lock(&THR_LOCK_dbug);
if (_db_keyword_(cs, keyword, 0))
{
DoPrefix(cs, _line_); DoPrefix(cs, _line_);
if (TRACING) if (TRACING)
{ {
@ -1420,6 +1436,8 @@ void _db_dump_(uint _line_, const char *keyword,
(void) fputc('\n',cs->stack->out_file); (void) fputc('\n',cs->stack->out_file);
DbugFlush(cs); DbugFlush(cs);
} }
else if (!cs->locked)
pthread_mutex_unlock(&THR_LOCK_dbug);
} }
@ -2105,6 +2123,7 @@ static void DBUGCloseFile(CODE_STATE *cs, FILE *fp)
{ {
if (fp != stderr && fp != stdout && fclose(fp) == EOF) if (fp != stderr && fp != stdout && fclose(fp) == EOF)
{ {
if (!cs->locked)
pthread_mutex_lock(&THR_LOCK_dbug); pthread_mutex_lock(&THR_LOCK_dbug);
(void) fprintf(cs->stack->out_file, ERR_CLOSE, cs->process); (void) fprintf(cs->stack->out_file, ERR_CLOSE, cs->process);
perror(""); perror("");