From: Olav Sandstaa Date: March 2 2009 2:53pm Subject: bzr commit into mysql-6.0-falcon-team branch (olav:3043) Bug#40155 List-Archive: http://lists.mysql.com/commits/68000 X-Bug: 40155 Message-Id: <20090302145308.27298.qmail@fimafeng08> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit #At file:///home/os136802/mysql/develop/repo/falcon-bug40155/ based on revid:vvaintroub@stripped 3043 Olav Sandstaa 2009-03-02 Fix to Bug #40155 Error: assertion (ret == 0) failed at line 80 in file Mutex.cpp This crash was due to the Memory manager trying to lock the same mutex twice. It happened when the server run out of memory. The memory manager handles this by throwing an exception. Unfortunatly, when creating this exception there there was call both the Log and the JString class that did allocate memory leading to the second call to the memory manager's mutex. This patch fixes this by: -SQLError exception do not longer call the Log if the error code is out-of-memory -SQLError use an new method on JString that does not allocate memory for the text but just stores the pointer to the existing string In addition the memory manager now writes a message directly to stderr when it runs out of memory. modified: storage/falcon/JString.cpp storage/falcon/JString.h storage/falcon/MemMgr.cpp storage/falcon/SQLError.cpp storage/falcon/SQLError.h per-file messages: storage/falcon/JString.cpp Support for using an external string instead of copying the string to an internal buffer. This is done to avoid having to allocate space in the JString object in situations where Falcon have run out of memory. storage/falcon/JString.h Add a method for setting the JSTring's string to use an externally allocated string storage/falcon/MemMgr.cpp Write an error message to stderr when the memory manager is uanble to allocate more memory. storage/falcon/SQLError.cpp Special handle the OUT_OF_MEMORY_ERROR code so that this is handled without allocating memory. === modified file 'storage/falcon/JString.cpp' === modified file 'storage/falcon/JString.cpp' --- a/storage/falcon/JString.cpp 2008-04-09 01:36:46 +0000 +++ b/storage/falcon/JString.cpp 2009-03-02 14:52:49 +0000 @@ -56,6 +56,7 @@ **************************************/ string = NULL; + staticString = false; } JString::JString (const char *stuff) @@ -72,6 +73,7 @@ **************************************/ string = NULL; + staticString = false; setString (stuff); } @@ -90,6 +92,7 @@ if ((string = source.string)) ++((int*) string)[-1]; + staticString = false; } JString::~JString () @@ -349,6 +352,13 @@ if (!string) return; + if (staticString) + { + string = NULL; + staticString = false; + return; + } + string -= sizeof (int); if (--((int*) string)[0] == 0) @@ -469,6 +479,13 @@ { alloc (length); memcpy (string, source, length); + staticString = false; +} + +void JString::setStringStatic(const char* source) +{ + string = const_cast(source); + staticString = true; } int JString::findSubstring(const char * string, const char * sub) === modified file 'storage/falcon/JString.h' --- a/storage/falcon/JString.h 2007-10-23 20:50:22 +0000 +++ b/storage/falcon/JString.h 2009-03-02 14:52:49 +0000 @@ -130,6 +130,7 @@ void append (const char*, int length); void setString (const char*); void setString (const char *source, int length); + void setStringStatic (const char *source); void Format (const char*, ...); inline const char *getString() @@ -155,6 +156,7 @@ void release(); char *string; + bool staticString; }; === modified file 'storage/falcon/MemMgr.cpp' --- a/storage/falcon/MemMgr.cpp 2009-02-23 22:42:36 +0000 +++ b/storage/falcon/MemMgr.cpp 2009-03-02 14:52:49 +0000 @@ -702,6 +702,9 @@ void* MemMgr::memoryIsExhausted(void) { #ifdef FALCONDB + fprintf(stderr, "[ERROR] Falcon: Memory is exhausted\n"); + fflush(stderr); + Log::logBreak ("Memory is exhausted\n"); #endif === modified file 'storage/falcon/SQLError.cpp' --- a/storage/falcon/SQLError.cpp 2008-06-19 15:09:45 +0000 +++ b/storage/falcon/SQLError.cpp 2009-03-02 14:52:49 +0000 @@ -59,8 +59,15 @@ if (vsnprintf (temp, sizeof (temp) - 1, txt, args) < 0) temp [sizeof (temp) - 1] = 0; - text = temp; - error (temp); + // Special handle how we deal with the error string for out-of-memory + // errors + + if (code != OUT_OF_MEMORY_ERROR) + text = temp; + else + text.setStringStatic(txt); + + error (code, temp); sqlcode = (int) code; } @@ -76,6 +83,8 @@ * SQL exception -- quite generic. * **************************************/ + ASSERT(code != OUT_OF_MEMORY_ERROR); + va_list args; va_start (args, txt); char temp [1024]; @@ -88,7 +97,7 @@ temp [sizeof (temp) - 1] = 0; text = temp; - error (temp); + error (code, temp); sqlcode = (int) code; } @@ -166,7 +175,7 @@ temp [sizeof (temp) - 1] = 0; text = temp; - error (temp); + error (code, temp); sqlcode = (int) code; } @@ -175,11 +184,25 @@ return stackTrace; } -void SQLError::error(const char *string) +void SQLError::error(int code, const char *string) { #ifdef FALCONDB - LogLock logLock; - Log::log(LogException, "Exception: %s\n", string); + if (Log::isActive(LogException)) + { + // We special handle out-memory-errors in order to avoid that a + // call to the Log will generate a new call back to the memory manager + + if (code != OUT_OF_MEMORY_ERROR) + { + LogLock logLock; + Log::log(LogException, "Exception: %s\n", string); + } + else + { + fprintf(stderr, "Falcon: Exception: %s\n", string); + fflush(stderr); + } + } #endif } === modified file 'storage/falcon/SQLError.h' --- a/storage/falcon/SQLError.h 2007-09-20 15:44:25 +0000 +++ b/storage/falcon/SQLError.h 2009-03-02 14:52:49 +0000 @@ -53,7 +53,7 @@ JString objectName; private: - void error (const char *string); + void error (int sqlcode, const char *string); }; #endif