Vladimir Panov
2005-02-11 02:37:18 UTC
Hi.
When omniORB 4.0.5 (or any 4.0 version, actually) is built with GCC 3.4,
then a statically linked program against it segfaults on startup. The
reason is that the static initializers of the code sets are not executed
(even the ones from libomniORB4.a, not only the ones from
libomniCodeSets4.a). The reason seems to be a new optimization in GCC
3.4 called "unit-at-a-time" which is on by default when using -O2.
As far as I understood, this optimization considers the static
initilizers to be dead code, and GCC doesn't even generate machine code
for them, let alone run them. I tried to fix this in the source
(including the advised way of using the "used" attribute) but miserably
failed. Of course, there should be a way to achieve this in the source
somehow and this would be the best solution.
Another solution is to use -fno-unit-at-a-time, and I have attached a
patch for it against omniORB 4.0.5 (don't forget to run autoreconf after
you apply it). But this should be considered a temporary solution
because the option might be dropped in the future.
Here is the GCC 3.4's changelog which gives some information about the
unit-at-a-time optimization:
http://gcc.gnu.org/gcc-3.4/changes.html
Vlado
-------------- next part --------------
diff -r -u omniORB-4.0.5-orig/acinclude.m4 omniORB-4.0.5/acinclude.m4
--- omniORB-4.0.5-orig/acinclude.m4 2004-10-17 23:14:25.000000000 +0300
+++ omniORB-4.0.5/acinclude.m4 2005-02-06 22:23:57.000000000 +0200
@@ -470,3 +470,14 @@
fi
])
+AC_DEFUN([OMNI_CHECK_NO_UNIT_AT_A_TIME],
+[AC_CACHE_CHECK(whether $CC accepts -fno-unit-at-a-time,
+omni_cv_no_unit_at_a_time,
+[
+ AC_LANG_PUSH(C)
+ save_CFLAGS=$CFLAGS
+ CFLAGS="$CFLAGS -fno-unit-at-a-time"
+ AC_COMPILE_IFELSE(AC_LANG_PROGRAM(,), omni_cv_no_unit_at_a_time="yes", omni_cv_no_unit_at_a_time="no")
+ CFLAGS=$save_CFLAGS
+ AC_LANG_POP
+])])
diff -r -u omniORB-4.0.5-orig/configure.ac omniORB-4.0.5/configure.ac
--- omniORB-4.0.5-orig/configure.ac 2004-10-18 03:44:55.000000000 +0300
+++ omniORB-4.0.5/configure.ac 2005-02-06 23:02:15.000000000 +0200
@@ -26,6 +26,12 @@
AC_LANG(C++)
+OMNI_CHECK_NO_UNIT_AT_A_TIME
+if test "x$omni_cv_no_unit_at_a_time" = "xyes"
+then
+ EXTRA_GCC_CXXFLAGS="-fno-unit-at-a-time"
+fi
+AC_SUBST(EXTRA_GCC_CXXFLAGS)
dnl ** Libraries
diff -r -u omniORB-4.0.5-orig/mk/beforeauto.mk.in omniORB-4.0.5/mk/beforeauto.mk.in
--- omniORB-4.0.5-orig/mk/beforeauto.mk.in 2004-10-18 03:44:56.000000000 +0300
+++ omniORB-4.0.5/mk/beforeauto.mk.in 2005-02-06 23:00:46.000000000 +0200
@@ -733,7 +733,7 @@
ifdef Compiler_GCC
CMAKEDEPEND += -D__GNUC__
CXXMAKEDEPEND += -D__GNUG__ -D__GNUC__
-CXXOPTIONS = -Wall -Wno-unused -fexceptions
+CXXOPTIONS = -Wall -Wno-unused -fexceptions @EXTRA_GCC_CXXFLAGS@
EgcsMajorVersion = 1
EgcsMinorVersion = 1
SHAREDLIB_CPPFLAGS = -fPIC
When omniORB 4.0.5 (or any 4.0 version, actually) is built with GCC 3.4,
then a statically linked program against it segfaults on startup. The
reason is that the static initializers of the code sets are not executed
(even the ones from libomniORB4.a, not only the ones from
libomniCodeSets4.a). The reason seems to be a new optimization in GCC
3.4 called "unit-at-a-time" which is on by default when using -O2.
As far as I understood, this optimization considers the static
initilizers to be dead code, and GCC doesn't even generate machine code
for them, let alone run them. I tried to fix this in the source
(including the advised way of using the "used" attribute) but miserably
failed. Of course, there should be a way to achieve this in the source
somehow and this would be the best solution.
Another solution is to use -fno-unit-at-a-time, and I have attached a
patch for it against omniORB 4.0.5 (don't forget to run autoreconf after
you apply it). But this should be considered a temporary solution
because the option might be dropped in the future.
Here is the GCC 3.4's changelog which gives some information about the
unit-at-a-time optimization:
http://gcc.gnu.org/gcc-3.4/changes.html
Vlado
-------------- next part --------------
diff -r -u omniORB-4.0.5-orig/acinclude.m4 omniORB-4.0.5/acinclude.m4
--- omniORB-4.0.5-orig/acinclude.m4 2004-10-17 23:14:25.000000000 +0300
+++ omniORB-4.0.5/acinclude.m4 2005-02-06 22:23:57.000000000 +0200
@@ -470,3 +470,14 @@
fi
])
+AC_DEFUN([OMNI_CHECK_NO_UNIT_AT_A_TIME],
+[AC_CACHE_CHECK(whether $CC accepts -fno-unit-at-a-time,
+omni_cv_no_unit_at_a_time,
+[
+ AC_LANG_PUSH(C)
+ save_CFLAGS=$CFLAGS
+ CFLAGS="$CFLAGS -fno-unit-at-a-time"
+ AC_COMPILE_IFELSE(AC_LANG_PROGRAM(,), omni_cv_no_unit_at_a_time="yes", omni_cv_no_unit_at_a_time="no")
+ CFLAGS=$save_CFLAGS
+ AC_LANG_POP
+])])
diff -r -u omniORB-4.0.5-orig/configure.ac omniORB-4.0.5/configure.ac
--- omniORB-4.0.5-orig/configure.ac 2004-10-18 03:44:55.000000000 +0300
+++ omniORB-4.0.5/configure.ac 2005-02-06 23:02:15.000000000 +0200
@@ -26,6 +26,12 @@
AC_LANG(C++)
+OMNI_CHECK_NO_UNIT_AT_A_TIME
+if test "x$omni_cv_no_unit_at_a_time" = "xyes"
+then
+ EXTRA_GCC_CXXFLAGS="-fno-unit-at-a-time"
+fi
+AC_SUBST(EXTRA_GCC_CXXFLAGS)
dnl ** Libraries
diff -r -u omniORB-4.0.5-orig/mk/beforeauto.mk.in omniORB-4.0.5/mk/beforeauto.mk.in
--- omniORB-4.0.5-orig/mk/beforeauto.mk.in 2004-10-18 03:44:56.000000000 +0300
+++ omniORB-4.0.5/mk/beforeauto.mk.in 2005-02-06 23:00:46.000000000 +0200
@@ -733,7 +733,7 @@
ifdef Compiler_GCC
CMAKEDEPEND += -D__GNUC__
CXXMAKEDEPEND += -D__GNUG__ -D__GNUC__
-CXXOPTIONS = -Wall -Wno-unused -fexceptions
+CXXOPTIONS = -Wall -Wno-unused -fexceptions @EXTRA_GCC_CXXFLAGS@
EgcsMajorVersion = 1
EgcsMinorVersion = 1
SHAREDLIB_CPPFLAGS = -fPIC