List:Internals« Previous MessageNext Message »
From:Vasil Dimov Date:September 29 2006 2:10pm
Subject:dbug/factorial getting SIGBUS during build (5.0.26-BK)
View as plain text  
Hi,

I intend to submit this as a bug but I want to discuss it here first.

Here is a detailed description of the problem and 2 possible solutions:

On a fresh 5.0 source tree (5.0.26 from BK actually) I:
* ran the autotools, nothing relevant to the problem in that
* ./configure
* make

and I noticed some programs crashing during the build:

...
./factorial 1 2 3 4 5 | cat > output1.r
Bus error (core dumped)
./factorial -\#t:o 2 3 | cat >output2.r
Bus error (core dumped)
./factorial -\#d:t:o 3 | cat >output3.r
Bus error (core dumped)
./factorial -\#d,result:o 4 | cat >output4.r
Bus error (core dumped)
./factorial -\#d:f,factorial:F:L:o 3 | cat >output5.r
Bus error (core dumped)
...

Further investigation showed this:

% gdb factorial
...
Program received signal SIGBUS, Bus error.
0x00000000004018a8 in _db_enter_ (_func_=0x40307c "main",
    _file_=0x403072 "my_main.c", _line_=26, _sfunc_=0x7fffffffea78,
    _sfile_=0x7fffffffea70, _slevel_=0x7fffffffea6c, _sframep_=0x7fffffffea60)
    at dbug.c:710
709         *_sfunc_ = state->func;
(gdb) bt
#0  0x00000000004018a8 in _db_enter_ (_func_=0x40307c "main",
    _file_=0x403072 "my_main.c", _line_=26, _sfunc_=0x7fffffffea78,
    _sfile_=0x7fffffffea70, _slevel_=0x7fffffffea6c, _sframep_=0x7fffffffea60)
    at dbug.c:709
#1  0x00000000004011a5 in main (argc=1, argv=0x7fffffffead0) at my_main.c:26
(gdb) ins state
$8 = (CODE_STATE *) 0xd0d0d0d0d0d0d0d0

so it is a bogus pointer dereferencing problem here:

dbug/dbug.c:_db_enter_():
709:    *_sfunc_ = state->func;  // state==0xd0d0d0d0d0d0d0d0

``state'' is initialized here:

dbug/dbug.c:_db_enter_():
704:    if (!(state=code_state()))  // code_state() returns 0xd0d0d0d0d0d0d0d0

looking at code_state() I found this:

dbug/dbug.c:354:code_state():
354:  struct st_my_thread_var *tmp=my_thread_var;
...
357:    if (!(state=(CODE_STATE *) tmp->dbug))
...
366:  return state;

So actually tmp->dbug is 0xd0d0d0d0d0d0d0d0 here

Going further down the chain to the ``tmp'' allocation:

my_thread_var is defined to be _my_thread_var here:

include/my_pthread.h:
680:#define my_thread_var (_my_thread_var())

and here is the body of _my_thread_var:

mysys/my_thr_init.c:_my_thread_var():
239:  struct st_my_thread_var *tmp=
240:    my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);

This thing is allocated and fired out with pthread_setspecific() here:

mysys/my_thr_init.c:my_thread_init():
170:  if (!(tmp= (struct st_my_thread_var *) calloc(1, sizeof(*tmp))))
...
175:  pthread_setspecific(THR_KEY_mysys,tmp);

So this variable is allocated at mysys/my_thr_init.c:170.

Looking at ``struct st_my_thread_var'' definition one can see that
``dbug'' and ``name'' members are present only when DBUG_OFF is not
defined:

