Bug 111928

Summary: glibc 2.3 causes linking problems with Undefined Symbol __ctype_b and others
Product: Red Hat Enterprise Linux 3 Reporter: Jeff Mikesell <jeffm>
Component: glibcAssignee: Jakub Jelinek <jakub>
Status: CLOSED NOTABUG QA Contact: Brian Brock <bbrock>
Severity: high Docs Contact:
Priority: high    
Version: 3.0CC: michel.pottiez
Target Milestone: ---   
Target Release: ---   
Hardware: i686   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2004-03-02 22:17:09 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
zip file which was in the Service Request Number mentioned none

Description Jeff Mikesell 2003-12-11 18:19:49 UTC
Description of problem: Undefined Symbol __ctype_b and others 
Service Request Number 276194 with Redhat Techsupport has .zip file

Version-Release number of selected component (if applicable):
Enterprise AS 3, WS 3, ES 3 and Redhat PRO 9.0 with latest patches

How reproducible: Very Reproducable


Steps to Reproduce:
To reproduce
  unzip linkproblem.zip
  cd objects
  linklib.sh   # to produce libgemfire.so
  linkexe.sh   
  # linkexe.sh will produce  
  #   /libgemfire.so: undefined reference to `__ctype_b'
  #   collect2: ld returned 1 exit status

All .o files were compiled on RH AS 3 using /usr/bin/gcc 
or /usr/bin/g++

nm *.o does not work on RH AS 3 , it claims "no symbols for any .o"

Using a RH 7.3 system,  nm *.o shows no occurrance of __ctype_b
in any of our .o files , but  __ctype_b still shows up in 
libgemfire.so

On RH AS 3, I see this:
  % cd /usr/lib
  % nm -D -A *stdc++*.so | grep ctype
  libstdc++-2-libc6.1-1-2.9.0.so:         U __ctype_b

If the __ctype_b in libemfire.so is coming from libstdc++-2-libc6.1-1-
2.9.0.so,
then what additional library must we include to resolve it ?

  
Actual results:


Expected results: Should link without errors


Additional info:

I found the reason for the failures on Glibc 2.3. I also found a fix 
some customers did to fix the problem. Both are published below.

glibc 2.3.x changes some symbols (__ctype_b, __ctype_toupper, 
__ctype_tolower) as hidden attribute. These symbols that are
crashing the old 2.2.x dynamic linking code in static binaries
are now exported.

I understand that this is a problem Red hat 9 renaming _ctype_b to
_ctype_b_loc, but what can I do to get around this? I have 20+ ec 
programs I must compile on this OS.

Since all of our code on Redhat AS 3, WS 3 and Redhat 9.0 fails. 
Below is what others did to fix the problem on Redhat 9.0. Hope this 
helps

Customer Fix
-------------                 
We used a brute force approach. Make the following code into a .c 
file, and include it in your program. At the start of main(), catll 
ctSetup().

Make sure you compile statically or else the dynamic loader will 
cause problems.

I've seen others use macros, but this worked good enough for us... 


#include <ctype.h>


__const unsigned short int *__ctype_b;
__const __int32_t *__ctype_tolower;
__const __int32_t *__ctype_toupper;


void ctSetup()
{
__ctype_b = *(__ctype_b_loc());
__ctype_toupper = *(__ctype_toupper_loc());
__ctype_tolower = *(__ctype_tolower_loc());
}

Comment 1 Suzanne Hillman 2004-01-05 22:08:14 UTC
Created attachment 96774 [details]
zip file which was in the Service Request Number mentioned

Comment 2 Jakub Jelinek 2004-03-02 22:17:09 UTC
a) nm *.o works for me just fine
b) __ctype_b in your case comes from liblssrv.a which has NOT been
   rebuilt on RHEL3 (clearly has been built with gcc-2.96-RH of very
   old vintage, against glibc-2.2.x)
   Backwards binary compatibility is ensured through symbol versioning,
   which works for linked programs and shared libraries only, never
   worked for .o or .a files and there were never guarantees they
   can be used between different OS versions
c) we ship compat-glibc and compat-gcc, so you should be able to compile
   your objects using compat-gcc against compat-glibc headers and
   link against compat-glibc and that liblssrv.a
Your ctSetup will only work as long as you never setlocale/uselocale,
or whenever setlocale is called ctSetup() is called afterwards as well.
With uselocale it will never work properly (as there ctype_b etc.
are per thread variables, which is btw the reason why *_loc() accessors
are now used).

Comment 3 Jeff Mikesell 2004-03-02 23:09:21 UTC
You are mistaken. We built/compiled the code from scratch on AS 3
using the gcc 3.2 compiler.

We have no code which includes ctype.h. We use java in all of our
products. It is my opinion that you have some old ctype code in
you Java JDK which includes ctype or still in you old ctype in your 
libraries. 

Redhat has lost a lot of money because of this problem. Our new 
vender is Suse which when we build product on Suse 9 from scratch 
does not have the problem. So I guess Redhat has screwed the pouch 
again.

Poor Engineering

