]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Modify the sqlite3_log() interface and implementation so that it never uses
authordrh <drh@noemail.net>
Wed, 3 Mar 2010 22:40:09 +0000 (22:40 +0000)
committerdrh <drh@noemail.net>
Wed, 3 Mar 2010 22:40:09 +0000 (22:40 +0000)
dynamic memory allocation - to avoid deadlocking when called while holding
the memory allocator mutex.  Cherry-pick merge of [28d1bc98d6].

FossilOrigin-Name: 6f368b5448363ae497bd4ff49b4ceeafb27f8cb3

manifest
manifest.uuid
src/printf.c
src/sqlite.h.in

index 5559317755f238de50ad7ddefb8ff8925bb46ac6..5c55939792b7aa4edfbc2c03d61f93ff9c30b274 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,8 +1,8 @@
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1
 
-C When\sTEMP\sfiles\sare\sin\smemory,\salso\sput\sthe\smassive\sTEMP\sfile\sused\sby\nthe\sVACUUM\scommand\sin\smemory.\s\sThis\sis\sa\scherry-pick\smerge\sof\n[9daf4e7d07]
-D 2010-03-03T00:02:58
+C Modify\sthe\ssqlite3_log()\sinterface\sand\simplementation\sso\sthat\sit\snever\suses\ndynamic\smemory\sallocation\s-\sto\savoid\sdeadlocking\swhen\scalled\swhile\sholding\s\nthe\smemory\sallocator\smutex.\s\sCherry-pick\smerge\sof\s[28d1bc98d6].
+D 2010-03-03T22:40:10
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in c5827ead754ab32b9585487177c93bb00b9497b3
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -161,13 +161,13 @@ F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
 F src/pcache1.c 2bb2261190b42a348038f5b1c285c8cef415fcc8
 F src/pragma.c f37f33665b02447d83669620ddc1fd4fd1f70b0a
 F src/prepare.c dede8f2d7f5810cea08ab7a4ced02fcc2d6478e9
-F src/printf.c ed476ea406ce79dec397268ef9035f914ee40453
+F src/printf.c 7c2ae3a3c1833691bfbeed85f75125d8752b278e
 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
 F src/resolve.c 8e51ac017123b86f35de30ccdb0f18c73963c979
 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
 F src/select.c 0109b993c360d649857523abb72919e1794f9b45
 F src/shell.c 546fe4b6df101c6cc3d08aa7b7b414136ce03ffc
-F src/sqlite.h.in 37d8930135ae33ac8f122351df0bc6c4d979ab61
+F src/sqlite.h.in e8e40f18450884f2693f330ff5956fd920678fd1
 F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89
 F src/sqliteInt.h 4d7df175023a23232cc0abc07b51081ef9a61cec
 F src/sqliteLimit.h 3afab2291762b5d09ae20c18feb8e9fa935a60a6
@@ -787,14 +787,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P b8fbf4275bded6680e368a6a8343866467bd7e22
-R 8d3fb3450b9039abffe355510b2ce9e1
+P e5342234357dcfde33fb7589f87d64f6de7d9970
+R 01beb709cf7bc8e3972a5b032e7b971a
 U drh
-Z f181595e67ffa01f9304a3649d1c0172
+Z 0d66440290a8834e0da1130d7723d7df
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.6 (GNU/Linux)
 
-iD8DBQFLjac1oxKgR168RlERAk6eAJ0YE+odWO/gkCH53A7tOKqbbQSrfwCdFSCy
-ReHe9787/6uuebRnSKK4zco=
-=zWwd
+iD8DBQFLjuVOoxKgR168RlERAgTuAJ4qlt0mKQUYvcO4Xl9vNMna3dxhcgCfcVYt
+H1/v9Io9D3GEbLQlwd992Nk=
+=ii3q
 -----END PGP SIGNATURE-----
index ea970c2f2c3a14aaa46e6230ea02b4e0a884ba2a..77bb9495b1076951c2f02043abb0fdef84684714 100644 (file)
@@ -1 +1 @@
-e5342234357dcfde33fb7589f87d64f6de7d9970
\ No newline at end of file
+6f368b5448363ae497bd4ff49b4ceeafb27f8cb3
\ No newline at end of file
index 497aaf61943548bdb335c95f1a1b8996612c7126..a1534cb4e735742c0015e553f48db11b2029efa6 100644 (file)
@@ -937,25 +937,39 @@ char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
   return z;
 }
 
+/*
+** This is the routine that actually formats the sqlite3_log() message.
+** We house it in a separate routine from sqlite3_log() to avoid using
+** stack space on small-stack systems when logging is disabled.
+**
+** sqlite3_log() must render into a static buffer.  It cannot dynamically
+** allocate memory because it might be called while the memory allocator
+** mutex is held.
+*/
+static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){
+  StrAccum acc;                           /* String accumulator */
+#ifdef SQLITE_SMALL_STACK
+  char zMsg[150];                         /* Complete log message */
+#else
+  char zMsg[400];                         /* Complete log message */
+#endif
+
+  sqlite3StrAccumInit(&acc, zMsg, sizeof(zMsg), 0);
+  acc.useMalloc = 0;
+  sqlite3VXPrintf(&acc, 0, zFormat, ap);
+  sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
+                           sqlite3StrAccumFinish(&acc));
+}
+
 /*
 ** Format and write a message to the log if logging is enabled.
 */
 void sqlite3_log(int iErrCode, const char *zFormat, ...){
-  void (*xLog)(void*, int, const char*);  /* The global logger function */
-  void *pLogArg;                          /* First argument to the logger */
   va_list ap;                             /* Vararg list */
-  char *zMsg;                             /* Complete log message */
-  
-  xLog = sqlite3GlobalConfig.xLog;
-  if( xLog && zFormat ){
+  if( sqlite3GlobalConfig.xLog ){
     va_start(ap, zFormat);
-    sqlite3BeginBenignMalloc();
-    zMsg = sqlite3_vmprintf(zFormat, ap);
-    sqlite3EndBenignMalloc();
+    renderLogMsg(iErrCode, zFormat, ap);
     va_end(ap);
-    pLogArg = sqlite3GlobalConfig.pLogArg;
-    xLog(pLogArg, iErrCode, zMsg ? zMsg : zFormat);
-    sqlite3_free(zMsg);
   }
 }
 
index bbeafa9d3cb4f9ad8abec67224fae66432ec9bae..dfc6a0ac5d819c31507b8d22abcfc023eefa6f74 100644 (file)
@@ -5653,6 +5653,12 @@ int sqlite3_strnicmp(const char *, const char *, int);
 ** virtual tables, collating functions, and SQL functions.  While there is
 ** nothing to prevent an application from calling sqlite3_log(), doing so
 ** is considered bad form.
+**
+** To avoid deadlocks and other threading problems, the sqlite3_log() routine
+** will not use dynamically allocated memory.  The log message is stored in
+** a fixed-length buffer on the stack.  If the log message is longer than
+** a few hundred characters, it will be truncated to the length of the
+** buffer.
 */
 void sqlite3_log(int iErrCode, const char *zFormat, ...);