include/my_pthread.h:
659:struct st_my_thread_var
660:{
...
673:#ifndef DBUG_OFF
674:  gptr dbug;
675:  char name[THREAD_NAME_SIZE+1];
676:#endif

So the thing is that when the code is compiled with DBUG_OFF
(the default) these members are not present in the code that allocates
the space *but* dbug/dbug.c says in its very beginning:

69:#ifdef DBUG_OFF
70:#undef DBUG_OFF
71:#endif

and expects ``dbug'' member to be present. Here is another cut from a
gdb session which shows the core of the problem:

% gdb factorial
(gdb) b code_state
Breakpoint 1 at 0x4013b8: file dbug.c, line 354.
(gdb) b my_thr_init.c:170
Breakpoint 2 at 0x402bb8: file my_thr_init.c, line 170.
...
Breakpoint 2, my_thread_init () at my_thr_init.c:170
170       if (!(tmp= (struct st_my_thread_var *) calloc(1, sizeof(*tmp))))
(gdb) ins sizeof(struct st_my_thread_var)
$3 = 96
(gdb) n
180       pthread_setspecific(THR_KEY_mysys,tmp);
(gdb) ins tmp
$4 = (struct st_my_thread_var *) 0x505880
(gdb) ins *tmp
$5 = {thr_errno = 0, suspend = 0x0, mutex = 0x0, current_mutex = 0x0,
  current_cond = 0x0, pthread_self = 0x0, id = 0, cmp_length = 0, abort = 0,
  init = 0 '\0', next = 0x0, prev = 0x0, opt_info = 0x0}
(gdb) c
Continuing.

Breakpoint 1, code_state () at dbug.c:354
354       CODE_STATE *state=0;
(gdb) ins sizeof(struct st_my_thread_var)
$6 = 120
(gdb) n
355       struct st_my_thread_var *tmp=my_thread_var;
(gdb) n
356       if (tmp)
(gdb) n
358         if (!(state=(CODE_STATE *) tmp->dbug))
(gdb) ins *tmp
$7 = {thr_errno = 0, suspend = 0x505980, mutex = 0x505900,
  current_mutex = 0x0, current_cond = 0x0, pthread_self = 0x0, id = 1,
  cmp_length = 0, abort = 0, init = 1 '\001', next = 0x0, prev = 0x0,
  opt_info = 0x0,
  dbug = 0xd0d0d0d0d0d0d0d0 <Error reading address 0xd0d0d0d0d0d0d0d0: Bad address>,
name = 'Р' <repeats 11 times>}
(gdb)

Notice sizeof() returning different values.

Enough on the problem.

Now to the fix - there are at least several ways to get rid of the
crashing program during build. I have created a patches for two most
obvious of them:

1) Nothing in the dbug/ directory is to be touched/compiled/linked
against/executed if debugging is turned off.

here is the patch:

--- dbug_exclude.diff begins here ---
diff -urN mysql-5.0.orig/configure.in mysql-5.0/configure.in
--- mysql-5.0.orig/configure.in	Wed Sep 27 09:24:55 2006
+++ mysql-5.0/configure.in	Fri Sep 29 12:40:23 2006
@@ -1658,16 +1658,27 @@
   # Medium debug.
   CFLAGS="$DEBUG_CFLAGS $DEBUG_OPTIMIZE_CC -DDBUG_ON -DSAFE_MUTEX $CFLAGS"
   CXXFLAGS="$DEBUG_CXXFLAGS $DEBUG_OPTIMIZE_CXX -DDBUG_ON -DSAFE_MUTEX $CXXFLAGS"
+  dbug_lib="\$(top_builddir)/dbug/libdbug.a"
+  sql_server_dirs_dbug=dbug
 elif test "$with_debug" = "full"
 then
   # Full debug. Very slow in some cases
   CFLAGS="$DEBUG_CFLAGS -DDBUG_ON -DSAFE_MUTEX -DSAFEMALLOC $CFLAGS"
   CXXFLAGS="$DEBUG_CXXFLAGS -DDBUG_ON -DSAFE_MUTEX -DSAFEMALLOC $CXXFLAGS"
+  dbug_lib="\$(top_builddir)/dbug/libdbug.a"
+  sql_server_dirs_dbug=dbug
 else
   # Optimized version. No debug
   CFLAGS="$OPTIMIZE_CFLAGS -DDBUG_OFF $CFLAGS"
   CXXFLAGS="$OPTIMIZE_CXXFLAGS -DDBUG_OFF $CXXFLAGS"