Comment 4 Jakub Jelinek 2004-03-02 23:36:27 UTC
I beg to disagree.  liblssrv.a doesn't come up from our Java rpms
(rpm -qplv IBMJava2-JRE-1.4.1-11.i386.rpm IBMJava2-SDK-1.4.1-11.i386.rpm jrockit-j2se-8.1.1.1-2.i386.rpm | grep liblssrv.a
yields nothing) and it clearly has not been rebuilt on RHEL3:
objdump -s -j .comment liblssrv.a | head
In archive liblssrv.a:

lckfncn.o:     file format elf32-i386

Contents of section .comment:
 0000 00474343 3a202847 4e552920 322e3936  .GCC: (GNU) 2.96
 0010 20323030 30303733 31202852 65642048   20000731 (Red H
 0020 6174204c 696e7578 20372e30 2900      at Linux 7.0).

lmdltn.o:     file format elf32-i386

nm liblssrv.a | grep ctype_b
         U __ctype_b
         U __ctype_b
         U __ctype_b
         U __ctype_b
         U __ctype_b
         U __ctype_b
         U __ctype_b
         U __ctype_b
         U __ctype_b
         U __ctype_b
         U __ctype_b

SuSE 9 AFAIK doesn't support uselocale(3), so no wonder old __ctype_b
can work there, but the 2 cannot coexist.  Either code using __ctype_b
will link and misbehave in the presence of uselocale in the application
(e.g. libstdc++ uses uselocale quite heavily), or linking will ensure
all code using ctype is rebuilt and thus works in presence of uselocale(3).
RHEL3 does the latter by default and you can do the former by linking
against compat-glibc.

Comment 5 Jeff Mikesell 2004-03-03 01:15:14 UTC
The problem is we are building with the Sun supplied Linux JDK's 
for Redhat which are suppose to be upward compatable. Building 
product on RHEL 3 no longer is compatable. And by the way 
everything was compiled, linked and built with the gcc 3.2 compiler
on RHEL 3.

This will definitely cause many problems for your customers who are
trying to use the latest releases. I find it interesting the Suse
took time to address the problem and Redhat does not care.

Comment 6 michel pottiez 2004-03-18 10:47:36 UTC
I came across the same problem when recompiling my soft on RHEL3.
undefined reference to `__ctype_b

The fact is that I use a thrid party software (Parasolid) that has not
been specifically compiled on that version (and they do not intend to
do it just for me...).
So, I am blocked at this level. Where can I find the work around
(compat-glic ??? where can I find it)

Thanks


Comment 7 Jakub Jelinek 2004-03-18 12:01:28 UTC
compat-glibc is shipped in RHEL3.  Just install it (up2date compat-glibc)
and compile/link your software against it
(-I/usr/lib/i386-redhat-linux7/include/ -L/usr/lib/i386-redhat-linux7/lib/ )

Comment 8 michel pottiez 2004-03-18 14:05:54 UTC
Thanks for the advice. When I do this I get the follwoing compilation
problem...

What is the way out of it ?

Thanks

In file included from
/usr/include/c++/3.2.3/i386-redhat-linux/bits/gthr-default.h:37,
                 from
/usr/include/c++/3.2.3/i386-redhat-linux/bits/gthr.h:98,
                 from
/usr/include/c++/3.2.3/i386-redhat-linux/bits/c++io.h:37,
                 from /usr/include/c++/3.2.3/bits/fpos.h:44,
                 from /usr/include/c++/3.2.3/iosfwd:46,
                 from /usr/include/c++/3.2.3/ios:44,
                 from /usr/include/c++/3.2.3/ostream:45,
                 from /usr/include/c++/3.2.3/iostream:45,
                 from /usr/include/c++/3.2.3/backward/iostream.h:32,
                 from _lib_i/_rw/rw/defs.h:398,
                 from _lib_i/_rw/rw/tooldefs.h:156,
                 from _lib_i/_rw/rw/cstring.h:205,
                 from _incl/_Foundation/flexKey.h:7,
                 from _src/igg/_System/igg.C:7:
/usr/lib/i386-redhat-linux7/include/pthread.h:163: syntax error before `
   __thread'
/usr/lib/i386-redhat-linux7/include/pthread.h:165: `pthread_create'
declared as
   function returning a function
/usr/lib/i386-redhat-linux7/include/pthread.h:166: syntax error before
`void'
/usr/lib/i386-redhat-linux7/include/pthread.h:591: storage class
specifiers
   invalid in parameter declarations
/usr/lib/i386-redhat-linux7/include/pthread.h:591: storage class
specified for
   parameter `parameter'
I

Comment 9 Jakub Jelinek 2004-03-18 14:13:46 UTC
You can use i386-redhat-linux7-g{cc,++} (from compat-gcc).
Or sed -i s/__thread/__threadp/ /usr/lib/i386-redhat-linux7/include/{pthread.h,bits/sigthread.h}
I'll change that in compat-glibc for U3.

Comment 10 michel pottiez 2004-03-18 15:50:28 UTC
Hi,

I now have the unresolved:

/usr/X11R6/lib/libX11.so: undefined reference to
`__ctype_toupper_loc'
/usr/X11R6/lib/libX11.so: undefined reference to
`__ctype_tolower_loc'

Any hint ?