Package: libmysqlclient15off
Version: 5.0.32-3

Using libmysqlclient in multi-threaded enviroments like java can result in:
#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
#  SIGILL (0x4) at pc=0x00000000, pid=10933, tid=2877021104
#
# Java VM: Java HotSpot(TM) Client VM (Blackdown-1.4.2-03 mixed mode)
# An error report file with more information is saved as hs_err_pid10933.log
#
# If you would like to submit a bug report, please visit:
#   http://www.blackdown.org/cgi-bin/jdk
#

After two days finding the bug. i discovered that in the taocrypt library included in libmysql are calls to signal(...).

In the signal(2) Manual Page. Section NOTES says: "The effects of this call in a multi-threaded process are unspecified..." (indeed is true)

My modest solution is to relace signal(...) with pthread_sigmask(...) and sigaction(...)

Attached is the patch

Thanks.
PD: Sorry form my poor english.

diff -Nrau mysql-dfsg-5.0-5.0.32.orig/extra/yassl/taocrypt/src/integer.cpp mysql-dfsg-5.0-5.0.32/extra/yassl/taocrypt/src/integer.cpp
--- mysql-dfsg-5.0-5.0.32.orig/extra/yassl/taocrypt/src/integer.cpp	2006-12-20 08:13:59.000000000 -0300
+++ mysql-dfsg-5.0-5.0.32/extra/yassl/taocrypt/src/integer.cpp	2007-02-22 15:21:04.000000000 -0300
@@ -1050,11 +1050,21 @@
     }
     return true;
 #else
-    typedef void (*SigHandler)(int);
+    struct sigaction sigact,sigoldact;
+    memset(&sigact,0,sizeof(sigact));
+    sigact.sa_handler=SigIllHandler;
+    sigemptyset(&sigact.sa_mask);
+    if(0!=sigaction(SIGILL,&sigact,&sigoldact)) return false;
+
+    sigset_t newmask,oldmask;
+    sigemptyset(&newmask);
+    sigaddset(&newmask,SIGILL);
 
-    SigHandler oldHandler = signal(SIGILL, SigIllHandler);
-    if (oldHandler == SIG_ERR)
+    if(0!=pthread_sigmask(SIG_UNBLOCK,&newmask,&oldmask))
+    {
+        sigaction(SIGILL,&sigoldact,NULL);
         return false;
+    }
 
     bool result = true;
     if (setjmp(s_env))
@@ -1062,7 +1072,11 @@
     else
         __asm __volatile ("xorpd %xmm0, %xmm0");
 
-    signal(SIGILL, oldHandler);
+    if(sigismember(&oldmask,SIGILL))
+    {
+        pthread_sigmask(SIG_BLOCK,&newmask,NULL);
+    }
+    sigaction(SIGILL,&sigoldact,NULL);
     return result;
 #endif
 }
diff -Nrau mysql-dfsg-5.0-5.0.32.orig/extra/yassl/taocrypt/src/misc.cpp mysql-dfsg-5.0-5.0.32/extra/yassl/taocrypt/src/misc.cpp
--- mysql-dfsg-5.0-5.0.32.orig/extra/yassl/taocrypt/src/misc.cpp	2006-12-20 08:14:34.000000000 -0300
+++ mysql-dfsg-5.0-5.0.32/extra/yassl/taocrypt/src/misc.cpp	2007-02-22 15:20:57.000000000 -0300
@@ -199,11 +199,22 @@
     }
     return true;
 #else
-    typedef void (*SigHandler)(int);
 
-    SigHandler oldHandler = signal(SIGILL, SigIllHandler);
-    if (oldHandler == SIG_ERR)
+    struct sigaction sigact,sigoldact;
+    memset(&sigact,0,sizeof(sigact));
+    sigact.sa_handler=SigIllHandler;
+    sigemptyset(&sigact.sa_mask);
+    if(0!=sigaction(SIGILL,&sigact,&sigoldact)) return false;
+
+    sigset_t newmask,oldmask;
+    sigemptyset(&newmask);
+    sigaddset(&newmask,SIGILL);
+
+    if(0!=pthread_sigmask(SIG_UNBLOCK,&newmask,&oldmask))
+    {
+        sigaction(SIGILL,&sigoldact,NULL);
         return false;
+    }
 
     bool result = true;
     if (setjmp(s_env))
@@ -218,7 +229,11 @@
             : "%eax", "%ecx", "%edx" 
         );
 
-    signal(SIGILL, oldHandler);
+    if(sigismember(&oldmask,SIGILL))
+    {
+        pthread_sigmask(SIG_BLOCK,&newmask,NULL);
+    }
+    sigaction(SIGILL,&sigoldact,NULL);
     return result;
 #endif
 }

Reply via email to