+  # do not touch dbug/ if debug is turned off
+  # because dbug.c uses members of struct st_my_thread_var which are present
+  # only when DBUF_OFF is not defined
+  dbug_lib=
+  sql_server_dirs_dbug=
 fi
+AC_SUBST(dbug_lib)
+AM_CONDITIONAL(DBUG, test "$with_debug" = "yes" -o "$with_debug" = "full")
 
 # Force static compilation to avoid linking problems/get more speed
 AC_ARG_WITH(mysqld-ldflags,
@@ -2521,7 +2532,7 @@
   THREAD_LOBJECTS="thr_alarm.o thr_lock.o thr_mutex.o thr_rwlock.o my_pthread.o
my_thr_init.o mf_keycache.o"
   AC_SUBST(THREAD_LOBJECTS)
   server_scripts="mysqld_safe mysql_install_db"
-  sql_server_dirs="strings mysys dbug extra regex"
+  sql_server_dirs="strings mysys $sql_server_dirs_dbug extra regex"
 
 
   #
diff -urN mysql-5.0.orig/dbug/dbug.c mysql-5.0/dbug/dbug.c
--- mysql-5.0.orig/dbug/dbug.c	Wed Sep 27 09:25:26 2006
+++ mysql-5.0/dbug/dbug.c	Fri Sep 29 12:40:23 2006
@@ -67,7 +67,7 @@
  */
 
 #ifdef DBUG_OFF
-#undef DBUG_OFF
+#error DBUG_OFF must not be defined when compiling dbug.c nor any of the dependent
libraries
 #endif
 #include <my_global.h>
 #include <m_string.h>
diff -urN mysql-5.0.orig/extra/Makefile.am mysql-5.0/extra/Makefile.am
--- mysql-5.0.orig/extra/Makefile.am	Wed Sep 27 09:25:26 2006
+++ mysql-5.0/extra/Makefile.am	Fri Sep 29 12:40:23 2006
@@ -17,7 +17,7 @@
 INCLUDES =		-I$(top_builddir)/include -I$(top_srcdir)/include \
 			@ndbcluster_includes@ -I$(top_srcdir)/sql
 LDADD =			@CLIENT_EXTRA_LDFLAGS@ ../mysys/libmysys.a \
-			../dbug/libdbug.a ../strings/libmystrings.a
+			$(dbug_lib) ../strings/libmystrings.a
 BUILT_SOURCES=		$(top_builddir)/include/mysqld_error.h \
                         $(top_builddir)/include/sql_state.h \
                         $(top_builddir)/include/mysqld_ername.h
diff -urN mysql-5.0.orig/heap/Makefile.am mysql-5.0/heap/Makefile.am
--- mysql-5.0.orig/heap/Makefile.am	Wed Sep 27 09:25:28 2006
+++ mysql-5.0/heap/Makefile.am	Fri Sep 29 12:40:23 2006
@@ -15,7 +15,7 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 INCLUDES =		-I$(top_builddir)/include -I$(top_srcdir)/include 
-LDADD =			libheap.a ../mysys/libmysys.a ../dbug/libdbug.a \
+LDADD =			libheap.a ../mysys/libmysys.a $(dbug_lib) \
 			../strings/libmystrings.a
 pkglib_LIBRARIES =	libheap.a
 noinst_PROGRAMS	=	hp_test1 hp_test2
diff -urN mysql-5.0.orig/heap/hp_test2.c mysql-5.0/heap/hp_test2.c
--- mysql-5.0.orig/heap/hp_test2.c	Wed Sep 27 09:25:28 2006
+++ mysql-5.0/heap/hp_test2.c	Fri Sep 29 12:40:23 2006
@@ -19,9 +19,6 @@
 #ifndef USE_MY_FUNC		/* We want to be able to dbug this !! */
 #define USE_MY_FUNC
 #endif
-#ifdef DBUG_OFF
-#undef DBUG_OFF
-#endif
 #ifndef SAFEMALLOC
 #define SAFEMALLOC
 #endif
diff -urN mysql-5.0.orig/libmysql/Makefile.shared mysql-5.0/libmysql/Makefile.shared
--- mysql-5.0.orig/libmysql/Makefile.shared	Wed Sep 27 09:25:36 2006
+++ mysql-5.0/libmysql/Makefile.shared	Fri Sep 29 12:40:23 2006
@@ -49,7 +49,6 @@
 			ctype-uca.lo xml.lo my_strtoll10.lo str_alloc.lo 
 
 mystringsextra= 	strto.c
-dbugobjects =		dbug.lo # IT IS IN SAFEMALLOC.C sanity.lo
 mysysheaders =		mysys_priv.h my_static.h
 vioheaders =		vio_priv.h
 mysysobjects1 =		my_init.lo my_static.lo my_malloc.lo my_realloc.lo \
@@ -91,6 +90,12 @@
 if HAVE_YASSL
 yassl_las = $(top_srcdir)/extra/yassl/src/libyassl.la \
 	    $(top_srcdir)/extra/yassl/taocrypt/src/libtaocrypt.la
+endif
+
+if DBUG
+dbugobjects = dbug.lo
+else
+dbugobjects =
 endif
 
 # The automatic dependencies miss this
diff -urN mysql-5.0.orig/myisam/Makefile.am mysql-5.0/myisam/Makefile.am
--- mysql-5.0.orig/myisam/Makefile.am	Wed Sep 27 09:25:37 2006
+++ mysql-5.0/myisam/Makefile.am	Fri Sep 29 12:40:23 2006
@@ -20,7 +20,7 @@
 INCLUDES =		-I$(top_builddir)/include -I$(top_srcdir)/include
 LDADD =			@CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
 			$(top_builddir)/mysys/libmysys.a \
-			$(top_builddir)/dbug/libdbug.a \
+			$(dbug_lib) \
 			$(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
 pkglib_LIBRARIES =	libmyisam.a
 bin_PROGRAMS =		myisamchk myisamlog myisampack myisam_ftdump
diff -urN mysql-5.0.orig/myisam/mi_test2.c mysql-5.0/myisam/mi_test2.c
--- mysql-5.0.orig/myisam/mi_test2.c	Wed Sep 27 09:25:39 2006
+++ mysql-5.0/myisam/mi_test2.c	Fri Sep 29 12:40:23 2006
@@ -19,9 +19,6 @@
 #ifndef USE_MY_FUNC		/* We want to be able to dbug this !! */
 #define USE_MY_FUNC
 #endif
-#ifdef DBUG_OFF
-#undef DBUG_OFF
-#endif
 #ifndef SAFEMALLOC
 #define SAFEMALLOC
 #endif
diff -urN mysql-5.0.orig/server-tools/instance-manager/Makefile.am
mysql-5.0/server-tools/instance-manager/Makefile.am
--- mysql-5.0.orig/server-tools/instance-manager/Makefile.am	Wed Sep 27 09:26:35 2006
+++ mysql-5.0/server-tools/instance-manager/Makefile.am	Fri Sep 29 12:40:23 2006
@@ -84,7 +84,7 @@
 			$(top_builddir)/vio/libvio.a \
 			$(top_builddir)/mysys/libmysys.a \
 			$(top_builddir)/strings/libmystrings.a \
-			$(top_builddir)/dbug/libdbug.a \
+			$(dbug_lib) \
 			@openssl_libs@ @yassl_libs@ @ZLIB_LIBS@
 
 
diff -urN mysql-5.0.orig/sql/Makefile.am mysql-5.0/sql/Makefile.am
--- mysql-5.0.orig/sql/Makefile.am	Wed Sep 27 09:26:35 2006
+++ mysql-5.0/sql/Makefile.am	Fri Sep 29 12:40:23 2006
@@ -35,7 +35,7 @@
 			$(top_builddir)/heap/libheap.a \
 			$(top_builddir)/vio/libvio.a \
 			$(top_builddir)/mysys/libmysys.a \
-			$(top_builddir)/dbug/libdbug.a \
+			$(dbug_lib) \
 			$(top_builddir)/regex/libregex.a \
 			$(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@ @NDB_SCI_LIBS@
 
diff -urN mysql-5.0.orig/vio/Makefile.am mysql-5.0/vio/Makefile.am
--- mysql-5.0.orig/vio/Makefile.am	Wed Sep 27 09:27:12 2006
+++ mysql-5.0/vio/Makefile.am	Fri Sep 29 12:40:23 2006
@@ -26,15 +26,15 @@
 noinst_PROGRAMS	=	test-ssl test-sslserver test-sslclient
 noinst_HEADERS=	vio_priv.h
 test_ssl_SOURCES=	test-ssl.c $(yassl_dummy_link_fix)
-test_ssl_LDADD=   	@CLIENT_EXTRA_LDFLAGS@ ../dbug/libdbug.a libvio.a \
+test_ssl_LDADD=   	@CLIENT_EXTRA_LDFLAGS@ $(dbug_lib) libvio.a \
 			../mysys/libmysys.a ../strings/libmystrings.a \
 			$(openssl_libs) $(yassl_libs)
 test_sslserver_SOURCES= test-sslserver.c $(yassl_dummy_link_fix)
-test_sslserver_LDADD=   @CLIENT_EXTRA_LDFLAGS@	../dbug/libdbug.a libvio.a \
+test_sslserver_LDADD=   @CLIENT_EXTRA_LDFLAGS@ $(dbug_lib) libvio.a \
 			../mysys/libmysys.a ../strings/libmystrings.a \
 			$(openssl_libs) $(yassl_libs)
 test_sslclient_SOURCES= test-sslclient.c $(yassl_dummy_link_fix)
-test_sslclient_LDADD=   @CLIENT_EXTRA_LDFLAGS@	../dbug/libdbug.a libvio.a \
+test_sslclient_LDADD=   @CLIENT_EXTRA_LDFLAGS@ $(dbug_lib) libvio.a \
 			../mysys/libmysys.a ../strings/libmystrings.a \
 			$(openssl_libs) $(yassl_libs)
 libvio_a_SOURCES=	vio.c viosocket.c viossl.c viosslfactories.c
--- dbug_exclude.diff ends here ---

2) Make structure st_my_thread_var independent of DBUG_OFF

--- dbug_fix_struct.diff begins here ---
diff -ur mysql-5.0.orig/include/my_pthread.h mysql-5.0/include/my_pthread.h
--- mysql-5.0.orig/include/my_pthread.h	Wed Sep 27 09:25:28 2006
+++ mysql-5.0/include/my_pthread.h	Fri Sep 29 14:37:02 2006
@@ -670,10 +670,8 @@
   my_bool init;
   struct st_my_thread_var *next,**prev;
   void *opt_info;
-#ifndef DBUG_OFF
   gptr dbug;
   char name[THREAD_NAME_SIZE+1];
-#endif
 };
 
 extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const));
--- dbug_fix_struct.diff ends here ---

What do you think about it?

-- 
Vasil Dimov
gro.DSBeerF@dv
%
Never test for an error condition you don't know how to handle.
                -- Steinbach

Attachment: [application/pgp-signature]
Thread
dbug/factorial getting SIGBUS during build (5.0.26-BK)Vasil Dimov29 Sep
  • Re: dbug/factorial getting SIGBUS during build (5.0.26-BK)Sergei Golubchik4 Oct
    • Re: dbug/factorial getting SIGBUS during build (5.0.26-BK)Vasil Dimov5 Oct
      • Re: dbug/factorial getting SIGBUS during build (5.0.26-BK)Sergei Golubchik5 Oct