Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2e062b6

Browse files
committed
Remove race conditions between ECPGdebug() and ecpg_log().
Coverity complains that ECPGdebug is accessing debugstream withoutholding debug_mutex, which is a fair complaint: we should takedebug_mutex while changing the settings ecpg_log looks at.In some branches it also complains about unlocked use of simple_debug.I think it's intentional and safe to have a quick unlocked check ofsimple_debug at the start of ecpg_log, since that early exit willalways be taken in non-debug cases. But we should rechecksimple_debug after acquiring the mutex. In the worst case, callingECPGdebug concurrently with ecpg_log in another thread could resultin a null-pointer dereference due to debugstream transiently beingNULL while simple_debug isn't 0.This is largely hypothetical, since it's unlikely anybody usesECPGdebug() at all in the field, and our own regression testsdon't seem to be hitting the theoretical race conditions either.Still, if we're going to the trouble of having mutexes here, we oughtto be using them in a way that's actually safe not just almost safe.Hence, back-patch to all supported branches.
1 parent0c6b649 commit2e062b6

File tree

1 file changed

+30
-11
lines changed
  • src/interfaces/ecpg/ecpglib

1 file changed

+30
-11
lines changed

‎src/interfaces/ecpg/ecpglib/misc.c

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ static struct sqlca_t sqlca =
9191
staticpthread_mutex_tdebug_mutex=PTHREAD_MUTEX_INITIALIZER;
9292
staticpthread_mutex_tdebug_init_mutex=PTHREAD_MUTEX_INITIALIZER;
9393
#endif
94-
staticintsimple_debug=0;
94+
staticvolatileintsimple_debug=0;
9595
staticFILE*debugstream=NULL;
9696

9797
void
@@ -242,7 +242,11 @@ void
242242
ECPGdebug(intn,FILE*dbgs)
243243
{
244244
#ifdefENABLE_THREAD_SAFETY
245+
/* Interlock against concurrent executions of ECPGdebug() */
245246
pthread_mutex_lock(&debug_init_mutex);
247+
248+
/* Prevent ecpg_log() from printing while we change settings */
249+
pthread_mutex_lock(&debug_mutex);
246250
#endif
247251

248252
if (n>100)
@@ -255,6 +259,12 @@ ECPGdebug(int n, FILE *dbgs)
255259

256260
debugstream=dbgs;
257261

262+
/* We must release debug_mutex before invoking ecpg_log() ... */
263+
#ifdefENABLE_THREAD_SAFETY
264+
pthread_mutex_unlock(&debug_mutex);
265+
#endif
266+
267+
/* ... but keep holding debug_init_mutex to avoid racy printout */
258268
ecpg_log("ECPGdebug: set to %d\n",simple_debug);
259269

260270
#ifdefENABLE_THREAD_SAFETY
@@ -271,6 +281,11 @@ ecpg_log(const char *format,...)
271281
intbufsize;
272282
char*fmt;
273283

284+
/*
285+
* For performance reasons, inspect simple_debug without taking the mutex.
286+
* This could be problematic if fetching an int isn't atomic, but we
287+
* assume that it is in many other places too.
288+
*/
274289
if (!simple_debug)
275290
return;
276291

@@ -295,18 +310,22 @@ ecpg_log(const char *format,...)
295310
pthread_mutex_lock(&debug_mutex);
296311
#endif
297312

298-
va_start(ap,format);
299-
vfprintf(debugstream,fmt,ap);
300-
va_end(ap);
301-
302-
/* dump out internal sqlca variables */
303-
if (ecpg_internal_regression_mode&&sqlca!=NULL)
313+
/* Now that we hold the mutex, recheck simple_debug */
314+
if (simple_debug)
304315
{
305-
fprintf(debugstream,"[NO_PID]: sqlca: code: %ld, state: %s\n",
306-
sqlca->sqlcode,sqlca->sqlstate);
307-
}
316+
va_start(ap,format);
317+
vfprintf(debugstream,fmt,ap);
318+
va_end(ap);
308319

309-
fflush(debugstream);
320+
/* dump out internal sqlca variables */
321+
if (ecpg_internal_regression_mode&&sqlca!=NULL)
322+
{
323+
fprintf(debugstream,"[NO_PID]: sqlca: code: %ld, state: %s\n",
324+
sqlca->sqlcode,sqlca->sqlstate);
325+
}
326+
327+
fflush(debugstream);
328+
}
310329

311330
#ifdefENABLE_THREAD_SAFETY
312331
pthread_mutex_unlock(&debug_mutex);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp